Angular 5 with Canvas drawImage not showing up

11,998

Solution 1

@Kaiido is correct. I need to wait for the image to load. I'm using setTimeout(e => this.draw(), 500); until I figure out a better solution.

Solution 2

try by using the following code:

Component HTML

<img #pdf style="display: none;" src="assets/pdf.png" />
<canvas #canvas></canvas>

Component.ts

 @ViewChild('canvas') public canvas: ElementRef;
 //Assets
 @ViewChild('pdf') imageObj: ElementRef;
 canvasEl: any;
 ctx: CanvasRenderingContext2D;
 ...
 draw() {
    ...
    this.ctx = this.canvas.nativeElement.getContext('2d');
    this.ctx.drawImage(imageObj.nativeElement, width, height);     
 }
 ...

Finaly all your code is ok. Just implement the loading image by using Element Ref.

Solution 3

in your javascript (or typescript code, you can someting like this to solve the timeout of the image:

var ctx = element.getContext("2d");
var img = new Image();
img.onload = function() {
    ctx.drawImage(img, 0, 0, img.width, img.height);
    // do other canvas handling here!
}
img.src = "assets/images/image.png";

This working 100% on HTML5, but have not tried to us it withing ts files. Hope this helps!

Solution 4

You can also wrap the onload in a Promise and use the async/await pattern for this:

export async function loadImage(src: string): Promise<HTMLImageElement> {
    const image = new Image();
    image.src = src;
    return new Promise(resolve => {
        image.onload = (ev) => {
            resolve(image);
        }
    });
}

Usage:

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);
}
Share:
11,998

Related videos on Youtube

Tommy J
Author by

Tommy J

Updated on September 15, 2022

Comments

  • Tommy J
    Tommy J over 1 year

    Trying to add a background image to canvas using drawImage and it's not showing up. I know the path to the image is correct because I can do <img src="{{ imageName }}" /> and that works. Everything else works fine in JavaScript but doesn't translate well to 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();
        }
      }
    ...
    }
    

    When I do a console.log(this.imageObj); sometimes I get <img src="../../assets/pdf.png"> and other times I get only <img>. Does that have anything to do with it?

  • Tommy J
    Tommy J almost 6 years
    Sorry, this doesn't seem to work. The image doesn't show up at all.
  • Abel Valdez
    Abel Valdez almost 6 years
    Did you tried ? I have in my GitHub working like that
  • user2649601
    user2649601 over 5 years
    You could use do the draw in the onload of the image, i.e. let image = new Image(); image.onload = function() { this.draw() }; image.src = '///';