我的画布充当地图。用户可以单击画布,并在地图(画布)上绘制标记。坐标存储在一个数组中。
当用户点击播放按钮时,画布将第一个数组标记绘制在其位置,一秒后绘制第二个标记,另一个稍后绘制第三个标记,依此类推。
我怎么能实现这个目标?我已经尝试使用for循环并调用一个setTimeout函数,该函数在循环中传递i的值,但循环变为快速,我无法理解它。
function timer() {
for (i=0; i<array.length; i++){
play(i);
}
}
function play(i) {
setTimeout(function() {
ctx.clearRect(0,0, c.width, c.height);
ctx.beginPath();
ctx.moveTo(array[i].x, array[i].y);
ctx.lineTo(array[i].x,array[i].y);
cursor(array[i].x,array[i].y);
}, 1000);
}
答案 0 :(得分:2)
使用requestAnimationFrame并将差异存储在刻度值中,以便您只在每秒过后处理更改。
如果您不能使用requestAnimationFrame,则使用setTimeout(play,1000)在1000秒后再次调用播放功能。当然,只需在结束时递增索引并在索引超出界限之前停止。
请勿使用setInterval ,因为这可能会超出之前间隔的操作。它不会等待完成上一段处理才能完成。
E.g。
<script>
var lastTick = 0;
var elapsed = 0;
var index = 0;
var array = [4, 5, 6, 7, 8, 9, 10];
function animationLoop(tick) {
var diff = tick - lastTick;
elapsed += diff;
if (elapsed > 1000) {
ctx.clearRect(0, 0, c.width, c.height);
ctx.beginPath();
ctx.moveTo(array[index].x, array[index].y);
ctx.lineTo(array[index].x, array[index].y);
cursor(array[index].x, array[index].y);
elapsed -= 1000;
index++;
}
if (index < array.length) {
lastTick = tick;
window.requestAnimationFrame(animationLoop);
}
}
window.requestAnimationFrame(animationLoop);
</script>
答案 1 :(得分:1)
setTimeout可能不是最佳解决方案。你最好每隔x毫秒使用setInterval来调用一个单独的函数。你可以粘贴有问题的for循环吗?
修改:
首先,我看到你正在使用画布,所以我猜是googlemaps api?即便如此,您应该使用requestAnimationFrame进行任何动画密集型工作。此外,由于您的播放功能正在完成,定时器功能实际上是无关紧要的。
我自己在requestAnimationFrame上有点生疏,但我认为这段代码可能会有所帮助。我认为setInterval部分会使requestAnimationFrame无意义,你需要将实际时间移动到play函数中。我只是不记得怎么做了。
var i = 0;
/*
* change the 1000 to make the animation faster or slower.
* 1000ms == 1s so 10000 = 10 seconds
*/
setInterval(timer(), 1000);
function timer() {
window.requestAnimationFrame(play);
}
function play() {
if (i <= array.length) {
ctx.clearRect(0, 0, c.width, c.height);
ctx.beginPath();
ctx.moveTo(array[i].x, array[i].y);
ctx.lineTo(array[i].x, array[i].y);
cursor(array[i].x, array[i].y);
i++;
window.requestAnimationFrame(play);
}
}
答案 2 :(得分:1)
您希望设置间隔并清除计数器(在此范围内递增)达到某个点时的间隔。例如: -
var t;
var counter = 0;
var array = ['your', 'data'];
function timer() {
t = setInterval(play, 1000);
}
function play() {
if (counter !== array.length) {
ctx.clearRect(0,0, c.width, c.height);
ctx.beginPath();
ctx.moveTo(array[counter].x, array[counter].y);
ctx.lineTo(array[counter].x,array[counter].y);
cursor(array[counter].x,array[counter].y);
counter++;
} else {
clearInterval(t);
t = null;
}
}
timer(); // begin calling play() every 1 second for array.length (2 in example) loops