缩放后我无法正确绘制。
目的是允许用户在图像上绘制矩形。我正在使用画布显示图像,然后在图像上绘制矩形,效果很好。但是现在我正在尝试添加放大和缩小功能。放大/缩小后,我需要移动矩形,才能正确进行操作。
我有3个保存矩形坐标的数组:
当我缩放画布并出于某种原因尝试在特定位置绘制矩形时,
我是Canvas和Angular的新手,请让我知道我要去哪里了。
tagger-component.ts
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 = []
currentItems = []
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.9;
public previousScale = 1.0;
@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 ++;
var s = Math.max(this.CanvasWidth / this.image.width, this.CanvasHeight / this.image.height);
console.log(s)
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
var a = this.initX * this.scale
var b = this.initY * this.scale
var c = this.uniX * this.scale
var d = this.uniY * this.scale
console.log(this.initX,this.initY,this.uniX,this.uniY)
console.log(a,b,c,d)
this.drawItems.push({
name: "",
x0: a,
y0: b,
x1: c,
y1: d
});
this.currentItems.push({
x0: a,
y0: b,
x1: c,
y1: d
});
this.originalItems.push({
name: "",
x0: Math.ceil(a * this.hRatio),
y0: Math.ceil(b * this.vRatio),
x1: Math.ceil(c *this.hRatio),
y1: Math.ceil(d * 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()
}
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.currentItems[i].x0,
this.currentItems[i].y0 ,
this.currentItems[i].x1 ,
this.currentItems[i].y1
);
this.context.lineWidth = 3;
this.context.strokeStyle = color;
this.context.stroke();
}
}
scaleUpBoundingBox(){
for (var i = 0; i < this.drawItems.length; i++) {
this.currentItems[i].x0 = this.drawItems[i].x0 * this.scale;
this.currentItems[i].y0 = this.drawItems[i].y0 * this.scale;
this.currentItems[i].x1 = this.drawItems[i].x1 * this.scale;
this.currentItems[i].y1 = this.drawItems[i].y1 * this.scale;
}
}
zoomIn(){
console.log("zooming in")
this.previousScale = this.scale
this.scale /= this.scaleMultiplier;
// console.log(this.previousScale,this. scale)
this.scaleUpBoundingBox();
this.showImage();
}
zoomOut(){
console.log("zooming out")
this.previousScale = this.scale
this.scale *= this.scaleMultiplier;
// console.log(this.previousScale,this. scale)
this.scaleUpBoundingBox();
this.showImage();
}
}
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 * scale + 'px' , 'top': drawItem.y0 *scale + '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>
tagger-component.scss
.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;
}
完整的代码可以在这里找到:https://stackblitz.com/edit/angular-ckfmpv