2011-11-17 30 views
7

Tôi đã thực hiện một số nghiên cứu về cách hoạt động của canvas. Nó được cho là "chế độ tức thời" có nghĩa là nó không nhớ bản vẽ của nó trông như thế nào, chỉ có bitmap duy trì mọi thứ thay đổi.Canvas có tự vẽ lại mọi lúc mọi thứ thay đổi không?

Điều này dường như gợi ý rằng canvas không tự vẽ lại khi thay đổi.
Tuy nhiên, khi tôi thử nghiệm canvas trên iPad (về cơ bản tôi vẫn vẽ các đường song song trên canvas), tốc độ khung hình giảm nhanh khi có nhiều dòng trên canvas. Các dòng được vẽ chậm hơn và theo một cách tăng vọt hơn.

Điều này có nghĩa là canvas thực sự phải vẽ toàn bộ điều về thay đổi? Hoặc có lý do khác cho sự thay đổi này về hiệu suất?

Trả lời

11

Vải HTML ghi nhớ trạng thái cuối cùng của pixel sau mỗi lần thực hiện đột quỵ/điền. Nó không bao giờ tự vẽ lại. (Trình duyệt web có thể cần phải ghi lại các phần của hình ảnh cuối cùng lên màn hình, ví dụ: nếu một đối tượng HTML khác được di chuyển qua khung hình và sau đó đi lại, nhưng điều này không giống như việc cấp lại các lệnh vẽ.

Ngữ cảnh luôn nhớ trạng thái hiện tại của nó, bao gồm mọi đường dẫn bạn đã tích luỹ. Có thể bạn vô tình xóa đường dẫn giữa 'làm mới' và trên khung đầu tiên bạn vẽ một đường, trên khung thứ hai hai dòng, trên khung thứ ba ba dòng, và vv (Bạn có đang gọi ctx.closePath()ctx.beginPath()? Bạn có đang xóa canvas giữa các bản vẽ không?)

Đây là an example cho biết vải không tự vẽ lại. Ngay cả ở hàng chục nghìn dòng tôi thấy cùng tốc độ khung hình với hàng trăm dòng (được giới hạn ở tốc độ 200 khung hình/giây trên Chrome, ~ 240fps trên Firefox 8.0, khi vẽ 10 dòng trên mỗi khung hình).

var lastFrame = new Date, avgFrameMS=5, lines=0; 
function drawLine(){ 
    ctx.beginPath(); 
    ctx.moveTo(Math.random()*w,Math.random()*h); 
    ctx.lineTo(Math.random()*w,Math.random()*h); 
    ctx.closePath(); 
    ctx.stroke(); 
    var now = new Date; 
    var frameTime = now - lastFrame; 
    avgFrameMS += (frameTime-avgFrameMS)/20; 
    lastFrame = now; 
    setTimeout(drawLine,1); 
    lines++; 
} 
drawLine(); 

// Show the stats infrequently 
setInterval(function(){ 
    fps.innerHTML = (1000/avgFrameMS).toFixed(1); 
    l.innerHTML = lines; 
},1000); 

Seen trong hành động: http://phrogz.net/tmp/canvas_refresh_rate.html

Đối với phản ánh thêm về những gì mã của bạn được thực sự làm so với những gì bạn nghi ngờ nó đang làm, chia sẻ trường hợp thử nghiệm của bạn với chúng tôi.

+1

Cảm ơn ví dụ tuyệt vời !!!! Tôi thấy vấn đề đơn giản là tôi không gọi context.closePath() !! – Codier

+0

Câu trả lời hay. Tôi muốn bạn có một số điểm thưởng cho việc này! –

Các vấn đề liên quan