typescript - Angular 5 med Canvas drawImage vises ikke
Prøver å legge til et bakgrunnsbilde på canvas ved å bruke drawImage, men det vises ikke. Jeg vet at banen til bildet er korrekt fordi jeg kan gjøre <img src="{{ imageName }}" /> og det fungerer. Alt annet fungerer fint i JavaScript, men oversettes ikke godt til Angular.
HTML :
<canvas #canvas></canvas>
TypeScript:
import { Component, OnInit } from '@angular/core';
...
@Component({
selector: 'app-box-picker',
templateUrl: './box-picker.component.html',
styleUrls: ['./box-picker.component.css']
})
export class BoxPickerComponent implements OnInit {
@ViewChild('canvas') public canvas: ElementRef;
canvasEl: any;
ctx: CanvasRenderingContext2D;
@Input() public width = 535.0;
@Input() public height = 669.25;
mousePosition: any;
isMouseDown: boolean;
dragoffx: number;
dragoffy: number;
circles: any;
imageObj = new Image();
imageName = "../../assets/pdf.png";
constructor() {
}
ngOnInit() {
}
public ngAfterViewInit() {
this.canvasEl = this.canvas.nativeElement;
this.ctx = this.canvasEl.getContext('2d');
this.canvasEl.width = this.width;
this.canvasEl.height = this.height;
this.imageObj.src = this.imageName;
console.log(this.imageName);
console.log(this.imageObj);
// init circles
var c1 = new Circle();
c1.init(50, 50, 15, "rgba(217,83,79, .5)", "black", this.ctx);
// console.log(c1);
c1.out();
this.circles = [c1];
this.draw();
this.captureDownEvents(this.canvasEl);
this.captureMoveEvents(this.canvasEl);
this.captureUpEvents(this.canvasEl);
}
draw() {
//clear canvas
this.ctx.clearRect(0, 0, this.canvasEl.width, this.canvasEl.height);
this.ctx.drawImage(this.imageObj, 0, 0, this.canvasEl.width, this.canvasEl.height);
this.drawCircles();
}
drawCircles() {
for (var i = this.circles.length - 1; i >= 0; i--) {
this.circles[i].draw();
}
}
...
}
Når jeg gjør en console.log(this.imageObj); får jeg noen ganger <img src="../../assets/pdf.png"> og andre ganger får jeg bare <img>. Har det noe å gjøre med det?
Svar #1
@Kaiido har rett. Jeg må vente på at bildet lastes. Jeg bruker setTimeout(e => this.draw(), 500); inntil jeg finner en bedre løsning.
Svar #2
Du kan også pakke onload inn i en Promise og bruke async/await-mønsteret for dette:
export async function loadImage(src: string): Promise<HTMLImageElement> {
const image = new Image();
image.src = src;
return new Promise(resolve => {
image.onload = (ev) => {
resolve(image);
}
});
}
Bruk:
async drawImage() {
const image: HTMLImageElement = await loadImage('assets/pdf.png');
this.ctx = this.canvas.nativeElement.getContext('2d');
this.ctx.drawImage(image, 0, 0, image.width, image.height);
}
