I'm using the html canvas from inside Blazor hybrid using JSInterop.
So far it was working fine, but now I need to add a picture on the canvas and it is not working.
I have placed the picture in the wwwroot/Images/Image2.jpg folder. In the JS file I have:
let canvasCtx;
const image = new Image();
image.src = 'Images/Image2.jpg';
function InitBgndImage1(chart) {
canvasCtx = chart.getContext("2d");
//canvasCtx.beginPath();
//canvasCtx.rect(20, 20, 150, 100);
//canvasCtx.stroke();
canvasCtx.drawImage(image, 0, 0);}
The function is called from the Blazor file as follows:
<div class="chart-container">
<canvas @ref="chartCanvas"></canvas>
@code { ElementReference chartCanvas;
protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
JS.InvokeVoidAsync("InitBgndImage1", chartCanvas);
}
}
The rectangle is drawn when not commented but the picture never displays.
What could be the reason?
This is not due to Blazor but due to Javascript.
When you set image.src = 'Images/Image2.jpg';
, the image is not actually loaded yet. You have to wait for it to load before drawing.
Try this:
document.querySelector("button").addEventListener("click", async () => {
const img = new Image();
await new Promise(r => {
img.onload = r;
img.src = "https://fastly.picsum.photos/id/237/200/300.jpg?hmac=TmmQSbShHz9CdQm0NkEjx1Dyh_Y984R9LpNrpvH2D_U";
});
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
});
<p>
<button>Draw</button>
</p>
<canvas></canvas>
If you didn't wait, you can see it doesn't work as well (a cache may make it work the 2nd attempt):
document.querySelector("button").addEventListener("click", () => {
const img = new Image();
img.src = "https://fastly.picsum.photos/id/237/200/300.jpg?hmac=TmmQSbShHz9CdQm0NkEjx1Dyh_Y984R9LpNrpvH2D_U";
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
});
<p>
<button>Draw</button>
</p>
<canvas></canvas>