Reputation: 441
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?
Upvotes: 9
Views: 16928
Reputation: 3237
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);
}
Upvotes: 4
Reputation: 2408
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.
Upvotes: 2
Reputation: 31
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!
Upvotes: 3
Reputation: 441
@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.
Upvotes: 7