在requestAnimationFrame中使用clearRect不会显示动画

时间:2012-06-29 15:52:34

标签: javascript image html5 animation

我想在HTML5画布上做一个简单的javascript动画。现在我的画布是分层的,这样当我收到一个鼠标事件时,背景图层不会改变,但是带有头像的顶层会移动。如果我使用requestAnimationFrame并且不清除屏幕,我会看到我的漂亮的小玩家在屏幕上移动多个框架中的长尾巴。但是,如果我尝试在每个动画帧之后执行clearRect,那么我的角色永远不会出现,我不确定是什么导致了这个。

我使用这些链接作为我的代码的基础:  
http://www.html5canvastutorials.com/advanced/html5-canvas-start-and-stop-an-animation/  http://paulirish.com/2011/requestanimationframe-for-smart-animating/  http://www.nczonline.net/blog/2011/05/03/better-javascript-animations-with-requestanimationframe/

很多例子都是动画形状的绘制,而我正在使用图像,不确定这是否重要,我是否应该只使用画布转换函数而不是clearRect,但不认为这应该已经有所作为。此外,为了便于阅读,我删除了一堆代码,因此括号可能已关闭,但代码正常运行,我只是为了可读性而这样做,因此您可以在一个方向上看到动画。我的代码看起来像:

// what is this function for? See here - http://stackoverflow.com/questions/10237471/please-explain-this-requestanimationframe-idiom
window.requestAnimFrame = function(callback){
// add in this parentheses - http://stackoverflow.com/questions/5605588/how-to-use-    requestanimationframe
   return ( window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback){
        window.setTimeout(callback, 1000 / 60);
    }
);
}();

function stopAnimatingPlayer(currentAvatarAnimating, destinationCellX, destinationCellY) {
    gIsAnimating = false;
    //Did this final draw because I wasn't sure if the avatar would end on the exact pixel position, so this should snap him back into place
    drawAvatar(currentAvatarAnimating, destinationCellX, destinationCellY, false,0,0);
}   

function movePlayer(lastTime, playerPixelX, playerPixelY, destinationCellX, destinationCellY) {
if (gIsAnimating) {
    // the canvas is already globally held as gAvatarCanvasElement & gAvatarDrawingContext;

    // update
    var date = new Date();
    var time = date.getTime();
    var timeDiff = time - lastTime;
    var linearSpeed = 100;
    // pixels / second
    var linearDistEachFrame = linearSpeed * timeDiff / 1000;
    var horizontal = false;
    var newX, newY;

    // gets the new coordinate of the player
    if (gTowerCurrentPlayer == 1) {
        //fill in later - just trying to get one horizontal animation working
        } else if (destinationCellY == gPlayer1Cell.y) { // we're moving horizontally
    var currentX = playerPixelX;
            var diffX = destinationCellX - gPlayer1Cell.x;
            horizontal = true;
            if (diffX > 0) { // player is moving right - just get one direction going for now
                if (currentX < getPixelFromRow(destinationCellX)) {
                    newX = currentX + linearDistEachFrame;
                } else {
                    stopAnimatingPlayer(gTowerCurrentPlayer, destinationCellX, destinationCellY); 
                }
            } //fill in rest later - get one direction working

    lastTime = time;

    // clear - this is where the problem is
    gAvatarDrawingContext.clearRect(playerPixelX, playerPixelY, kPieceWidth, kPieceHeight);
    //gAvatarDrawingContext.clearRect(0,0, gAvatarCanvasElement.width, gAvatarCanvasElement.height);

    if (horizontal) {
        drawAvatar(gTowerCurrentPlayer, 0, 0, true, newX, playerPixelY);
        // request new frame
        requestAnimFrame(function(){ 
            movePlayer(lastTime, newX, playerPixelY, destinationCellX, destinationCellY);
        });
    } 
}
}

function animatePlayer(playerPixelX, playerPixelY, destinationCellX, destinationCellY) {
    gIsAnimating = true; // global var here
    var date = new Date();
    var time = date.getTime();
    movePlayer(time, playerPixelX, playerPixelY, destinationCellX, destinationCellY); 
}

如果有人能提供任何帮助我会非常感激,我只是不知道为什么这不起作用。我不需要超级华丽的动画,这就是为什么我没有使用kineticjs或任何其他库。

感谢。

1 个答案:

答案 0 :(得分:1)

当你清除画布时,它会删除画布上的所有内容,所以如果你在绘制之后调用它,你会得到一个空白画布,这就是你所描述的。相反,您应该等到下一帧,然后在绘制之前清除画布,而不是之后,以便绘制的图像显示一段时间。要解决您的问题,只需将清除命令向上移动,以便在每个帧的绘图命令之前立即执行。