admin管理员组文章数量:1264888
window.onload = ->
boxOrig1 = 10
boxOrig2 = 30
canvasW = 400
canvasH = 300
ctx = $("#canvas")[0].getContext('2d');
draw = (origin,dimension) ->
ctx.clearRect(0, 0, canvasW, canvasH)
ctx.fillStyle = 'rgb(200,0,0)'
ctx.fillRect(origin + boxOrig1, boxOrig1, dimension, dimension)
ctx.fillStyle = 'rgba(0, 0, 200, 0.5)'
ctx.fillRect(origin + boxOrig2, boxOrig2, dimension, dimension)
for m in [10..100] by 10
t = setTimeout (-> draw(m, 150)), 1000
t.clearTimeout
# draw(m,150)
# alert m
As an exercise, the code above is meant to draw a little design on a canvas, pause for a second, then redraw it again 10 pixels to the right.
I can see that the mechanics work fine when I interrupt the loop with an alert (as in those last two mented lines), but I'm not getting the expected behavior with the setTimeout function. The design just appears at the rightmost position after the timeout, skipping the incremental steps in between.
I've tried many different ways of doing this from other examples, but it's just melting my brain. Any suggestions?
window.onload = ->
boxOrig1 = 10
boxOrig2 = 30
canvasW = 400
canvasH = 300
ctx = $("#canvas")[0].getContext('2d');
draw = (origin,dimension) ->
ctx.clearRect(0, 0, canvasW, canvasH)
ctx.fillStyle = 'rgb(200,0,0)'
ctx.fillRect(origin + boxOrig1, boxOrig1, dimension, dimension)
ctx.fillStyle = 'rgba(0, 0, 200, 0.5)'
ctx.fillRect(origin + boxOrig2, boxOrig2, dimension, dimension)
for m in [10..100] by 10
t = setTimeout (-> draw(m, 150)), 1000
t.clearTimeout
# draw(m,150)
# alert m
As an exercise, the code above is meant to draw a little design on a canvas, pause for a second, then redraw it again 10 pixels to the right.
I can see that the mechanics work fine when I interrupt the loop with an alert (as in those last two mented lines), but I'm not getting the expected behavior with the setTimeout function. The design just appears at the rightmost position after the timeout, skipping the incremental steps in between.
I've tried many different ways of doing this from other examples, but it's just melting my brain. Any suggestions?
Share Improve this question asked Nov 29, 2011 at 22:42 user105090user105090 3571 gold badge5 silver badges9 bronze badges2 Answers
Reset to default 11Geoff has outlined one approach (using setInterval
and clearing it from the callback), so I'll outline the other: Using setTimeout
from the callback. Something like
m = 10
do drawCallback = ->
draw m, 150
m += 10
setTimeout drawCallback, 1000 unless m > 100
Note that there is a subtle timing difference between the two approaches that you should be aware of: setInterval func, 1000
will run the function once every 1000ms; the chained setTimeout
will put a 1000ms delay between each function call. So if draw
took 100ms, say, the chained setTimeout
would be equivalent to setInterval func, 1100
. It probably doesn't matter, but it's worth being aware of.
Bonus approach: You don't have to abandon your loop; you could just set all the timeouts from it at once:
for m in [10..100] by 10
do (m) ->
setTimeout (-> draw(m, 150)), 100 * m
The do (m)
is necessary so that the closure passed to setTimeout
sees each value of m
, not just its final value in the loop. See my article A CoffeeScript Intervention for more info on this.
Finally: I know this all seems very confusing at first, but timing in JS is actually very simple because the language is single-threaded. That means that events you schedule with setTimeout
or setInterval
or any other async function will never occur during a loop, even if the loop is infinite. They only occur after all of your code has finished executing. I talk about this in a little more detail in my book on CoffeeScript.
This might be expressed more intuitively as a setInterval:
window.onload = ->
boxOrig1 = 10
boxOrig2 = 30
canvasW = 400
canvasH = 300
ctx = document.getElementById("canvas").getContext('2d')
draw = (origin,dimension) ->
ctx.clearRect(0, 0, canvasW, canvasH)
ctx.fillStyle = 'rgb(200,0,0)'
ctx.fillRect(origin + boxOrig1, boxOrig1, dimension, dimension)
ctx.fillStyle = 'rgba(0, 0, 200, 0.5)'
ctx.fillRect(origin + boxOrig2, boxOrig2, dimension, dimension)
count = 10
timer = setInterval (->
if count == 100
clearInterval(timer)
draw(count, 150); count+=10
), 1000
本文标签: javascriptHow do I use setTimout in Coffeescript within a loopStack Overflow
版权声明:本文标题:javascript - How do I use setTimout in Coffeescript within a loop - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1740944125a2312038.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论