これは非常に単純なスライドショーのコードで、4 秒間に 4 つの画像を 1 秒間に 1 画像ずつ表示する必要があります。代わりに、4 秒の遅延が発生し、すべての画像が重ねて描画されます。私は何を間違っていますか?
<html>
<head>
<script langugage="javascript">
// 4 images
var image0 = new Image();
image0.src = "img/image0.png";
var image1 = new Image();
image1.src = "img/image1.png";
var image0 = new Image();
image2.src = "img/image2.png";
var image3 = new Image();
image3.src = "img/image3.png";
// array of 4 images
images = new Array(image0, image1, image2, image3);
// this is the main function
function draw(){
myCanvas = document.getElementById('myCanvas');
ctx = myCanvas.getContext('2d');
counter=0; // this is the index of the next image to be shown
for (var i=0;i<images.length;i++){
setTimeout(draw_next_image, 1000);
ctx.clearRect(0, 0, myCanvas.width, myCanvas.height)
}
}
// this is the function called after each timeout to draw next image
function draw_next_image(){
ctx.drawImage(images[counter], 0, 0);
counter++;
if (counter>images.length) {counter=0;}
}
window.onload = draw;
</script>
</head>
<body>
<canvas id="myCanvas" width="800" height="600"></canvas>
</body>
</html>
更新: 答えは:
上記のコードでは、誤ってgetTimeout
function が同期的であると想定していました。つまり、呼び出し時にプログラムの実行が停止し、1000 ミリ秒待機してから を呼び出してから実行すると予想していましdraw_next_image
たctx.clearRect
。
実際には、Javascript はそのようには機能しません。実際getTimeout
には非同期です。つまりgetTimeout
、 Timeout を設定してほぼ瞬時に戻り、コードの実行が続行されるため、ctx.clearRect
はすぐに、実際にはの前に呼び出されdraw_next_image
ます。そのため、Timeout が切れて が呼び出さdraw_next_image
れるまでに、コードの実行が任意のコード行に到達する可能性があります。私の場合clearRect
、タイムアウトの期限が切れるずっと前に、4 つすべてがほぼ同時に呼び出されます。それから 1000 ミリ秒後、4 つのタイムアウトすべてが次々とすぐに期限切れになり、4 つの画像すべてがほぼ同時に描画されclearRects
ます。これはかなり前に実行されました。