web-dev-qa-db-ja.com

HTML5 Canvas:描画が終了したときにイベントを取得

Canvas要素に画像を描画しています。次に、このプロセスに依存するコードを完成させます。私のコードは次のようになります:

var myContext = myCanvasElement.getContext('2d'),
    myImg = new Image();

myImg.onload = function() {
    myContext.drawImage(containerImg, 0, 0, 300, 300);
};

myImg.src = "someImage.png";

それでは、drawImageが完了したときに通知を受けたいと思います。仕様を確認しましたが、イベントも、コールバック関数を渡す可能性も見つかりませんでした。これまでのところ、タイムアウトを設定しましたが、これは明らかに持続可能ではありません。この問題をどのように解決しますか?

23
elHornair

ほとんどすべてのJavascript関数と同様に、drawImagesynchronousです。つまり、実際に想定されていることを実行した後でのみ戻ります。

とは言っても、他のほとんどのDOM呼び出しと同様に、行うことが想定されていますは、ブラウザーがイベントループに入ったときに再描画されるもののキューアップリストです。

具体的に登録してそれを通知できるイベントはありません。そのようなイベントハンドラーを呼び出すことができるようになるまでに、再描画がすでに行われているためです。

19
Alnitak

Jef Claesはそれをかなりよく説明しています 彼のウェブサイトで

スクリプトが既に解釈され実行されている間、ブラウザは画像を非同期で読み込みます。画像が完全に読み込まれていない場合、キャンバスは画像のレンダリングに失敗します。

幸いなことに、これを解決するのは難しくありません。画像からコールバックを受け取り、読み込みが完了したことを通知するまで、描画を開始するのを待つ必要があります。

<script type="text/javascript">        
window.addEventListener("load", draw, true);

function draw(){                                    
    var img = new Image();
    img.src = "http://3.bp.blogspot.com/_0sKGHtXHSes/TPt5KD-xQDI/AAAAAAAAA0s/udx3iWAzUeo/s1600/aspnethomepageplusdevtools.PNG";                
    img.onload = function(){
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');    

        context.drawImage(img, 0, 0);        
    };            
}                    
7
Elisha Mooring

画像が読み込まれたときに既にイベントがあり、1つのこと(描画)を行います。別のことをして、drawImageの後に実行したいことをすべて実行する関数を呼び出してみませんか?文字通りちょうど:

myImg.onload = function() {
    myContext.drawImage(containerImg, 0, 0, 300, 300);
    notify(); // guaranteed to be called after drawImage
};
4
Simon Sarris