提高 html canvas mousemove 图像蒙版的性能

nae*_*luh 2 javascript performance canvas

我有一个画布,正在绘制图像并进行剪辑以创建图像被显示的效果。我的代码工作正常,我尝试使用 debouce 方法和 rAF 来提高画布渲染性能,但我只看到了很小的收益(如果有的话)。

我怀疑我迭代 x 和 y 坐标数组的方式可能是问题所在。当将数组放入控制台时,其速度似乎与屏幕上出现的圆圈相同。

这是重绘函数:

  function redraw(mouse) {
     m.push(mouse);
     m.forEach(function (a) {
        ctx.drawImage(img, 0, 0);
        ctx.beginPath();
        ctx.rect(0, 0, 500, 500);
        ctx.arc(a.x, a.y, 70, 0, Math.PI * 2, true);
        ctx.clip();
        ctx.fillRect(0, 0, 500, 500)
      })
    }
Run Code Online (Sandbox Code Playgroud)

我想我正在寻找的是一些加快我的代码速度的建议,以便圆圈的渲染看起来更像绘图。

这是工作演示 -> http://jsfiddle.net/naeluh/4h7GR/

Gam*_*ist 5

这里有几个问题:
\n\xe2\x80\xa2 你的鼠标代码是一场噩梦,每次移动都会遍历 DOM。
\n\xe2\x80\xa2 您每次移动都会重绘所有内容。

\n\n

所以我建议一种更有效的解决方案:
\n\xe2\x80\xa2 堆叠两个画布,下面的一个是你的图像,上面的一个是蒙版。
\n\xe2\x80\xa2 有效地处理鼠标。
\n\xe2\x80\xa2 鼠标移动时仅清除遮罩画布的一部分:每次移动仅在遮罩画布上绘制一个圆圈。
\n (为此我使用了 globalCompositeOperation = \'destination-out\' )

\n\n

结果无论是在 Firefox、Chrome 或 Safari 上都非常流畅。

\n\n

(在 Mac 操作系统上测试)。

\n\n

小提琴: \n(您必须单击才能清除)

\n\n

http://jsfiddle.net/gamealchemist/4h7GR/22/

\n\n

html

\n\n
<canvas   style=\'position: absolute; top: 0;left: 0;\' id="canvas1" width="500" height="500"></canvas>\n<canvas style=\'position: absolute;top: 0;left: 0;\' id="canvas2" width="500" height="500"></canvas>\n
Run Code Online (Sandbox Code Playgroud)\n\n

js

\n\n
var can = document.getElementById("canvas1");\nvar ctx = can.getContext("2d");\nvar can2 = document.getElementById("canvas2");\nvar ctx2 = can2.getContext("2d");\n\nvar img = new Image();\nimg.onload = function () { ctx.drawImage(img,0,0); };\nimg.src = "http://placekitten.com/500/500";\n\nctx2.fillStyle=\'#000\';\nctx2.fillRect(0,0,500,500);\nctx2.globalCompositeOperation = \'destination-out\';\n\nfunction clearThis(x,y) {\n    console.log(\'toto\');\n    ctx2.fillStyle=\'#F00000\';\n    ctx2.beginPath();\n    ctx2.arc(x, y, 70, 0, Math.PI * 2, true);\n    ctx2.fill();\n}\n\nvar mouse = {\n    x: 0,\n    y: 0,\n    down: false\n};\n\nfunction setupMouse(canvas, onMouseMove, preventDefault) {\n    var rectLeft, rectTop;\n    var hook = canvas.addEventListener.bind(canvas);\n    var mouseDown = updateMouseStatus.bind(null, true);\n    var mouseUp = updateMouseStatus.bind(null, false);\n    hook(\'mousedown\', mouseDown);\n    hook(\'mouseup\', mouseUp);\n    hook(\'mousemove\', updateCoordinates);\n    hook(\'scroll\', updateRect);\n    // var mouseOut = function() { mouse.down=false ; } ;\n    // hook(\'mouseout\', mouseOut); \n    function updateMouseStatus(b, e) {\n        mouse.down = b;\n        updateCoordinates(e);\n        if (preventDefault) {\n            e.stopPropagation();\n            e.preventDefault();\n        }\n    }\n\n    function updateCoordinates(e) {\n        mouse.x = (e.clientX - rectLeft);\n        mouse.y = (e.clientY - rectTop);\n        onMouseMove(mouse.x, mouse.y);\n    }\n\n    function updateRect() {\n        var rect = canvas.getBoundingClientRect();\n        rectLeft = rect.left;\n        rectTop = rect.top;\n    }\n    updateRect();\n};    \nsetupMouse(can2, clearThis, true);\n
Run Code Online (Sandbox Code Playgroud)\n