为什么我这段canvas绘图会在一到两分钟之后变慢然后持续变慢,最后很卡很卡的样子

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div>
  <canvas id="water" height="0" width="0" ref="canvas"></canvas>
  <!--        <img ref="pumpImg" src="https://cdn.gosafenet.com/static/images/bdrc/pump.png" style="display: none"/>-->
  <!--        <img ref="pumpActiveImg" src="https://cdn.gosafenet.com/static/images/bdrc/pumpActive.png"-->
  <!--             style="display: none"/>-->
  <img ref="pumpNormal" id="pump" src="https://cdn.gosafenet.com/static/images/board/waterPumpStatus/pumpNormal.png"
      style="display: none"/>
  <img ref="pumpWarn" src="https://cdn.gosafenet.com/static/images/board/waterPumpStatus/pumpWarn.png"
      style="display: none"/>
  <img ref="pumpDanger" src="https://cdn.gosafenet.com/static/images/board/waterPumpStatus/pumpDanger.png"
      style="display: none"/>
  <img ref="pumpOffline" src="https://cdn.gosafenet.com/static/images/board/waterPumpStatus/pumpOffline.png"
      style="display: none"/>
  <img ref="fanNormal" id="fans" src="https://cdn.gosafenet.com/static/images/board/waterPumpStatus/fanNormal.png"
      style="display: none"/>
  <img ref="fanWarn" src="https://cdn.gosafenet.com/static/images/board/waterPumpStatus/fanWarn.png"
      style="display: none"/>
  <img ref="fanDanger" src="https://cdn.gosafenet.com/static/images/board/waterPumpStatus/fanDanger.png"
      style="display: none"/>
  <img ref="fanOffline" src="https://cdn.gosafenet.com/static/images/board/waterPumpStatus/fanOffline.png"
      style="display: none"/>
</div>
</body>
</html>
<script>
  let canvas = document.getElementById('water')
  let fans = document.getElementById('fans')
  let pump = document.getElementById('pump')
  let fansRotate = 0;
  let dashList = [10, 8]
  let offset = 0
  let animationFrame=null;
  let ctx = canvas.getContext('2d');

  setCanvasSize();
  paint();
  paint(); paint();

  function paint() {
    ctx.clearRect(0, 0, 1000, 291); // 清空画布
    ctx.drawImage(pump, 0, 0, 1000,291);
    ctx.save()

    //绘制旋转的风扇


    fansRotate +=3
    if(fansRotate>3000){
      fansRotate=0
    }

    ctx.translate(412, 151);
    ctx.rotate(fansRotate*Math.PI/180)
    ctx.translate(-412, -151);
    // ctx.drawImage(fanImgUrl, 383, 126,124,124,0,0,100,100)
    ctx.drawImage(fans, 0, 0, 124, 124, 387, 126, 50, 50)

    ctx.restore()

    ctx.beginPath();
    ctx.strokeStyle = "rgba(12,85,76,0.9)"
    ctx.lineWidth = 20;
    ctx.setLineDash(dashList);
    ctx.moveTo(58, 153);
    ctx.lineTo(340, 153);
    ctx.moveTo(470, 238);
    ctx.lineTo(528, 238);
    ctx.moveTo(586, 238);
    ctx.lineTo(950, 238);
    offset -= 1
    if (offset < -36) {
      offset = 0
    }
    ctx.lineDashOffset = offset;
    ctx.stroke();
    ctx.save()
    ctx.beginPath()
    ctx.stroke();

    requestAnimationFrame(paint)
  }

  function setCanvasSize() {
    canvas.width = 1000;
    canvas.height = 291
  }
</script>

不知道为什么,运行一会儿之后,旋转就会变卡,怎么都想不到原因,有高手能看下吗?

阅读 4.5k
3 个回答

可能是你的ctx.save调用的问题,被压入画布栈的太多了,超出了内存,建议把上一次绘画逻辑抽出来直接重绘

不是慢卡.
而是你的一次正常paint就是这么慢.

你连续3次调用,使得一开始单次绘制中,全局变量fansRotateoffset增加的幅度就很大.后面经过requestAnimationFrame的协同,多次paint正好叠加到了一起,渐渐趋同于单次paint,就很慢了.

你可以保留一次paint调用,然后fansRotate单次幅度增加到9,offset增加到3,就可以保持这种速度了.

建议封装一下,不要使用全局变量.这样即便是真的要多次绘制,也避免互相影响.

内存没有溢出,楼上正解,只是你连续调用了三次paint,并且每次都requestAnimationFrame,最后风扇转速逐渐趋于+3而不是+9了,所以感觉越转越慢。

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