2014-05-23 117 views
3

我想在canvas上創建水滴下降效果。我使用array.to創建了一些樣本滴動畫動畫它我的意思是改變它們的位置我介紹setTimeout function.it工作的單個水滴。因爲我的畫布上有多次下降,它不再工作了..drops仍然保持靜止。setTimeout函數可以用來動畫所有單獨的下拉?在HTML畫布上的雨滴動畫

這裏是搗鼓個體下降jsfiddle

動畫效果single drop animation

<html> 
<head> 
</head> 
<body> 
<script> 
function makeit(){ 
var canvas=document.getElementById("mycanvas"); 
var ctx=canvas.getContext('2d'); 
canvas.width=600; 
canvas.height=600; 
canvas.style.border="1px solid black"; 

var drop=function (x,y){ 
ctx.save(); 

ctx.fillStyle="orange"; 
ctx.fillRect(0,0,canvas.width,canvas.height); 
ctx.fill(); 

ctx.fillStyle="red"; 
ctx.moveTo(x-5,y); 
ctx.lineTo(x,y-7); 
ctx.lineTo(x+5,y); 
ctx.arc(x,y,5,0,Math.PI); 

ctx.closePath(); 

ctx.fill(); 
ctx.restore(); 
y=y+3; 
if(y==canvas.height){ 
y=0; 
} 

var m=setTimeout('drop('+x+','+y+')',20); 

} 

var xpos=[10,20,30,40,50,60,70,70,76]; 
var ypos=[30,20,60,80,76,90,30,40,79]; 
for(i=0;i<xpos.length;i++){ 
drop(xpos[i],ypos[i]); 

} 

} 
window.onload=makeit; 
</script> 
<canvas id="mycanvas" ></canvas> 



</body> 
</html> 

回答

2

這裏是我會怎麼做你想要什麼:

function makeit() { 
    // These variables can be used in the drawing functions 
    var canvas = document.getElementById("mycanvas"); 
    var ctx = canvas.getContext('2d'); 
    var drops = []; 

    // Init canvas & drops 
    init(); 

    // Make the 3rd drop falls 
    var fall = setInterval(function() { 
     updateDrop(3); 
    }, 200); 

    // Make the 7th drop falls 
    var fall2 = setInterval(function() { 
     updateDrop(7); 
    }, 400); 

    // Stop the 3rd drop at anytime with this code : 
    // clearInterval(fall); 


    // Functions 
    function init() { 
     canvas.width = 600; 
     canvas.height = 600; 
     canvas.style.border = "1px solid black"; 
     // Draw background 
     drawBackground(); 
     // Draw drops 
     var xpos = [10, 20, 30, 40, 50, 60, 70, 70, 76]; 
     var ypos = [30, 20, 60, 80, 76, 90, 30, 40, 79]; 
     for (i = 0; i < xpos.length; i++) { 
      drops.push(drawDrop(xpos[i], ypos[i])); 
     } 
    } 

    function drawBackground() { 
     ctx.fillStyle = "orange"; 
     ctx.fillRect(0, 0, canvas.width, canvas.height); 
     ctx.fill(); 
    } 

    function drawDrop(x, y) { 
     ctx.beginPath(); 
     ctx.fillStyle = "red"; 
     ctx.moveTo(x - 5, y); 
     ctx.lineTo(x, y - 7); 
     ctx.lineTo(x + 5, y); 
     ctx.arc(x, y, 5, 0, Math.PI); 
     ctx.closePath(); 
     ctx.fill(); 

     return { 
      'x': x, 
       'y': y 
     }; 
    } 

    function updateDrop(dropNumber) { 
     var dropNumber = dropNumber - 1; //Because 0 is first 
     // Update position   
     if (drops[dropNumber].y >= canvas.height) { 
      drops[dropNumber].y = 0; 
     } else { 
      drops[dropNumber].y += 3; 
     } 
     //Draw background 
     drawBackground(); 
     //Draw drops 
     for (i = 0; i < drops.length; i++) { 
      drawDrop(drops[i].x, drops[i].y); 
     } 
    } 

} 
window.onload = makeit; 

然後,如果你想停止第三滴下跌,你可以執行這條線:

clearInterval(fall); 

只要看看的jsfiddle:http://jsfiddle.net/Oliboy50/QHRaS/5/

畫線之前,請不要忘記ctx.beginPath(),否則你將無法清除它們。

+2

這是正確的,但你應該解釋爲什麼這會有所幫助。除了這是一個不好的做法,傳遞一個字符串到'setTimeout'將會在全局上下文中運行代碼。 'drop'在全局上下文中不存在,因此無法運行。 –

+1

它應該是這樣的http://jsfiddle.net/humptydumpty45/TumeY/其中個別滴可以單獨確定。 –

+0

@ James Montagne全球環境的含義是什麼?如果你解釋 –

2

下面是使用window.requestAnimationFrame動畫你滴另一種選擇:

  • 定義落僞類,它知道它的x,y位置和它下降

  • 添加刪除的速度方法重繪畫布上的下拉列表並增加其Y值以使其下降。使用window.requestAnimationFrame創建一個動畫循環(1)通過用橙色背景填充畫布來清除畫布,(2)使每一滴落下並(3)在畫布上重新繪製每一滴。

註釋的代碼和演示:http://jsfiddle.net/m1erickson/m8UPC/

<!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"); 

    // a flag to let you stop the animation 
    var ok2animate=true; 


    // a Drop pseudo-class 
    // Properties: current x,y & the speed at which this drop falls 
    function Drop(){ 
     this.x=Math.random()*(canvas.width-20); 
     this.y=-Math.random()*20; 
     this.fallRate=1; 
    } 
    // draw this drop on the canvas 
    Drop.prototype.draw=function(){ 
     ctx.beginPath(); 
     ctx.moveTo(this.x-5,this.y); 
     ctx.lineTo(this.x,this.y-7); 
     ctx.lineTo(this.x+5,this.y); 
     ctx.arc(this.x,this.y,5,0,Math.PI); 
     ctx.closePath(); 
     ctx.fill(); 
     return(this);  
    } 
    // make this drop "fall" 
    Drop.prototype.fall=function(){ 
     this.y+=this.fallRate; 
     return(this); 
    } 

    // an animation loop to make some test drops fall 
    function animate(){ 

     // request another animation frame 
     if(ok2animate){ 
      requestAnimationFrame(animate); 
     } 

     // fill the canvas with the orange background 
     ctx.fillStyle="orange"; 
     ctx.fillRect(0,0,canvas.width,canvas.height) 

     // make all drops fall and then redraw them 
     ctx.fillStyle="red"; 
     for(var i=0;i<drops.length;i++){ 
      drops[i].fall().draw(); 
     } 

    } 

    // let the user stop the animation 
    $("#stop").click(function(){ 
     ok2animate=false; 
    }); 



    // an array of objects each representing 1 drop 
    var drops=[]; 

    // add some test drops 
    for(var i=0;i<10;i++){ 
     drops.push(new Drop());  
    } 

    // start the animation 
    requestAnimationFrame(animate); 


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

請注意,requestAnimationFrame尚未完全兼容:http://caniuse.com/requestanimationframe與畫布兼容性的比較:http://caniuse.com/canvas – Oliboy50

+1

如果您擔心兼容性問題,那麼會有一個非常好的墊片當requestAnimationFrame不可用時,返回setTimeout:http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/乾杯! – markE

+0

從我認爲你已經使用jQuery的語法。我還沒有開始學習jQuery的yet.thanks無論如何:) –