我有一个基于 Select 图像的问题. 我有一个来自BE的对象数组,每个对象都有自己的坐标,这取决于图像的X和Y. IMAGE在那里有一些吸引力,并包括一些数字. 所以Obj上的属性itemNumber与img中显示的数字相同. 例如,如果itemNumber为1,则坐标为数字1将在图像上加边框.

到目前为止,我已经取得了一些成就,但我不能每次都 Select 正确的X和Y.

我创造了一个Stackblitz

在堆叠闪电战中,你可以找到2个IMG. 在第二个问题上,你会看到事情的本来面目. 我try 了很多方法,但都不成功

这是我的奥比杰儿子.

[
 {
        "itemNumber": "1",
        "partNumber": "4400535240",
        "coordinates": [
            {
                "itemCounter": 0,
                "xposition": 970,
                "yposition": 375
            }
        ]
    },
    {
        "itemNumber": "2",
        "partNumber": "4400541680",
        "coordinates": [
            {
                "itemCounter": 0,
                "xposition": 1282,
                "yposition": 522
            }
        ]
    },
    {
        "itemNumber": "4",
        "partNumber": "4400541390",
        "coordinates": [
            {
                "itemCounter": 0,
                "xposition": 445,
                "yposition": 307
            }
        ]
    },
 ]`

这是我的TS代码.

showCorner(event: ResponseList) {
console.log(event.coordinates)

const xClientHeight = document.getElementById('imgPath')?.clientHeight as number;
const xClientWidth = document.getElementById('imgPath')?.clientWidth as number;

console.log(xClientHeight);
console.log(xClientWidth);


this.coordinateX =  xClientWidth - event.coordinates[0].yposition;
this.coordinateY = xClientHeight - event.coordinates[0].xposition;



(document.getElementById('rec1') as HTMLInputElement).innerHTML = "<img src='../../../assets/rec.gif'  style='width:25px; height:25px;'></img>";

}


showImage(imagePath: string) {
return this.environment.endpoints.backendBaseUrl + imagePath; // 
imagePath
}

我的HTML码

<table>
        <thead>
            <tr>
                <th scope="col">Name</th>
               
            </tr>
        </thead>
        <tbody>
          <tr *ngFor="let row of jsonData">
                <td (click)="showCorner(row)">{{ row.name }}</td>
               
            </tr>         
        </tbody>
    </table>

<div class="flex-1 relative">
  <div class="relative">
    <img id="imgPath" (click.double)="addBorder($event)"  style="width: 832px; max-width: fit-content;" [src]="showImage(partListImage.imagePath)">
    <div id="rec1" class="absolute" [style]="{'left': coordinateX+ 'px', 'top': coordinateY+ 'px'}">
    </div>
  </div>
</div>

正如你在图像中看到的,其中有数字. 当您点击表格时,每个数字都将被选中.

推荐答案

问题是坐标是从后端来的,我不能更改它们,我需要像你一样做,因为在img中,1张图像大约有40个坐标,我有大约100个img,我不能手动更改它们

所有IMG来自后台的IMG维度为1664 × 2344

As provided by the backend, set the original image dimensions (1664x2344) in your component.
Compute the scaling factors based on the current displayed size of the image in the frontend and the original dimensions. Apply Scaling to Coordinates: Use the scaling factors to adjust the coordinates received from the backend. I have adjusted them in this stackblitz.

你的app.component.ts分将是:

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements AfterViewInit {
  @ViewChild('imgPath', { static: false }) imgElementRef!: ElementRef;
  coordinateX!: number;
  coordinateY!: number;
  originalCoordinates: any; // To store original coordinates
  columns = [
    {
      itemNumber: '1',
      partNumber: '4400535240',
      coordinates: [
        {
          itemCounter: 0,
          xposition: 970,
          yposition: 375,
        },
      ],
    },
    {
      itemNumber: '2',
      partNumber: '4400541680',
      coordinates: [
        {
          itemCounter: 0,
          xposition: 1282,
          yposition: 522,
        },
      ],
    },
    {
      itemNumber: '4',
      partNumber: '4400541390',
      coordinates: [
        {
          itemCounter: 0,
          xposition: 445,
          yposition: 307,
        },
      ],
    },
  ];

  constructor() {
    // Deep copy of original columns to preserve original coordinates
    this.originalCoordinates = JSON.parse(JSON.stringify(this.columns));
  }

  ngAfterViewInit() {
    // Calculate and apply scaling when the view is initialized
    this.calculateAndApplyScaling();
  }

  showCorner(event: any) {
    // Calculate and apply scaling
    this.calculateAndApplyScaling();

    // Use the scaled coordinates
    this.coordinateX = event.coordinates[0].xposition;
    this.coordinateY = event.coordinates[0].yposition + 80;

    // Log coordinates to console
    console.log('Selected Coordinates:', this.coordinateX, this.coordinateY);

    // Update the border element
    this.updateBorderElement();
  }

  private calculateAndApplyScaling() {
    const imgElement = this.imgElementRef.nativeElement as HTMLImageElement;
    const currentWidth = imgElement.clientWidth;
    const currentHeight = imgElement.clientHeight;

    console.log(
      'Image Current Width:',
      currentWidth,
      'Current Height:',
      currentHeight
    );

    // Use naturalWidth and naturalHeight properties
    const originalWidth = imgElement.naturalWidth;
    const originalHeight = imgElement.naturalHeight;

    const scaleX = currentWidth / this.originalWidth;
    const scaleY = currentHeight / this.originalHeight;

    console.log('Scale Factor X:', scaleX, 'Scale Factor Y:', scaleY);

    // Apply scale factors to each original coordinate
    this.columns.forEach((column, index) => {
      column.coordinates.forEach((coordinate, coordIndex) => {
        const originalCoordinate =
          this.originalCoordinates[index].coordinates[coordIndex];
        coordinate.xposition = originalCoordinate.xposition * scaleX;
        coordinate.yposition = originalCoordinate.yposition * scaleY;

        console.log(
          `Original Coordinates: (${originalCoordinate.xposition}, ${originalCoordinate.yposition}), Scaled Coordinates: (${coordinate.xposition}, ${coordinate.yposition})`
        );
      });
    });
  }

  private updateBorderElement() {
    const recElement = document.getElementById('rec1') as HTMLElement;
    if (recElement) {
      recElement.style.border = '2px solid red';
      recElement.style.width = '25px';
      recElement.style.height = '25px';
      recElement.style.left = this.coordinateX + 'px';
      recElement.style.top = this.coordinateY + 'px';

      console.log(
        'Border Element Updated:',
        `Left: ${this.coordinateX}px, Top: ${this.coordinateY}px`
      );
    }
  }

  addBorder(event: any) {
    console.log('Add Border Event:', event);
    const e = event.target.getBoundingClientRect();
    console.log('Bounding Client Rect:', e);
    const xClientH = event.screenY;
    const xClientY = event.screenX;

    this.coordinateX = xClientY;
    this.coordinateY = xClientH;
    console.log(
      'Coordinates from Event:',
      `X: ${this.coordinateX}, Y: ${this.coordinateY}`
    );

    const recElement = document.getElementById('rec1') as HTMLInputElement;
    if (recElement) {
      recElement.innerHTML =
        "<img src='../../assets/flow-editor/Image/rec.gif' style='width:25px; height:25px;'></img>";
    }
  }
}

并且您的HTML代码确保定位相对于图像的父容器是绝对的.

<table>
  <thead>
    <tr>
      <th scope="col">Name</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let row of columns">
      <td (click)="showCorner(row)">{{ row.itemNumber }}</td>
      <td (click)="showCorner(row)">{{ row.partNumber }}</td>
    </tr>
  </tbody>
</table>

<div class="flex-1 relative">
  <div class="relative">
    <img
      #imgPath
      (click.double)="addBorder($event)"
      style="width: 832px; max-width: fit-content;"
      src="../../assets/flow-editor/Image/ev00129014.png"
    />
    <div
      id="rec1"
      class="absolute"
      [ngStyle]="{ left: coordinateX + 'px', top: coordinateY + 'px' }"
    ></div>
  </div>
</div>

请注意,我必须调整从../assets/...../../assets/...的任何资源路径,以确保资源图像正确显示.

Javascript相关问答推荐

React对话框模式在用户单击预期按钮之前出现

我可以使用CSS有效地实现最大宽度=100%和最大高度=100%,而无需父母有明确的/固定的宽度和高度,替代方法吗?

传递一个大对象以在Express布局中呈现

为什么这个JS模块在TypeScript中使用默认属性导入?""

如何从URL获取令牌?

简单的PayPal按钮集成导致404错误

如何在Vue 3中创建自定义 Select 组件,并将选项作为HTML而不是props 传递?

使用POST请求时,Req.Body为空

使用js构造一个html<;ath&>元素并不能使其正确呈现

在使用REACT更改了CSS类之后,无法更改CSS样式

如何在.NET Core中将chtml文件链接到Java脚本文件?

当标题被点击时,如何使内容出现在另一个div上?

在不扭曲纹理的情况下在顶点着色器中旋转UV

如何在TransformControls模式下只保留箭头进行翻译?

$GTE的mongoose 问题

如何使pdf.js上的文本呈现为可选?

使用Java脚本替换字符串中的小文本格式hashtag

通过ng-绑定-html使用插入的HTML中的函数

Rails 7:在不使用导入映射的情况下导入Java脚本

从客户端更新MongoDB数据库