使用剪辑区域减慢画布性能

时间:2014-06-30 12:20:04

标签: canvas html5-canvas

我在Canvas中使用粒子发射器创建了一些烟雾。一切都很好但设计要求我在画布上添加一个遮罩,这样我们就可以看到页面背景了。当我添加剪辑区域时,我的性能极差,尤其是在Safari中。在使用剪辑区域时,我可以做些什么来优化性能?

这是没有面具的烟雾

http://codepen.io/fatlinesofcode/pen/AcLim

并使用面具

http://codepen.io/fatlinesofcode/pen/GLFqf

我每次都在渲染循环中绘制一个矢量区域。

ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(960, 00);
ctx.lineTo(960, 500);
ctx.lineTo(960 / 2, 550);
ctx.lineTo(0, 500);
ctx.closePath();
ctx.clip();
ctx.restore();

1 个答案:

答案 0 :(得分:2)

是的,context.clip很贵。

也许使用覆盖蒙版而不是剪贴蒙版。

由于您只是将叠加蒙版blitting到画布上,因此它比计算剪切路径中的像素要快得多。

第1步:抽烟

enter image description here

步骤2:绘制隐藏不需要的部分烟雾的覆盖遮罩

左:覆盖蒙版。
右:带覆盖面罩的烟雾。

enter image description here enter image description here

示例代码和演示:http://jsfiddle.net/m1erickson/uHg4E/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var maskCanvas=document.createElement("canvas");
    var maskCtx=maskCanvas.getContext('2d');

    var img=new Image();
    img.onload=start;
    img.src="https://dl.dropboxusercontent.com/u/139992952/multple/mountain.png";
    function start(){

        makeOverlayMask();

        var smokeImage = new Image();
        smokeImage.src = "data:image/png;base64,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";
        smokeImage.onload = function () {

            ctx.clearRect(0,0,canvas.width,canvas.height);
            for(var y=0;y<canvas.height;y+=smokeImage.height){
                ctx.drawImage(smokeImage,canvas.width/2-15,y);
            }
            ctx.drawImage(maskCanvas,0,0);

        }
    }

    function makeOverlayMask(){
        maskCanvas.width=img.width;
        maskCanvas.height=img.height+166;
        //
        maskCtx.drawImage(img,0,166);
        //
        maskCtx.save();
        maskCtx.globalCompositeOperation="destination-out";    
        maskCtx.beginPath();
        maskCtx.moveTo(0, 0);
        maskCtx.lineTo(320, 00);
        maskCtx.lineTo(320, 166);
        maskCtx.lineTo(320 / 2, 183);
        maskCtx.lineTo(0, 166);
        maskCtx.closePath();
        maskCtx.fill();
        maskCtx.restore();
    }

}); // end $(function(){});
</script>
</head>
<body>
    <canvas id="canvas" width=320 height=300></canvas>
</body>
</html>