2010-01-11 8 views
7

Ich möchte vertikales Scrollen des Inhalts eines HTML5-Canvas-Elements implementieren. Ich möchte den gesamten Inhalt nicht noch einmal wiedergeben. Stattdessen möchte ich den gesamten Inhalt nach unten/oben verschieben und nur den Bereich rendern, der in die Ansicht gescrollt wurde.Was ist der schnellste Weg, um eine rechteckige (Pixel) Region innerhalb eines HTML5-Canvas-Elements zu verschieben

Ich experimentierte mit den getImageData und putImageData Funktionen, aber in meinen Tests sind sie fast so langsam wie die gesamte Szene neu zu streichen.

// scroll 20px down 
var data = ctx.getImageData(0, 0, width, height-20); 
ctx.putImageData(0, 20); 

Was ist der schnellste Weg, um rechteckige Pixelregionen innerhalb eines Canvas-Elements zu kopieren?

Antwort

12

Versuchen Sie folgendes:

ctx.drawImage(ctx.canvas, 0, 0, width, height-20, 0, 20, width, height-20); 

drawImage nehmen kann entweder eine HTMLImageElement, eine HTMLCanvasElement oder eine HTMLVideoElement für das erste Argument.

7

Für absolute Geschwindigkeit, würde ich eine übergroße <canvas> innerhalb eines <div> mit overflow:hidden gesetzt verwenden dann regelmäßig DOM-Methoden verwenden, um die <canvas> innerhalb des <div> zu blättern.

Natürlich opfert dies Speicherverbrauch zugunsten der Geschwindigkeit.

+0

Gute Idee, aber leider kenne ich nicht die genaue Größe im Voraus und der Scroll-Bereich ist potenziell Tausende von Pixel Höhe, so glaube ich nicht, dass dies für mich arbeiten wird. –

+0

Ich wünschte, ich hätte von diesem Ansatz gewusst, bevor ich das Scrollen in meiner Anwendung implementierte. Ich verwende doppelte Pufferung mit einem großen verborgenen Canvas und einem kleinen Viewport Canvas. Dann kopiere ich den neuen sichtbaren Teil von der versteckten in das Ansichtsfenster. Es funktioniert, könnte aber wahrscheinlich schneller sein. Und wenn das Bild mehrere tausend Pixel hoch sein könnte, würde meine Lösung nicht funktionieren. –

+0

Wenn jedoch nicht erwartet wird, dass Sie nach unten scrollen können, können Sie den letzten Bildschirm auf einer neuen "extra großen" Leinwand neu streichen, wenn Sie den unteren Rand erreichen. Und wenn Sie eine Ausfallzeit (wie eine Pause im Nachrichtenstrom) haben, können Sie neu streichen und abschneiden, ohne dass es jemand bemerkt. Die erstgenannte Technik beseitigt die Verzögerung nicht, aber sie begrenzt sie sicherlich, viel weniger zu geschehen. –