Angular 5 with Canvas drawImage not showing up
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);
}
Related videos on Youtube
Tommy J
Updated on September 15, 2022Comments
-
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 almost 6 yearsSorry, this doesn't seem to work. The image doesn't show up at all.
-
Abel Valdez almost 6 yearsDid you tried ? I have in my GitHub working like that
-
user2649601 over 5 yearsYou could use do the draw in the
onload
of the image, i.e.let image = new Image(); image.onload = function() { this.draw() }; image.src = '///';