2014-06-30 3 views
1

Я создаю дым, используя излучатель частиц в холсте. Все работает отлично, но для дизайна требуется добавить маску к холсту, чтобы мы могли видеть фон страницы. Когда я добавляю область отсечения, я получаю крайне низкую производительность, особенно в 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(); 

ответ

2

Да, context.clip стоит дорого.

Возможно, используйте маску наложения вместо обтравочной маски.

Поскольку вы просто blitting маску наложения на холст, это намного быстрее, чем вычисление, какие пиксели находятся в обтравочном контуре.

Шаг # 1: рисовать ваш дым

enter image description here!

Шаг # 2: нарисовать маску наложения, которая скрывает ненужную часть дыма

Слева: наложения маски.
Справа: дым с наложенной маской.

enter image description hereenter 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> 
+1

+1 также всего головы, если вы не знаете, Imgur поддерживает CORS хех его намного лучше быть в состоянии загрузить, а затем используйте изображение из imgur, а затем работайте с dataURL для демонстрационных/ответных скриптов. – Loktar

+1

@Loktar Спасибо. :-) Да, imgur отлично подходит для доставки изображений, совместимых с CORS. Я сам использую dropbox.com для доставки изображений, совместимых с CORS. Я оставил «дым» dataURL из кода опроса в демо - нет особой причины, кроме лени (!). – markE

+1

Спасибо, оверлейная маска намного быстрее, вот моя обновленная ручка. http://codepen.io/fatlinesofcode/pen/GLFqf – fatlinesofcode

Смежные вопросы