我在这里有一个工作的画布动画: http://codepen.io/lexbi/pen/KzZKze
虽然我正在尝试将其转换为使用setTimeout
转换为使用requestAnimationFrame
。
作为我想要完成的内容的简要概述,我将画布元素上的图像拆分为多个块,然后我想单独为这些块设置动画以重新创建“完整”图像。 (使用setTimeout
的codepen非常有效。)
似乎可以通过动画获得部分内容,而且,某些块的位置会更新,但是,实际上并没有看到动画发生。
我相信我为activeBlocks
对象创建的循环很早就完成了。这意味着它在动画结束之前到达此条件中的else
(它不应该):
if((blocks[blocks.length-1].x != blocks[blocks.length-1].toX)){
updateAndRender = true;
}else{
updateAndRender = false;
window.cancelAnimationFrame(requestId);
}
有人可以在这里建议我做错了吗?
看到粘贴代码集没有意义(因为它崩溃了),这是我转换它的最佳尝试:
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
img = new Image(),
rowPieces = 10,
columnPieces = 10,
totalPieces = rowPieces*columnPieces,
workingPiece = 0,
blocks = [],
activeBlocks = [],
minWait = 10,
lastTime = +new Date(),
updateAndRender = true,
requestId;
img.src = "http://lastresistance.com/wp-content/uploads/2014/09/ATT-fat-cat.jpg";
// // set height & width
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
img.onload = function(){
function theLoop(){
var loopCount = 0;
for(var colCount=0;colCount<columnPieces;colCount++){
for(var rowCount=0;rowCount<rowPieces;rowCount++){
blocks.push(
new Block(
(canvas.width/rowPieces), // w
(img.width/rowPieces), // sWidth
(canvas.height/columnPieces), // h
(img.height/columnPieces), // sHeight
((img.width/rowPieces)*rowCount), //sx
((canvas.width/rowPieces)*rowCount), //x
(canvas.width/rowPieces), // fromX
((canvas.width/rowPieces)*rowCount), // toX
((img.height/columnPieces)*colCount), // sy
((canvas.height/columnPieces)*colCount), // y
(canvas.height/columnPieces), // fromY
((canvas.height/columnPieces)*colCount), // toY
loopCount // Loop count, starting on 0
)
);
loopCount++;
}
}
}
theLoop();
function Block(w, sWidth, h, sHeight, sx, x, fromX, toX, sy, y, fromY, toY, loopCount){
this.w = w;
this.sWidth = sWidth;
this.h = h;
this.sHeight = sHeight;
this.sx = sx;
this.x = -x;
this.fromX = fromX;
this.toX = toX;
this.sy = sy;
this.y = -y;
this.fromY = fromY;
this.toY = toY;
this.i = loopCount;
}
Block.prototype.update = function(){
// so if the increment is NOT enlarged by "1" the position could final up being offset
if(this.y < this.toY){
this.y+=40;
}
//reset the y pos
if(this.y > this.toY){
this.y = this.toY;
}
// so if the increment is NOT enlarged by "1" the position could final up being offset
if(this.x < this.toX){
this.x+=40;
}
// reset the x pos
if(this.x > this.toX){
this.x = this.toX;
}
};
Block.prototype.render = function(){
context.drawImage(img, this.sx, this.sy, this.sWidth, this.sHeight, this.x, this.y, this.w, this.h);
};
//draw the screen
function animate() {
// This stops active blocks from growing larger than intended
if(activeBlocks.length <= blocks.length){
activeBlocks.push(blocks[workingPiece]);
if(workingPiece <= totalPieces){
workingPiece = workingPiece+1;
}else{
workingPiece = 0;
}
} // endif
context.clearRect(0,0,canvas.width, canvas.height);
for(var ei = 0; ei < activeBlocks.length; ++ei){
if((blocks[blocks.length-1].x != blocks[blocks.length-1].toX)){
updateAndRender = true;
}else{
updateAndRender = false;
window.cancelAnimationFrame(requestId);
}
if(updateAndRender == true){
// For some reason this still fires for 70 loops, not sure why, though this undefined IF at least stops errors in the console
if("undefined" !== typeof activeBlocks[ei]){
activeBlocks[ei].update();
activeBlocks[ei].render();
requestId = window.requestAnimationFrame(animate);
}
} // endif
} // for
};
requestId = window.requestAnimationFrame(animate);
}