2011-12-27 39 views
6

Tôi cố gắng để thực hiện một hình ảnh động wating của các loại nêu in this question, đặc biệt là cái gì đó trông như thế này:chờ animation với HTML5 Canvas

enter image description here

Nhưng tôi không muốn sử dụng tác phẩm đồ họa, và tôi cố gắng để thực hiện nó hoàn toàn trong html5 canvas và javascript. Ngoài ra, tôi muốn có một nền đen tròn hơn là một hình vuông. Là một bước đầu tiên, tôi đã cố gắng để vẽ một khung tĩnh (không có bất kỳ chuyển động/xoay) và đã làm điều này:

<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> 

Kết quả tôi nhận được là:

enter image description here

Vấn đề là, lineCap="round" không hoạt động chính xác cho tất cả các "khe hở" và thuộc tính lineWidth=0 không hoạt động cho cạnh của vòng tròn. Tôi đang làm gì sai? Tôi đã kiểm tra nó với Chrome 16.0.912.63 và Firefox 10.0, và có kết quả tương tự.


Đối với các bước tiếp theo, tôi sẽ để cho các bộ phận của các chức năng mà tôi đã tạo ở trên tương tác với

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

nhưng trong thời gian này, tôi cần phải giải quyết vấn đề này đầu tiên.

+1

đây là một plugin jQuery để làm điều tương tự: http: // fgnass.github.com/spin.js/, nhưng bạn muốn làm điều này như một trải nghiệm học tập thì đó là điều tuyệt vời – asawilliams

+0

@asawilliams tôi thấy. Cảm ơn các liên kết. Tôi không muốn dựa vào các thư viện bên ngoài, nhưng tôi sẽ xem xét nó. Có lẽ tôi có thể trích xuất và nghiên cứu các phần liên quan của nó. Nhưng tôi vẫn muốn biết tại sao mã của tôi ở trên không hoạt động như dự định. – sawa

+0

@asawilliams Việc triển khai mà bạn đã liên kết dường như hoạt động mà không cần jQuery. Tôi sẽ xem xét nó sâu hơn. – sawa

Trả lời

3

Có một chút nhầm lẫn ở đây.

Zero không phải là giá trị chấp nhận được cho chiều rộng của đường. Các spec quy định rằng nếu bạn nói lineWidth = 0 rằng nó sẽ là một no-op.

Ngoài ra, bạn không sử dụng lineWidth ở đó vì bạn không vuốt ve. fill() không tính đến chiều rộng của dòng.

Đối với vấn đề khác, tất cả những gì bạn phải làm là gọi beginPath! Xem ở đây:

http://jsfiddle.net/JfcDL/

Chỉ cần thêm beginPath cuộc gọi và bạn sẽ có được điều này với mã của bạn:

enter image description here

gì bạn đã làm sai được vẽ toàn bộ đường dẫn cho đến nay với tất cả các mới stroke(). Bạn cần phải gọi beginPath để mở một số mới để stroke chỉ áp dụng cho phần cuối cùng và không phải tất cả các bộ phận được tạo cho đến thời điểm này.

1

Nhờ sự giúp đỡ của nhiều người dân ở đây, cuối cùng tôi đã đưa ra với mã này, mà làm việc đầy đủ các phong trào:

<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>