Brett
Brett

Reputation: 332

angular2 drawImage on canvas after change detetion

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

Answers (2)

eta32carinae
eta32carinae

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

Brett
Brett

Reputation: 332

@rinukkusu answer is correct, thank you!

Maybe try calling the render method in ngAfterViewChecked

Upvotes: 1

Related Questions