我正在使用 Javascript 和画布编写非常基本的代码(刚刚开始学习)。我尝试做一些随机绘图(矩形有 50% 的机会出现在某些位置)。一旦发生这种情况,我希望浏览器等待一秒钟,清除屏幕并立即再次绘制它(视觉上应该立即将一张图替换为另一张图)。
当我这样做时,画布似乎不想更新,它只在主循环结束时更新一次,您可以在下面找到代码:
<script> let canvas = document.querySelector("canvas"); let context = canvas.getContext("2d"); function wait(ms) { var start = new Date().getTime(); var end = start; while (end < start + ms) { end = new Date().getTime(); } } for (let k = 0; k < 3; k++) { context.clearRect(0, 0, canvas.width, canvas.height); console.log("First checkpoint"); for (let i = 0; i < 5; i++) { for (j = 0; j < 5; j++) { let width_custom = 60; let height_custom = 60; let gap = 20; let x = 100 + (width_custom + gap) * i; let y = 100 + (height_custom + gap) * j; context.beginPath(); context.rect(x, y, width_custom, height_custom); context.stroke(); if (Math.random() > 0.5) { context.beginPath(); context.rect(x + 8, y + 8, width_custom - 16, height_custom - 16); context.stroke(); } } } wait(1000); console.log("Second checkpoint"); }
有没有办法在循环期间强制画布刷新?
您的wait函数违背了 javascript 的异步特性。您正在以某种方式阻止程序,因此事情不会被刷新。你应该使用setTimeout这种东西(setInterval甚至更好requestAnimationFrame)。
wait
setTimeout
setInterval
requestAnimationFrame
我准备了如何异步循环和等待的非常令人困惑但有趣的示例。我相信其他人会建议使用Promise。或await和async。都很好。
Promise
await
async
let canvas = document.querySelector("canvas"); let context = canvas.getContext("2d"); my_loop(3) function my_loop(k) { if (k > 0) { one_round(1000, function() { my_loop(k - 1) }) } } function one_round(delay, foo_then) { context.clearRect(0, 0, canvas.width, canvas.height); for (let i = 0; i < 5; i++) { for (j = 0; j < 5; j++) { let width_custom = 60; let height_custom = 60; let gap = 20; let x = 100 + (width_custom + gap) * i; let y = 100 + (height_custom + gap) * j; context.beginPath(); context.rect(x, y, width_custom, height_custom); context.stroke(); if (Math.random() > 0.5) { context.beginPath(); context.rect(x + 8, y + 8, width_custom - 16, height_custom - 16); context.stroke(); } } } setTimeout(foo_then, delay); } <canvas></canvas>