3

私はこれをずっと見つめていました、そしていくつかの助けが必要です。IEでは機能するがChromeでは機能しない次の簡略化されたフィドルの例があります(エラーはなく、Chromeでキャンバスがクリアされた後に画像が再描画されることはありません):

http://jsfiddle.net/JrLh7/3/

var myApp = {};
// redraw function that will be called during init and then will loop.
myApp.redrawFunction = function() {
    window.requestAnimationFrame(myApp.redrawFunction);
    // clear canvas (not needed in this simplified example, but I need it in my real app)
    myApp.drawingContext.clearRect(0, 0, myApp.canvas.width, myApp.canvas.height);
    // draw an image.
    var myImage = new Image();
    myImage.onload = function() {
        myApp.drawingContext.drawImage(myImage, 0, 0);
    };
    myImage.src= "http://www.w3.org/html/logo/img/mark-word-icon.png";
};
// initialize
$(function () {
    // setup the animation frame objects.
    window.requestAnimationFrame = window.requestAnimationFrame
        || window.mozRequestAnimationFrame
        || window.webkitRequestAnimationFrame
        || window.msRequestAnimationFrame;
    window.cancelAnimationFrame = window.CancelAnimationFrame
        || window.CancelRequestAnimationFrame
        || window.mozCancelAnimationFrame
        || window.mozCancelRequestAnimationFrame
        || window.msCancelAnimationFrame
        || window.msCancelRequestAnimationFrame
        || window.webkitCancelAnimationFrame
        || window.webkitCancelRequestAnimationFrame;
    // get canvas references.
    myApp.canvas = $("canvas")[0];
    myApp.drawingContext = myApp.canvas.getContext("2d");
    $(myApp.canvas).css("background-color", "#999999");
    // update canvas size to fill screen.
    myApp.canvas.width = $(window).width();
    myApp.canvas.height = $(window).height();
    $(window).resize(function (){
        myApp.canvas.width = $(window).width();
        myApp.canvas.height = $(window).height();
    });
    // start redraw loop
    myApp.redrawFunction();
});

このフィドルをIE10で開くと、機能します(ロゴが表示されます)。これをChromeで開くと、空白のキャンバスが表示され、キャンバスをクリアした後、drawImage呼び出しが機能しなかったことを示しています。私が欠けているアイデアはありますか?

4

1 に答える 1

3

問題は、キャンバスをクリアしてから、画像が読み込まれるのを待っていることです。画像が読み込まれると、アニメーションが再度実行され、キャンバスがクリアされて、新しい画像が読み込まれるのを待ちます。したがって、を呼び出すとすぐにキャンバスの状態が常に表示されます。これは、clearRectを呼び出すとdrawImage、の結果を確認する前にアニメーションルーチンが再び開始され、の結果が表示さdrawImage()れるためですclearRect()

解決策は、画像をペイントする準備ができるまでキャンバスをクリアしないことです。http://jsfiddle.net/JrLh7/6/

var myApp = {};
// redraw function that will be called during init and then will loop.
myApp.redrawFunction = function() {
    // Don't clear the canvas here, it will be empty until the onload handler is called 
    var myImage = new Image();
    myImage.onload = function() {
        // Clear canvas and immediately paint the image
        myApp.drawingContext.clearRect(0, 0, myApp.canvas.width, myApp.canvas.height);
        myApp.drawingContext.drawImage(myImage, 0, 0);
        // Then you should ask for another frame after you've finished painting the canvas
       window.requestAnimationFrame(myApp.redrawFunction);
    };
    myImage.src= "http://www.w3.org/html/logo/img/mark-word-icon.png";
};

ノート

非同期のアニメーションルーチンを使用することはあまり意味がありません。その場合、少なくとも、キャンバスのペイントが完了するまで、新しいアニメーションフレームをリクエストしないでください。

于 2013-03-12T00:23:42.833 に答える