2011-12-27 128 views
6

我想實現提到in this question的那種瓦亭動畫,尤其是一些看起來像這樣:與HTML5畫布等待動畫

enter image description here

但我不希望使用的圖形文件,和我試圖純粹在html5 canvas和javascript中實現它。另外,我想要一個圓形的黑色背景,而不是一個正方形的背景。作爲第一步,我試着畫靜態幀(沒有任何動靜/旋轉)和這樣做:

<html> 
<head><script> 
window.onload = function(){ 
    var c=document.getElementById("waiting").getContext("2d"); 
    c.lineCap="round"; 
    c.fillStyle="#353535"; 
    c.translate(100,100); 
    function slit(p){ 
     shade = 256*p; 
     th = 2*Math.PI*p; 
     cos = Math.cos(th); 
     sin = Math.sin(th); 
     c.strokeStyle = '#'+((shade<<16)+(shade<<8)+shade).toString(16); 
     c.moveTo(55*cos, 55*sin); 
     c.lineTo(84*cos, 84*sin); 
     c.stroke(); 
     c.closePath(); 
    } 
    c.lineWidth=0; 
    c.arc(0,0,100,0,Math.PI*2); 
    c.fill(); 
    c.lineWidth=7; 
    for(var i = 0;i<1;i+=0.05){slit(i);} 
} 
</script></head> 
<body><canvas id="waiting" width=200 height=200></canvas></body> 
</html> 

結果我得到的是:

enter image description here

的問題是, lineCap="round"對於所有「狹縫」都不能正常工作,並且lineWidth=0屬性對於圓的邊緣不起作用。我究竟做錯了什麼?我使用Chrome 16.0.912.63和Firefox 10.0進行了檢查,結果相似。


對於下一步,我打算讓的,我在上面創建的功能部件與

window.animationFrames = (function(callback){ 
    return window.requestAnimationFrame || 
    window.webkitRequestAnimationFrame || 
    window.mozRequestAnimationFrame || 
    window.oRequestAnimationFrame || 
    window.msRequestAnimationFrame || 
    function(callback){window.setTimeout(callback, 1000/60);}; 
})(); 

但暫時互動,我需要首先解決這個問題。

+1

這裏是一個jQuery插件做同樣的事情:HTTP:// fgnass.github.com/spin.js/,但你想做這個學習體驗,那很酷 – asawilliams 2011-12-27 22:10:22

+0

@asawilliams我明白了。感謝您的鏈接。我不想依賴外部庫,但我會看看它。也許我可以提取和研究它的相關部分。但是,我仍然想知道爲什麼我的代碼無法按預期工作。 – sawa 2011-12-27 22:13:51

+0

@asawilliams您鏈接的實現似乎沒有jQuery。我會更深入地研究它。 – sawa 2011-12-27 22:17:35

回答

3

這裏有點混亂。

零不是線寬的可接受值。該規範規定,如果你說lineWidth = 0它將是一個無操作。

此外,您沒有使用lineWidth,因爲您沒有撫摸。 fill()不考慮線寬。

至於另一個問題,你所要做的就是致電beginPath!在這裏看到:

http://jsfiddle.net/JfcDL/

只需添加beginPath電話,你會用你的代碼得到這個:

enter image description here

你在做什麼錯誤與每幅圖的整個路徑爲止新的stroke()。您需要致電beginPath打開一個新的,以便stroke僅適用於最後一部分,而不是迄今爲止所做的所有部件。

1

多虧了幾個人在這裏的幫助下,我終於想出了這個代碼,它與運動完全工作:

<html> 
<head><script> 
var r1 = 400; 
var r2 = 340; 
var r3 = 220; 
var slitWidth = 40; 
var speed = 0.0004; 
var attenuation = 1.7; 

function rgbToHex(r, g, b){ 
    return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); 
} 

window.nextFrame = (function(callback){ 
    return window.requestAnimationFrame || 
    window.webkitRequestAnimationFrame || 
    window.mozRequestAnimationFrame || 
    window.oRequestAnimationFrame || 
    window.msRequestAnimationFrame || 
    function(callback){window.setTimeout(callback, 1000/60);}; 
})(); 

window.onload = function(){ 
    var waiting=document.getElementById('waiting').getContext('2d'); 
    function slit(d,p){ 
     shade = Math.round(Math.pow(1-(d+p)%1, attenuation)*255) 
     th = Math.PI*2*(p); 
     cos = Math.cos(th); 
     sin = Math.sin(th); 
     waiting.strokeStyle = rgbToHex(shade, shade, shade); 
     waiting.beginPath(); 
     waiting.moveTo(r2*cos, r2*sin); 
     waiting.lineTo(r3*cos, r3*sin); 
     waiting.stroke(); 
     waiting.closePath(); 
    } 
    function frame(){ 
     waiting.arc(0,0,r1,0,Math.PI*2); 
     waiting.fill(); 
     var time = new Date().getTime()* speed; 
     for(var p = 1;p>0;p-=0.05){slit(time,p);} 
     nextFrame(function(){frame();}); 
    } 
    waiting.lineCap='round'; 
    waiting.lineWidth=slitWidth; 
    waiting.fillStyle='#353535'; 
    waiting.translate(r1, r1); 
    frame(); 
} 
</script></head> 
<body><canvas id='waiting' width=800 height=800></canvas></body> 
</html>