2012-12-17 24 views
10

Tôi cần vẽ nhiều điểm trên canvas HTML5 và quá trình này mất khá nhiều thời gian. Mã của tôi trông giống như sau:Tăng tốc độ vẽ nhiều điểm trên phần tử canvas HTML5

var points = getPoints() // Array of {x,y,color} 
var ctx = canvas.getContext("2d"); 

for (var i = 0; i < points.length; i++) { 
    ctx.fillStyle = points[i].color 
    ctx.beginPath() 
    ctx.arc(points[i].x, points[i].y, radius, 0, Math.PI * 2, true) 
    ctx.fill() } 

Tôi tự hỏi điều chỉnh hiệu suất nào tôi có thể làm để tăng tốc độ này. Tôi chỉ có 5 màu khác nhau. Ví dụ: tôi có được hưởng lợi từ biểu mẫu sắp xếp danh sách điểm khi đang di chuyển để thay đổi ctx.fillStyle chỉ 5 lần thay vì một lần cho mỗi điểm không?

+0

Tôi nghĩ rằng đây là một dòng khá chậm: 'ctx.arc (điểm [i] .x, điểm [i] .y, radius, 0, Math.PI * 2, true) 'Thử vẽ các hình chữ nhật đơn giản và xem nó có tăng tốc không. (IMHO, nó nên ...) – ppeterka

+1

Tôi đã thử nó và có, nó tăng tốc độ. Tôi không thấy làm thế nào mà sẽ giúp tuy nhiên. – Nicolas

+1

Tôi nghĩ rằng nếu bạn thiết lập một fiddle nó sẽ được dễ dàng hơn cho mọi người để tinh chỉnh nó, đây là một số sửa đổi tôi có thể nghĩ đến để làm cho nó nhanh hơn một chút (có thể) -> [** FIDDLE **] (http: // jsfiddle .net/4WTaQ /) ... – adeneo

Trả lời

13

Ví dụ: tôi có mang lại lợi ích cho biểu mẫu sắp xếp danh sách điểm để chuyển đổi ctx.fillStyle chỉ 5 lần thay vì một lần cho mỗi điểm không?

Theo kinh nghiệm của tôi, có - thay đổi .fillStyle thường là khá tốn kém.

Tôi đã có mã vẽ một số lượng lớn hình chữ nhật trong canvas và thời gian để vẽ hình chữ nhật chỉ với hai màu thay đổi thường xuyên tốt hơn nhiều so với nhiều màu thay đổi thường xuyên.

Nhưng dù sao, vì bạn chỉ có năm màu sắc khác nhau:

  1. Tạo một canvas off-màn hình vào đó bạn có thể vẽ lăm vòng tròn
  2. Sử dụng .drawImage() để blit vòng tròn màu ngay vào canvas điểm đến của bạn mà không cần phải để tính toán lại tọa độ hồ quang
  3. Gán points[i] cho biến cục bộ trong vòng lặp để tránh lặp lại cuộc hội thảo.

Mở máy tính xách tay của tôi mã này được vẽ 3000 vòng tròn trên vải 400x400 trong 7 mili giây:

var colours = ['red', 'green', 'blue', 'yellow', 'magenta']; 
var n = colours.length; 
var r = 10; 
var d = r * 2; 

var off = document.createElement('canvas'); 
off.width = n * d; 
off.height = d; 
var ctx = off.getContext('2d'); 

for (var i = 0; i < n; ++i) { 
    ctx.fillStyle = colours[i]; 
    ctx.beginPath(); 
    ctx.arc(i * d + r, r, r, 0, 2 * Math.PI); 
    ctx.closePath(); 
    ctx.fill(); 
} 

var canvas = document.getElementById('canvas'); 
var ctx2 = canvas.getContext('2d'); 
var t0 = Date.now(); 
for (var i = 0; i < 3000; ++i) { 
    var c = Math.floor(n * Math.random()); 
    var x = Math.floor(canvas.width * Math.random()); 
    var y = Math.floor(canvas.height * Math.random()); 
    ctx2.drawImage(off, c * d, d, d, x - r, y - r, d, d); 
} 
var t1 = Date.now(); 
alert((t1 - t0) + "ms"); 

Xem http://jsfiddle.net/alnitak/Dpgts/

+0

Chà, tôi làm nó trong 3ms. Ấn tượng. Cảm ơn nhiều! – Nicolas

+0

@Stewie BTW, nếu vòng kết nối của bạn không trùng lặp, bạn có thể tăng tốc độ này lên rất nhiều bằng cách sử dụng '.putImageData'. – Alnitak

+0

Họ không. Bạn có nghĩa là thay vì .drawImage()? – Nicolas

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