2

HTML5 キャンバスで単純な JavaScript アニメーションを実行しようとしています。現在、私のキャンバスは階層化されているため、マウス イベントを受け取ったときに背景レイヤーは変化しませんが、アバターを含む最上層が移動します。requestAnimationFrame を使用して画面をクリアしないと、素敵な小さなプレーヤーが複数のフレームで画面上を移動し、キャラクターの長い尻尾が表示されます。ただし、各アニメーション フレームの後に clearRect を実行しようとすると、キャラクターが表示されず、何が原因かわかりません。

コードの基礎としてこれらのリンクを使用しています:
http://www.html5canvastutorials.com/advanced/html5-canvas-start-and-stop-an-animation/ http://paulirish.com/2011/requestanimationframe- for-smart-animation/ 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 や他のライブラリを使用しませんでした。

ありがとう。

4

1 に答える 1

2

キャンバスをクリアすると、その上のすべてが消去されるため、描画後に呼び出すと、説明している空白のキャンバスが得られます。代わりに、次のフレームまで待ってから、描画後ではなく描画前にキャンバスをクリアして、描画された画像がしばらく表示されるようにする必要があります。問題を解決するには、クリア コマンドを上に移動して、各フレームの描画コマンドの直前に実行するようにします。

于 2012-07-01T09:47:55.577 に答える