问题描述
当频繁加载图片并渲染的时候,出现加载渲染图片的控件在两张图片切换的过程中出现白色闪烁的问题。
问题排查
查看源代码后,发现html中用 元素来显示图片的。 并且通过改变:src="jpgPath"的值来替换图片。
解决方法:
临时解决方法: 用canvas 绘制图片的方式来代替 。
新问题: 1. canvas 直接不断的绘制image,会出现闪屏的问题。
解决方法:使用双缓存解决 Canvas clearRect 引起的闪屏问题 : 使用双缓存解决问题
updateCanvas(){
const canvas = document.getElementById('canvas'); // 获取页面中的 canvas
const ctx = canvas.getContext('2d');
const tempCanvas = document.createElement('canvas'); // 新建一个 canvas 作为缓存 canvas
const tempCtx = tempCanvas.getContext('2d');
tempCanvas.width = 1448; tempCanvas.height = 750; // 设置宽高
// 开始绘制
tempCtx.drawImage(bg,0,0); // 背景
... // 省略其他绘制过程
// 缓存 canvas 绘制完成
ctx.clearRect(0,0,1448,750); // 清空旧 canvas
ctx.drawImage(tempCanvas,0,0); // 将缓存 canvas 复制到旧的 canvas
}
总结
重绘画布的时候,我们需要使用 clearRect 来清空画布,此时的画布是空的,开始重绘后,如果内容较多,时间也就相应的增加,因此视觉出现了空档期,我们就看到了闪屏的情况;
解决闪屏,其实就是怎么解决绘制时间较长的问题;
这里参考了图形图象处理编程中 双缓存 的概念,将绘制过程交给了 缓存 canvas,这样页面中的 canvas 就省去了绘制过程,而 缓存 canvas 并没有添加到页面,所以我们就看不到绘制过程,也就解决了闪屏的问题。
问题2 : 如何把图片缩放到canvas的大小
解决方法:在drawImage后面多添加两个参数值:canvas.width,canvas.height 就可以了。
tempCtx.drawImage(img1,0,0,canvas.width,canvas.height);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(tempCanvas,0,0,canvas.width,canvas.height);
最终代码:
updateCanvas(jpgPath) {
const canvas = document.getElementById('canvasImage');
const ctx = canvas.getContext('2d');
//canvas.width = 400;
//canvas.height = 400;
//canvas.style.border = '1px solid #ccc';
const tempCanvas = document.createElement('canvas');
const tempCtx = tempCanvas.getContext('2d');
//tempCanvas.width = 400;
//tempCanvas.height = 400;
var img1 = new Image();
img1.src= jpgPath;//只要设置了src属性,当前img对象立即去加载图片。
//第二步,图片加载完成后,把图片绘制到canvas上
img1.onload = function() {
tempCtx.drawImage(img1,0,0,canvas.width,canvas.height);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(tempCanvas,0,0,canvas.width,canvas.height);
};
},
// 获取当前帧的jpg路径
getPicPath() {
let _this = this;
axios.get(this.apiUrl + '/get_frame_jpg')
.then(function (response) {
console.log(response.data.data.pcdPath);
_this.jpgPath = _this.pcdUrl + response.data.data.jpgPath
_this.updateCanvas(_this.jpgPath); //核心,就是改为canvas绘制图片。
})
.catch(function (error) {
console.log(2,error);
});
},