Why is this 'for' loop not working?
I have a Javascript object called TweenManager which contains an array of Tween objects. The TweenManager should call the step() method on each tween in the 'tweens' array and all the tweens should run at the same time.
However, what's actually happening is that the TweenManager only runs one tween at a time, and doesn't start the next one until the previous tween is complete.
Here's the code for the tween manager
UPDATE: It might make more sense to look at it here
//Manage all tweens
function TweenManager(){
this.tweens = new Array();
this.timer;
this.start = function(){
this.timer = setInterval(this.run, 1, this);
}
// Loop through all tweens and call the step method
this.run = function(myself){
console.log(myself.tweens.length);
// stop the interval if the tween array is empty
if(myself.tweens.length == 0){
clearInterval(myself.timer)
}
// loop through all tweens and call the step() method
// !! Here's there the problem appears to be
for(i = 0; i < myself.tweens.length; i++){
thisTween = myself.tweens[i]
console.log(thisTween.element.attr('id'));
thisTween.step() // if I remove this, the line above logs the id's as expected
// clean up if the tween is complete
if(thisTween.t == thisTween.d){
myself.tweens.splice(i, 1);
}
}
}
this.addTween = function(b,c,d,element,suffix, decimal){
this.tweens.push( new Tween(b开发者_开发问答,c,d,element,suffix, decimal) )
}
}
The problem appears to be in the for loop. I have a hunch that this might have something to do with passing in this
in the setInterval
, although it's just a hunch, I don't understand what the problem could be. I get confused with variable scopes and whatnot.
Here's the Tween Object (Yup, ripped off form Robert Penner)
// Tween a number, add a suffix and insert it into an element
function Tween(b, c, d, element, suffix, decimal){
this.t = 0;
this.c = c;
this.d = d;
this.b = b;
this.element = element;
this.suffix = suffix;
this.step = function(){
if(this.t != this.d){
this.t += 1
var flip = 1
if (this.c < 0) {
flip *= -1
this.c *= -1
}
i = flip * (-Math.exp(-Math.log(this.c)/this.d * (this.t-this.d)) + this.c + 1) + this.b
if(!decimal){
this.element.html(Math.round(i) + this.suffix)
}else{
output = (Math.round(i * 10) / 10 + this.suffix)
formattedOutput = ( output - Math.round(output) == 0 ) ? output + ".0" : output;
this.element.html(formattedOutput)
}
}
}
}
And here's the implementation
tweenManager = new TweenManager();
tweenManager.addTween(0,80,300, $("#el1"), "°", false)
tweenManager.addTween(0,60,400, $("#el2"), "’", false)
tweenManager.addTween(0,12.5,300, $("#el3"), "", true)
tweenManager.start()
As always, any help, hinting or nudging the the right direction is greatly appreciated.
I think the problem is that you are trying to use setInterval as some sort of fork() function which means that you should moving it from where it is to put it on the step itself so that you call:
setInterval(thisTween.step, 1, ...
That is how you can make your tweens run in fake 'parallel'.
However what I really think you want is the new HTML5 Web Workers feature; I think that is for exactly this kind of activity.
精彩评论