本文介绍在Vue中使用Canvas绘制矩形时,因频繁调用clearRect清空整个画布导致的屏幕闪烁问题。通过引入双缓冲机制,利用临时层与显示层分离的策略,仅清空临时层并合并图像,有效解决了绘制过程中的视觉闪烁,提升了交互体验。
Canvas矩形绘制与闪屏问题
在Canvas中绘制矩形时,由于需要实时监测鼠标移动轨迹,屏幕上会不断生成新的矩形框。
官方提供的ctx.clearRect()方法虽然能清除图形,但它会清空整个画布内容。
为了保持图像可见,必须不断重新绘制新图片,这种频繁的清空与重绘操作导致了明显的屏幕闪烁现象。
针对这一交互体验问题,需要寻找更优的渲染策略。
双缓冲解决方案
微软提出的双缓冲图形技术为此提供了思路,该技术通过分离渲染状态来优化显示效果。
具体实现中,需要创建两个Canvas图层:一个用于临时绘制,另一个用于最终显示。
将鼠标监听事件绑定在显示层上,每次执行清空操作时仅针对临时层进行清理,从而避免整体画面的闪烁。
以下是实现该逻辑的关键代码片段。
代码实现与事件处理
<!--临时层-->
<canvas id="customPositionImg2" ref="table2" style=" display:none;"></canvas>
<!--显示层 增加鼠标按下,移动,松开事件-->
<canvas id="customPositionImg" ref="table" @mousedown="mousedown" @mousemove="mousemove" @mouseup="mouseup" style=""></canvas>
在显示层中渲染背景图片的逻辑如下。
//因为项目是dialog展示自定义画板,所以图片展示就写在了dialog打开的钩子里,如果需要直接复制
vue.nextTick里面的代码就行
show () {
vue.nextTick(_ => {
let customCanvas =this.$refs.table;// canvas显示层
this.customstyle ='';
customCanvas.height = 740;
customCanvas.width = 1460;
this.customcxt = customCanvas.getContext("2d");
let img = new Image();
img.src = this.imgSrc;
let that = this;
img.onload = function () {
that.customRwidth = customCanvas.width / img.width; //原图与展示图片的宽高比
that.customRheight = customCanvas.height / img.height;
that.customcxt.drawImage(img, 0, 0, customCanvas.width, customCanvas.height);
};
})
},
鼠标交互事件的处理代码包括按下、移动和松开三个状态。
//鼠标按下时执行
mousedown(e){
this.isMouseDownInCanvas = true;
// 鼠标按下时开始位置与结束位置相同 防止鼠标在画完矩形后 点击图画形成第二个图形
this.endX = e.offsetX;
this.endY = e.offsetY;
this.startX = e.offsetX;
this.startY = e.offsetY;
},
//鼠标移动式时执行
mousemove(e){
if (this.isMouseDownInCanvas){ // 当鼠标有按下操作时执行
console.log( e.offsetX,e.offsetY);
if((this.endX != e.offsetX)||( this.endY != e.offsetY)){
this.endX = e.offsetX;
this.endY = e.offsetY;
let wwidth = this.endX - this.startX;
let wheigth = this.endY - this.startY;
let tempCanvas = this.$refs.table2; // canvas临时层
let tempCtx = tempCanvas.getContext('2d');
tempCanvas.width = 1460; tempCanvas.height = 740; // 设置宽高
// 清除临时层指定区域的所有像素
tempCtx.clearRect(0, 0, 1460, 740);
// 重新展示图片
let img = new Image();
img.src = this.imgSrc;
let that = this;
img.onload = function () {
that.customcxt.drawImage(img, 0, 0,1460, 740);
};
this.customcxt.strokeStyle=" #00ff00"; //矩形框颜色
this.customcxt.lineWidth="2"; //矩形框宽度
this.customcxt.strokeRect(this.startX,this.startY,wwidth,wheigth); //绘制矩形
}else{
//鼠标按下静止时显示矩形的大小。
let wwidth2 = this.endX - this.startX;
let wheigth2 = this.endY - this.startY;
this.customcxt.strokeRect(this.startX,this.startY,wwidth2,wheigth2)
}
}
},
//鼠标松开时执行
mouseup(e){
this.isMouseDownInCanvas = false;
// 绘制最终的矩形框
let wwidth = this.endX - this.startX;
let wheigth = this.endY - this.startY;
this.customcxt.strokeRect(this.startX,this.startY,wwidth,wheigth)
},
通过上述双缓冲机制,可以在保持交互流畅性的同时消除绘制矩形时的闪烁问题。
以上所述是小编给大家介绍的vue cavnas绘制矩形并解决由clearRec带来的闪屏问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对本站网站的支持! 如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!