2009-08-10 5 views
0

Mit dem Canvas-Element zeichne ich eine Linie von einem Element zu einem anderen Element Ein anderes Element ist ziehbar, und beim Ziehen des Elements folgt die Linie dem ziehbaren Element.Slow Canvas Element

Mein Problem ist, dass die Wiedergabe langsam (Fx 3.5 auf einem Mac Powerbook) Ich glaube, ich habe apears gesehen viel bessere Leistung in Leinwand vor

Jeder mit Canvas Erfahrung, die einige Performance-Tipps geben?

Vielen Dank im Voraus

Die folgende Methode auf dem auf Drag-Ereignis aufgerufen wird,

// Runs when the element is dragged. 
function onDrag(key) 
{ 
    var ctx = canvas.context; 
    var fromRect = $('#box-' + key).offset(); 
    var fromHeight = $('#box-' + key).height(); 
    var fromWidth = $('#box-' + key).height(); 

    var toRect = $('#draggable').offset(); 
    var toWidth = $('#draggable').width(); 

    var startX = toRect.left + toWidth/2; 
    var startY = toRect.top + 4; 
    var endX = fromRect.left + fromWidth/2; 
    var endY = fromRect.top + fromHeight/2; 

    ctx.clearRect(0, 0, 5000, 5000); 
    ctx.beginPath(); 
    ctx.moveTo(startX, startY); 
    ctx.lineTo(endX, endY); 
    ctx.strokeStyle = "rgba(0, 0, 0,1)"; 
    ctx.stroke(); 

}

Danke für Tipps,

freundlichen Grüßen Eric

+1

Haben Sie Profiler verwendet? Wie "unbekannt (yahoo)" sagt, Ihr Engpass könnte all diese Höhe, Breite, Offset-Messungen sein. –

Antwort

2

I wäre wetten, dass die jQuery Funktionsaufrufe länger dauern han die Zeichnung. Wenn Sie mit Ihrer Anwendung Offset und Bemaßungen problemlos ohne jQuery berechnen können, können Sie dort möglicherweise zusätzliche Geschwindigkeit extrahieren.

2

Wo es möglich ist, Cache jQuery Auswahl:

var onDrag = (function(){ 

    var draggable = $('#draggable'), 
     ctx = canvas.context; // btw, don't you mean canvas.getContext('2d')? 

    return function(key) { 

     var box = $('#box-' + key), 
      fromRect = box.offset(), 
      fromHeight = box.height(), 
      fromWidth = box.height(), 
      toRect = draggable.offset(), 
      toWidth = draggable.width(), 
      startX = toRect.left + toWidth/2, 
      startY = toRect.top + 4, 
      endX = fromRect.left + fromWidth/2, 
      endY = fromRect.top + fromHeight/2; 

     ctx.clearRect(0, 0, 5000, 5000); 
     ctx.beginPath(); 
     ctx.moveTo(startX, startY); 
     ctx.lineTo(endX, endY); 
     ctx.strokeStyle = "rgba(0, 0, 0,1)"; 
     ctx.stroke(); 

    }; 

})(); 

Generell gilt: Wenn Sie eine Funktion haben, die mehrmals kurz hintereinander ausgeführt werden, stellen Sie sicher, Sie nur das, was zu tun ABSOLUT HAS Bei jedem Aufruf der Funktion FERTIG sein.

1

Falls die Elemente durch ihre IDs lokalisieren und ihre Dimensionen Lesen der Engpass ist, können Sie Ihre Funktion versuchen memoizing:

function onDrag(key) { 
    var cached = onDrag.cache[key]; 

    if (!cached) { 
     cached = { 
      fromRect = $('#box-' + key).offset(); 
      // etc. 
     }; 

     onDrag.cache[key] = cached; 
    } 

    var toRect = $('#draggable').offset(); 
    // etc. 
} 

onDrag.cache = {}; 

Diese Macht geben Ihnen einen Performance-Gewinn.

Können Sie auch versuchen, die clearRect() herauszunehmen, um zu sehen, ob es einen großen Unterschied macht? Sie können die Position des vorherigen Ziehvorgangs speichern und die vorherige Zeile einfach zurückverfolgen, um sie zu löschen, anstatt 5000 x 5000 = 25 Millionen Pixel zu malen. Nur eine Ahnung, da das Füllen von 25 Millionen Pixeln möglicherweise ein Problem darstellt, das auf der Canvas-Implementierung basiert.

0

Ich glaube wirklich, sollten Sie closePath() am Ende

0

Dies könnte sehr langsam sein, vor allem für eine so große Oberfläche. Versuchen Sie nur zu löschen, was Sie stattdessen benötigen:

ctx.clearRect (0, 0, 5000, 5000);