uni-app中drawImage绘制图片渲染空白,没报错,查看元素也有宽高。
应该是图片没加载完成就drawImage了,但是按照搜索到的解决方法在img.onload中drawImage也没解决,在img.onload中绘制,刷新页面,有时候有图片,有时候空白。
最后好像只有setTimeout才能解决,但是setTimeout的延迟时间应该设置为多少也不好确定,我试过0不行,至少要20ms才能稳定正常显示。
我还试过在img.onload回调中await img.decode()等待图片解码,在这个模拟里似乎解决了,但是在项目里也是有时正常,有时空白。
有人知道为什么会这样吗,onload 和 decode() 按理说应该已经确保了加载和解码完成,为什么还会空白?除了设置setTimeout 延迟,还有别的解决方案吗?
运行环境: H5
uni-app版本: 4.76
浏览器版本: Chrome 140.0.7339.186(正式版本) (64 位)
<template>
<view class="content">
<view class="body">
<canvas
:style="{
width: `${adjustedImageWidth}px`,
height:`${adjustedImageHeight}px`
}"
:canvas-id="canvasId"
class="canvas-img">
</canvas>
</view>
</view>
</template>
<script>
export default {
data() {
return {
adjustedImageHeight: 0,
adjustedImageWidth: 0,
canvasId: 'myCanvas'
};
},
onLoad() {
console.log('onLoad')
this.updateImageScaleInfo();
},
methods: {
updateImageScaleInfo(imageIndex) {
const imagePath = 'https://images.pexels.com/photos/19990334/pexels-photo-19990334.jpeg?auto=compress&cs=tinysrgb&w=1600&lazy=load';
uni.downloadFile({
url: imagePath,
success: (downloadRes) => {
const tempFilePath = downloadRes.tempFilePath;
uni.getImageInfo({
src: tempFilePath,
success: (res) => {
const systemInfo = uni.getSystemInfoSync();
const { safeArea } = systemInfo;
const imageHeight = res.height
const imageWidth = res.width
const containerWidth = systemInfo.windowWidth - safeArea.left;
const containerHeight = (imageHeight / imageWidth) * containerWidth;
this.adjustedImageHeight = containerWidth;
this.adjustedImageWidth = containerHeight;
// setTimeout(() => {
// this.startNewCanvasContext(tempFilePath);
// }, 500);
let img = new Image()
img.src = tempFilePath
img.onload = () => {
this.startNewCanvasContext(tempFilePath)
}
// this.startNewCanvasContext(tempFilePath)
}
});
}
});
},
startNewCanvasContext(imagePath) {
this.context = uni.createCanvasContext(this.canvasId, this);
this.context.drawImage(imagePath, 0, 0, this.adjustedImageWidth, this.adjustedImageHeight);
console.log('绘制图片', imagePath);
this.context.draw();
}
}
};
</script>
将 onLoad 换成 mounted