在vue框架下,canvas出现闪屏效果应该如何解决??

在vue框架下,canvas双缓冲是怎样实现,我现在已经在canvas添加了双缓冲,为何页面还是会出现闪屏效果??是我添加错了吗??
搜了好多例子都说做双缓存就可以,但是好像我这边拖拽图片还是一直闪,我这个双缓冲是做错了吗??

// 绘制
  drawCanvasFun () {
  this.canvasSize.drawCanvasWidth = this.$refs.flDiv.offsetWidth
  this.canvasSize.drawCanvasHeight = this.$refs.flDiv.offsetHeight

  var drawCanvas = document.getElementById('drawCanvas')
  var drawContext = drawCanvas.getContext('2d')
  drawCanvas.width = this.canvasSize.drawCanvasWidth
  drawCanvas.height = this.canvasSize.drawCanvasHeight

  var cacheCanvas = document.getElementById('cacheCanvas')
  var cacheCanvasCxt = cacheCanvas.getContext('2d')
  cacheCanvas.width = this.canvasSize.drawCanvasWidth
  cacheCanvas.height = this.canvasSize.drawCanvasHeight

  // 绘制直线
  // 绘制图片
  if (this.canvasData.length > 0) {
    this.canvasData.forEach((item, index) => {
      // this.drawImg(drawContext, item.source, item.x, item.y, item.width, item.height, item.key)
      this.drawImg(cacheCanvasCxt, item.source, item.x, item.y, item.width, item.height, item.key)
    })

  }
  if (this.canvasLineData.length > 0) {
    // console.log('this.canvasLineData', this.canvasLineData)
    this.canvasLineData.forEach((item, index) => {

      this.drawLine(item.point[0].x, item.point[0].y, item.point[1].x, item.point[1].y, item.point[0].point, item.point[1].point, index, item.color, 'cacheCanvasCxt')

      drawContext.drawImage(cacheCanvas, 0, 0, drawCanvas.width, drawCanvas.height)
    })
  }

},
// 绘制图片
drawImg (drawContext, source, x, y, width, height, key) {
  var drawCanvas = document.getElementById('drawCanvas')
  var dxt = drawCanvas.getContext('2d')
  var cacheCanvas = document.getElementById('cacheCanvas')
  var cacheCanvasCxt = cacheCanvas.getContext('2d')
  drawContext.save()
  drawContext.beginPath();
  // 绘制四个点
  // drawContext.moveTo(x + width / 2 - 2, y)
  // drawContext.lineTo(x + w / 2 + 2, y)
  // drawContext.lineTo(x + w / 2 + 2, y + 4)
  // 四个点宽
  let rectWidth = 6
  // var img = new BufferedImag()
  var img = new Image()
  img.src = source
  img.onload = () => {

    // drawContext.drawImage(img, this.moveToolImg.x, this.moveToolImg.y, this.moveToolImg.width, this.moveToolImg.height)
    drawContext.drawImage(img, x, y, width, height)

    drawContext.beginPath()
    drawContext.fillStyle = 'rgba(255,0,0,0.3)'
    drawContext.fillRect(x + width / 2 - rectWidth / 2, y, rectWidth, rectWidth) //上
    drawContext.fillRect(x + width - rectWidth, y + height / 2 - rectWidth / 2, rectWidth, rectWidth)//右
    drawContext.fillRect(x + width / 2 - rectWidth / 2, y + height - rectWidth, rectWidth, rectWidth)//下
    drawContext.fillRect(x, y + height / 2 - rectWidth / 2, rectWidth, rectWidth)//左
    drawContext.closePath()



    this.canvasData.forEach((item, index) => {
      // var img = new Image()
      if (key == item.key) {
        // fourPoint
        item['fourPoint'] = [
          {//上
            x: x + width / 2 - rectWidth / 2,
            y: y,
            point: 'T'
          },
          {//右
            x: x + width - rectWidth,
            y: y + height / 2 - rectWidth / 2,
            point: 'R'
          },
          {//下
            x: x + width / 2 - rectWidth / 2,
            y: y + height - rectWidth,
            point: 'B'
          },
          {//左
            x: x,
            y: y + height / 2 - rectWidth / 2,
            point: 'L'
          },
        ]
      }
    })
    // console.log('this.canvasData', this.canvasData)
    dxt.clearRect(0, 0, drawCanvas.width, drawCanvas.height);
    dxt.save()
    dxt.drawImage(cacheCanvas, 0, 0, drawCanvas.width, drawCanvas.height)
    dxt.restore()


    return true
  }
  drawContext.restore()

  // dxt.save()
  // dxt.drawImage(cacheCanvas, 0, 0, drawCanvas.width, drawCanvas.height)
  // dxt.restore()
  cacheCanvasCxt.clearRect(0, 0, cacheCanvas.width, cacheCanvas.height);
},
阅读 3.5k
2 个回答

this.canvasData 你不要放 data 里试一下。
猜测是数据变化造成视图频繁变化,也就是你说的闪屏问题

你没有必要自己实现所谓双缓冲,canvas内部已经帮你实现了,如果有所谓的闪屏问题一定是canvas元素本身发生了重绘,你可以排查一下这方面

下面的例子能观察到黑红切换吗。。。

var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 100, 100);

// Do something that takes a long time
var start = Date.now();
var sum = 0;
for (var j = 0; j < 9; j++) {
  for (var k = 0; k < 9999; k++) {
    for (var i = 0; i < 9999; i++) {
      sum += Math.sqrt(i);
    }
  }
}
console.log(Date.now() - start);

ctx.fillStyle = "red";
ctx.fillRect(0, 0, 100, 100);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题