Für Lernzwecke, ich schreibe etwas Code, um ein Bild nach dem Zufallsprinzip Pixel für Pixel in einer Leinwand zu zeichnen. Hier ist die link für die folgenden Codes.Canvas: Zeichnen Bild Pixel für Pixel und requestAnimationFrame Timing
Ich möchte die Animation innerhalb von 1 Sek. Beendet werden. Wie Sie jedoch von der Konsole aus sehen können, dauert es etwa 7 Sekunden. Ich versuche ein kleineres Bild, die Zahl schließt auf 1 Sekunde.
In diesem Fall ist das Timing von requestAnimationFrame nicht zuverlässig. Ich möchte die Ursache wissen. Ist es, weil putImageData
nach einem der Pixel in seinem Daten-Array sucht zu viel Zeit braucht? Oder ist es weil etwas anderes? Ich denke, wenn RequestAnimationFrame Timing ist nicht zuverlässig ist entscheidend für gute Animationen.
Darüber hinaus, gibt es einen besseren Weg zu tun, was ich tun möchte?
// At first, I get the image's data, then I build an array whose
// length is equal to the number of pixels of the image, each element
// of the array represents one of the image's pixel. Then I shuffle
// this array and pop a certain number of elements for
// `ctx.putImageData` to draw the corresponding pixel per frame.
var ctx = c.getContext("2d"),
img = new Image();
img.onload = init;
img.src = "download.png"; //placehold.it's 300x200 image
function formArr(w,h){ //Build image pixel outputting sequence array based on image's width and height
var arr = [];
for (i=0;i<w*h;i++){
arr.push(i);
}
return arr;
}
function Point(i,w){ //locate pixel's X and Y base on image width
this.x = i%w;
this.y = Math.floor(i/w);
}
function shuffleRect(arr){ //shuffle the output sequence array
....
}
function init(){
var w = ctx.canvas.width = img.width*2;
var h = ctx.canvas.height = img.height*2;
//form Image Data
ctx.drawImage(img,0,0,w,h);
var imageData = ctx.getImageData(0,0,w,h);
ctx.clearRect(0,0,w,h);
//build output sequence
var sequence = formArr(w,h);
shuffleRect(sequence);
var sec = 1; //animation duration
var t1 = Date.now();
function animate(){
var pointsPerFrame = Math.floor(w*h/sec/60)+1;
for (i=0;i<Math.min(pointsPerFrame,sequence.length);i++){
var j = sequence.pop();
ctx.putImageData(imageData,0,0,new Point(j,w).x,new Point(j,w).y,1,1); //draw points for next frame
}
if(sequence.length){requestAnimationFrame(animate)}else{
var t2 = Date.now();
console.log(t2-t1);
}
}
animate();
}
Können Sie erstellen stacksnippets oder jsfiddle zu demonstrieren? – guest271314