2014-03-26 99 views
0

我怎么可以优化该程序代码来渲染,而不当画布重新drawen优化帆布动画(正弦曲线)

var canvas = document.getElementById("sinewave"); 
var points = {}; 
var counter = 0; 
var intensity = 0; 

function f(x, intensity) { 
    return intensity * Math.sin(0.25 * x) + 100; 
} 

if (canvas.getContext) { 
    var ctx = canvas.getContext("2d"); 
    ctx.strokeStyle = '#fff'; 
    ctx.lineWidth = 2; 
    var x = 0, 
     y = f(0,0); 
    var timeout = setInterval(function() { 
     if(counter < 400) { 
      ctx.beginPath(); 
      ctx.moveTo(x, y); 
      x += 1; 
      y = f(x, intensity); 
      points[x] = y; 
      ctx.lineTo(x, y); 
      ctx.stroke(); 
      if (x > 1000) { 
       clearInterval(timeout); 
      } 
     } else { 
      ctx.clearRect(0, 0, 400, 200); 
      ctx.beginPath(); 
      points[x] = y; 
      x += 1; 
      y = f(x, intensity); 
      for(var i = 0; i < 400; i++) { 
       ctx.lineTo(i, points[i + counter - 400]); 
      } 
      ctx.stroke(); 
     } 
     counter++; 

    }, 5); 
} 

回答

0

的几点思考出现这种情况有点模糊的正弦波:

  1. 由于x == 0 &强度== 0,前400个曲线形成一条直线(?)。

  2. 您的setInterval时间太短(5毫秒)。屏幕只刷新约17毫秒,因此您正积累浏览器无意尝试填写的间隔调用。 (你正在堵塞!)。

  3. 使用新的(ish)requestAnimationFrame而不是setInterval,因为requestAnimationFrame更好地与显示硬件集成在一起。

这里的例子重构的代码和演示:http://jsfiddle.net/m1erickson/MZ7Ap/

<!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: black; } 
    canvas{border:1px solid red;} 
</style> 
<script> 
$(function(){ 

    var canvas=document.getElementById("canvas"); 
    var ctx=canvas.getContext("2d"); 
    ctx.strokeStyle = '#fff'; 
    ctx.lineWidth = 2; 

    var points = {}; 
    var counter = 0; 
    var intensity = 2; 
    var x = 0; 
    var y = fz(0,0); 

    animate(); 

    function fz(x, intensity) { 
     return intensity * Math.sin(0.25 * x) + 100; 
    } 

    function animate(time){ 

     requestAnimationFrame(animate); 

     draw(counter); 

     counter++; 

    } 

    function draw(counter){ 
     if(counter < 400) { 
      ctx.beginPath(); 
      ctx.moveTo(x, y); 
      x += 1; 
      y = fz(x, intensity); 
      points[x] = y; 
      ctx.lineTo(x, y); 
      ctx.stroke(); 
      if (x > 1000) { 
       clearInterval(timeout); 
      } 
     } else { 
      ctx.clearRect(0, 0, 400, 200); 
      ctx.beginPath(); 
      points[x] = y; 
      x += 1; 
      y = fz(x, intensity); 
      for(var i = 0; i < 400; i++) { 
       ctx.lineTo(i, points[i + counter - 400]); 
      } 
      ctx.stroke(); 
     } 
    } 

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

太神奇了! 谢谢,也会友好的建议如何通过方程来限制函数的高度? 因此,即使在100000强度下也不会高于帆布高度 – Leg0

+0

不客气!最大/最小正弦值是1.00和-1.00。因此,从你的f()开始反向工作:minIntensity = 100,maxIntensity = canvas.height-100。如果你想使用这些最小/最大值以外的值,你将不得不缩放强度值(这也会使你的波形倾斜,因为你的x值每次计算前进1个像素。 – markE