Reputation: 332
I have an angular2 component:
@Component({
selector: 'my-image',
template: `
<img #img src="{{src}}" style='display: none;' />
<canvas #canvas width="{{width}}" height="{{height}}"></canvas>`
})
export class ImageComponent implements AfterViewInit {
@ViewChild('canvas') canvas: ElementRef;
@ViewChild('img') img: ElementRef;
private ctx: CanvasRenderingContext2D;
private element: HTMLImageElement;
src: string;
width: number;
height: number;
constructor(canvas: ElementRef, img: ElementRef) {
this.width = window.innerWidth;
this.height = window.innerHeight;
this.src = 'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png';
}
ngAfterViewInit() {
this.ctx = this.canvas.nativeElement.getContext('2d');
this.element = this.img.nativeElement;
}
@HostListener('window:resize')
resize() {
this.width = window.innerWidth;
this.height = window.innerHeight;
this.render();
}
clear() {
this.ctx.clearRect(0, 0, this.width, this.height);
}
render() {
this.clear();
this.ctx.drawImage(this.element, 0, 0, 400, 400);
}
}
So everything works great, however, when i resize the window, the resize callback get hit and calls render. Then the binding on the canvas happens which resets the context and im left with a blank canvas. My initial thought was to call render again after the change detection occurred. Is that the right approach or is there a better way?
Thanks
Upvotes: 1
Views: 1978
Reputation: 611
The accepted answer doesn't seem to be an optimal solution because ngAfterViewChecked
is gonna be called multiple times. Another solution is this:
ngAfterViewInit() {
this.bgImg = new Image();
this.bgImg.src = this.img;
const ctx = this.canvasElement.getContext('2d');
this.bgImg.onload = () => {
ctx.drawImage(this.bgImg, 0, 0, this.canvasElement.width, this.canvasElement.height);
}
}
Upvotes: 0
Reputation: 332
@rinukkusu answer is correct, thank you!
Maybe try calling the render method in
ngAfterViewChecked
Upvotes: 1