Canvas 中 drawImage 使用记录
项目背景
最近在项目中遇到一个bug,记录下解决方案。该项目使用canvas的绘制功能,在画布中绘制各种图形以及图片等。其中图片资源的绘制使用的是CanvasDrawImage:
interface CanvasDrawImage {
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/drawImage) */
drawImage(image: CanvasImageSource, dx: number, dy: number): void;
drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;
drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
}
例如,通过下面的方式绘制svg图标
ctx.drawImage(
Graphics.getImageSource(svg)!,
rect.left,
rect.top,
15,
15,
);
其中 ctx 是 OffscreenCanvasRenderingContext2D 类型。
问题现象
- 将绘制的文件(包含
image)导出到本地磁盘,再次加载保存的文件,在canvas初次渲染的时候,图标未显示出来;
解决方案
- 在
img.onload()回调方法中执行绘制操作,即:
svgImg.onload = function () {
ctx.drawImage(svgImg, imgX, imgY, imgWidth, imgHeight);
};
以上方案解决了图片初次加载不显示的问题,但鼠标选中包含图标资源的元素时,图标会出现模糊闪动的现象。优化方案如下:
- 使用
img.complete来判断图片是否已加载完成,如果加载完成,则无需在加载回调中执行绘制操作,即:
if (svgImg.complete) { // 如果图片已经存在于浏览器缓存,直接调用回调函数
ctx.drawImage(svgImg, imgX, imgY, imgWidth, imgHeight);
} else {
svgImg.onload = function () {
ctx.drawImage(svgImg, imgX, imgY, imgWidth, imgHeight);
};