我在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();
答案 0 :(得分:2)
是的,context.clip很贵。
也许使用覆盖蒙版而不是剪贴蒙版。
由于您只是将叠加蒙版blitting到画布上,因此它比计算剪切路径中的像素要快得多。
第1步:抽烟
!
步骤2:绘制隐藏不需要的部分烟雾的覆盖遮罩
左:覆盖蒙版。
右:带覆盖面罩的烟雾。
示例代码和演示: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,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABjlJREFUeNqsl0lz20YQhTnYSXAxKcmS7aTKsrOUTz7lDyT//5BUDskhix27YtmSSYIrCAyQ/qYBiVaUWHKZVSBBDIh+/d7r7mHwePJN524v0zGm06lrOZGPy4t8kZcxd3tacJebJWgnCLwoCIKutXZXljY3xni+74We5wVVVduyLNfN3Z8dgJEgfhzHo7SX3hcaTJ5v55vNdhqGQbebdCeAmWfzl0VRrD4zA5plFEX9KIoHg+Hwi6Ojw2fWVsXbt29/3uV5xjXu3AoomKnrqvxcACQx44dhlPb7gwdpmt4/OTl+fnp6+n1VVeXh4cG35+fnvzRB7Wg4+lKkqtbr9blYwjZS1J8MgOhB4EdJEo/u3Rs9Pj4+ef7o0cPvDg+PngnV691ut/R9P8qyxWu+jyeTr3YiAef4REBUAOPzJiDBx8KL7qG8eknSHRP0yZPTH4aSJUxk2fwv1lSaqI8fxKBJNp+/3G63MzHkFhAcsKUgHJDbAfA8E/h+EBNkMOg/nEh2Q9GaQ93vR5PJwddVZQu9L0o3m837KI4HYtYhYKwtc3llZUkVVbaqHAv1bQCQfYDDAz9Iut3eQb/fP6HU2tLr9dKj3S5f7HbFKgjyZD6fvTg7e/Njvt3Oe93uAVkjEb+p67yyFk55/ygAlBcCBACuj5NkRDaspGnviMw5hxlozfPdYr1evZvN5i9Y68k9bV/orFZnRVluYKmuC0DU/yOBacIT3A85ut3uBPORNXQGQdjd/wUPph8URbkRyfzxePJ0uVy+EePGrIskFypF6BrXdR9613qdO7Tsgi7OlyxTNVmYrtebi+n0/W9lWWw0eFWSPYYrit0KDxAsjqMBa5gSJsRIsSRlAPvRKjDO+L6jftAfPER3AOAB1sgO7ZPEGFxOINb4jOPtDMcDdi6VgP4AAOB2m8+bUvxPAEa190J0jKNI4vcfjMfjJ8Ph4FEcJyMWoZHy02yMITBBkIrfYUikow9kWfZqtVyeifWlSryoKDpraVIfDCzvmvEkfS0v6bup1niYkjG0tkMHvcmKskJ3HVPKHvcDBikAS3CeS1fkfu65gQHjscCNTfMJmHhQy3eCcY0DGsmOo9ezubqdcitWfPIcPgGJHJQpPuGc6qURKVyVI2hcT+a+gjCea5/Nwyg7HrBYZK8Jlqb9Yxl9Y9ig3/NgrrcDm9/SjPCA0P+mobxl168qNTvXOQk+NJ9micuzRfYqlEnX0jubzf4k2GiUZ7idbohBWVcAtBjtemdnZz9dyIBiJuAV+kHLntSOVA+KXEpwZQluamgylNDFxcWvBU72/VBG7qK0Nt9IKQpUX2bBMa15Mhk/RXOoJnN+h/u5p5WGzBUAFJE5U7K69IBpa1o1rKuWjXagJElyrzGHz3fp9UMyw+Xuu5QpfYP9ASxhQJHQOiBOVs/n8DzMKM3Q1let2GjxebzzMBDyMIaLqlpZJJGy6FMVLhPNbAmlCpYMqQbjms1isfwbCVnX6+qz1qAqhdtZXlaB0VIxjgscrEOH7iVdSdovWVGe18sIM7IOMCSYTqe/LzKCd5w38IVzpvMCLNdNKbpqqIO9xmDai4Aoy2pDUMkghFbkkJMdWGGCFi2U76bT2R+r1fod4ITBDSZUZtzz6ibrQodRp9YqwwBai0EzAGSxlhvdhqFuu6JS6AXu4WJAppp2Q6RS+sWkK6nR1/R79gAA1F0QDPghUfCGslx3ml4jsTrlfivGnXZvm99IInYVCrU6HG28nLnwBfsELM0gqoKwhDFoBqw4zxd9Ir47JzWfDJomVrUHQOvjKroaBgORDQEZrzqKBYFIURR2tSrX77iPtdYD1WXL9XzditkCBrimbFgMuL8hEUGq+l8zse0PrelcZkL9VcnWtt0PlKU2o9qvK52Qtd033Z7r6+t/Wm7aEdWNeRofoKVxdXxlJG2rzDKpaQp7p7NfG04LUr3wwQg213fGwc1/wdREQNBMOgVGbB/Yzoy297d1vs9cY+I9XdVTtwLQYEA724LRLun5jSS1jlctNwHottty7rOda9arVve9dl/d+n9Bg9buZ3c1NaEZZ7NuXG93vUa3XDDnEtjLdo+LT/tzWmvZwLyhvdpGItipWnvVrkBKe5d/3P8IMAB3LDj0/a4R5QAAAABJRU5ErkJggg==";
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>