Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/414.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 画布中图像的放大和缩小问题_Javascript_Angular_Typescript_Canvas_Html5 Canvas - Fatal编程技术网

Javascript 画布中图像的放大和缩小问题

Javascript 画布中图像的放大和缩小问题,javascript,angular,typescript,canvas,html5-canvas,Javascript,Angular,Typescript,Canvas,Html5 Canvas,当我尝试放大和缩小画布图像时,我遇到了问题 其目的是允许用户在图像上绘制矩形。我使用画布来显示图像,然后在图像上绘制矩形,这很好。但现在我正在尝试添加放大和缩小功能。我面临以下问题: 当我放大或缩小时,我需要将矩形保持在与图像相同的位置。矩形保持在相同的坐标位置,但随着图像的移动,矩形中的图像部分已更改。如何在放大/缩小后保持矩形覆盖图像的相同部分 我是画布新手,不知道如何让它工作 以下是我遇到问题的组件: tagger.component.html <div class="ro

当我尝试放大和缩小画布图像时,我遇到了问题

其目的是允许用户在图像上绘制矩形。我使用画布来显示图像,然后在图像上绘制矩形,这很好。但现在我正在尝试添加放大和缩小功能。我面临以下问题:

当我放大或缩小时,我需要将矩形保持在与图像相同的位置。矩形保持在相同的坐标位置,但随着图像的移动,矩形中的图像部分已更改。如何在放大/缩小后保持矩形覆盖图像的相同部分

我是画布新手,不知道如何让它工作

以下是我遇到问题的组件:

tagger.component.html

<div class="row">
  <div class="text-image-content">
 
    <div class="column1">
        <div style="position: relative;">
            <div *ngFor="let drawItem of drawItems; let i = index">
                <input [ngStyle]="{'left':drawItem.x0 + 'px' , 'top': drawItem.y0 + 'px'}"
                    style="position: absolute; z-index: 999;" placeholder="Enter Object Name"
                    [(ngModel)]="drawItem.name" type="text">
                <input [ngStyle]="{'left':drawItem.x0 + 'px' , 'top': drawItem.y0 + 'px'}"
                    style="position: absolute; z-index: 999;" type="button" value="X" (click)="delete(i)">
            </div>
            
            <canvas #layer1 id="layer1" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
            <div class="row">
            </div>
        </div>
    </div>
    </div>
<button class="zoomBtn" (click)="zoomIn()">Zoom in</button>
<button class="zoomBtn" (click)="zoomOut()">Zoom out</button>
    <div class="column2">
        <div *ngFor="let drawItem of originalItems; let i = index">
            <div class="details">
              <div >Name: {{drawItem.name | titlecase}} </div>
               <div>({{drawItem.x0}}, {{drawItem.y0}} , {{drawItem.x0 + drawItem.x1}}, {{drawItem.y0 + drawItem.y1}})</div>
            </div>
        </div>
    </div>
</div>
完整的代码可以在以下位置找到:


谢谢

在Zoomin或Zoomout函数中,减小或增大边界框的坐标值,即this.drawItems。这就可以了。

我已经试过了,但我无法正确计算坐标。请制作一个单独的变量来存储固定值,并在单独的变量中更改值。感谢您的响应。我可以让它工作,但现在有一些其他问题。缩放后我无法绘制。请看这个问题:
import {
    Component,
    ViewChild,
    Input,
    Output,
    OnInit,
    EventEmitter,
    ElementRef
} from '@angular/core';

@Component({
    selector: "app-tagger",
    templateUrl: "./tagger.component.html",
    styleUrls: ["./tagger.component.scss"]
})
export class TaggerComponent implements OnInit {

    name = "Angular";
    constructor() { }
    drawItems = []
    originalItems = []
    count = 0
    @Input('CanvasHeight') CanvasHeight
    @Input('CanvasWidth') CanvasWidth
    @Output() selected = new EventEmitter();
    taggedItem = ""
    showInput: boolean = false;
    isMoving: boolean;
    public imgWidth: number;
    public uniX: number;
    public uniY: number;
    public uniX2: number;
    public uniY2: number;
    public initX: number;
    public initY: number;
    public imgHeight: number;
    public url: string;
    public image;
    public originalImageWidth;
    public originalImageHeight;
    public hRatio;
    public vRatio;
    public translatePos = {x: this.CanvasWidth / 2, y: this.CanvasHeight / 2};
    public scale = 1.0;
    public scaleMultiplier = 0.8;

    @ViewChild("layer1", { static: false }) layer1Canvas: ElementRef;
    private context: CanvasRenderingContext2D;
    private layer1CanvasElement: any;

  ngOnInit(){
    this.imageLoad();
  }

    delete(i) {
        console.log(i)
        this.drawItems.splice(i, 1);
        this.originalItems.splice(i,1);
        this.drawRect("red", 0, 0, 1);
    }

    imageLoad() {
      this.image = new Image();
      this.image.src = "https://i.ibb.co/12TJSNy/patio.jpg";
      this.image.onload = () => {
        console.log(this.CanvasWidth, this.CanvasHeight);
        console.log(this.image.width, this.image.height);
        this.originalImageWidth = this.image.width;
        this.originalImageHeight = this.image.height;
        this.image.width = this.CanvasWidth;
        this.image.height = this.CanvasHeight;
        this.hRatio =   this.originalImageWidth/this.CanvasWidth;
        this.vRatio =  this.originalImageHeight/this.CanvasHeight; 
        this.layer1CanvasElement = this.layer1Canvas.nativeElement;
        this.layer1CanvasElement.width = this.CanvasWidth;
        this.layer1CanvasElement.height = this.CanvasHeight;
        this.showImage();
      }
    }

    showImage() {
        this.count ++;
        this.layer1CanvasElement = this.layer1Canvas.nativeElement;
        this.context = this.layer1CanvasElement.getContext("2d");
        this.context.clearRect(0, 0, this.CanvasWidth, this.CanvasHeight);
        this.context.save();
        this.context.translate(this.translatePos.x, this.translatePos.y);
        this.context.scale(this.scale, this.scale);
        this.context.drawImage(this.image, 0,0, this.image.width, this.image.height);
        this.context.restore()
        let parent = this;
        if(this.count==1){
          this.layer1CanvasElement.addEventListener("mousedown", (e) => {
            this.isMoving = true
            this.initX = e.offsetX;
            this.initY = e.offsetY;
          });

        this.layer1CanvasElement.addEventListener("mouseup", (e) => {
            this.isMoving = false
            this.showInput = true
            this.drawItems.push({
                name: "",
                x0: this.initX,
                y0: this.initY,
                x1: this.uniX,
                y1: this.uniY
            });
            this.originalItems.push({
                name: "",
                x0: Math.ceil(this.initX * this.hRatio),
                y0: Math.ceil(this.initY * this.vRatio),
                x1: Math.ceil(this.uniX *this.hRatio),
                y1: Math.ceil(this.uniY * this.vRatio)
            });
            parent.drawRect("red", e.offsetX - this.initX, e.offsetY - this.initY, 0);
            this.uniX = undefined
            this.uniY = undefined
        });
      }
        

        this.layer1CanvasElement.addEventListener("mousemove", (e) => {
            if (this.isMoving) {
                parent.drawRect("red", e.offsetX - this.initX, e.offsetY - this.initY, 0);
            }
        });

        this.drawRect("red", 0, 0, 1);

    }


    drawRect(color = "black", height, width, flag) {
      if (this.uniX | flag) {
        this.context.clearRect(0, 0, this.CanvasWidth, this.CanvasHeight);
        this.context.save();
        this.context.translate(this.translatePos.x, this.translatePos.y);
        this.context.scale(this.scale, this.scale);
        this.context.drawImage(this.image, 0,0, this.image.width, this.image.height);
        this.context.restore()
      }
      // console.log(this.image.width, this.image.height)
      this.uniX = height
      this.uniY = width
      this.uniX2 = height
      this.uniY2 = width
      for (var i = 0; i < this.drawItems.length; i++) {
          this.context.beginPath();
          this.context.rect(
              this.drawItems[i].x0,
              this.drawItems[i].y0,
              this.drawItems[i].x1,
              this.drawItems[i].y1
          );
          this.context.lineWidth = 3;
          this.context.strokeStyle = color;
          this.context.stroke();
      }
    }

    zoomIn(){
      console.log("zooming in")
      this.scale /= this.scaleMultiplier;
      this.showImage();
    }
    zoomOut(){
      console.log("zooming out")
      this.scale *= this.scaleMultiplier;
      this.showImage();
      
    }
}
.button {
    color: transparent;
    cursor: pointer;
}

.column1 {
    float: left;
    width: 70%;
    padding: 10px;
    height: 300px; /* Should be removed. Only for demonstration */
}
.column2 {
    float: left;
    width: 25%;
    padding: 10px;
    height: 300px; /* Should be removed. Only for demonstration */
}

/* Clear floats after the columns */
.row:after {
    content: "";
    display: table;
    clear: both;
}

.details {
    margin: 10px;
}

.text-image-content{
border: 1px solid #979797;
    border-radius: 8px;
    padding: 0 10px;
    margin-left:20px;
    margin-right:20px;
    height: 300px;
    overflow-y: scroll;
    overflow-x: scroll;
    scrollbar-width: thin;
}

.zoomBtn{
  // height:10px;
}