Vue Canvas绘制矩形及解决clearRect闪屏的双缓冲方案

作者:青山有信

时间:2026-10-23

浏览:321

本文介绍在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带来的闪屏问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对本站网站的支持! 如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章