2011-12-27 2 views
6

Я пытаюсь реализовать Wating анимации, упомянутой 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

+0

@asawilliams, я вижу. Спасибо за ссылку. Я не хотел полагаться на внешние библиотеки, но я посмотрю на это. Возможно, я смогу извлечь и изучить соответствующие части. Но все же, я хочу знать, почему мой код выше не работает должным образом. – sawa

+0

@asawilliams Реализация, с которой вы связаны, работает без jQuery. Я посмотрю на нее глубже. – sawa

ответ

3

Здесь немного путаницы.

Zero не является допустимым значением для ширины линии. Спецификация диктует, что если вы скажете lineWidth = 0, что это будет no-op.

Кроме того, вы не используете 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> 
Смежные вопросы