yeeen
yeeen

Reputation: 4945

using setTimeout in javascript to do simple animation

I am using setTimeout to create animation in Javascript, but it does not seem to work. Only the 1st move of the animation is executed, no subsequent moves.

I tried on two different laptops using Firefox, one doesn't throw any error, but the one says self.animateCallback is not a function. I also see other errors like saying my timeout function is useless or "compile-and-go" when I tried diff ways. Doesn't seem to get it working. I tried "function(self){self.animateCallback()}" and "self.animateCallback" (with and without quotes).

The code is below, it is part of a prototype method.

    increment : function(incr, target, tick) {
    var self = this;

    self.animateCallback = function()
    {
        var done = Math.abs(self.currValue - target) < Math.abs(incr);
        if(!self.animateCallback || done) {

            if(done) {
                self.updateAngle(self.currValue/self.maxValue);
                self.stopAnimation(); //just setting animateCallback to null
            }
        }
        else
        {
            self.updateAngle((self.currValue+incr)/self.maxValue);
            setTimeout(self.animateCallback, tick);
        }

    }
    self.animateCallback.call();
},

Upvotes: 2

Views: 906

Answers (3)

Na7coldwater
Na7coldwater

Reputation: 1414

I think the error is that some other code is changing the value of self.animateCallback to something else. The first time through, setTimeout has the correct value for self.animateCallback, but after the first time, the value of self.animateCallback has changed to something else, which isn't a function, but is still a non-falsy value so that !self.animateCallback returns false.

You can try changing the if statement to this:

if((typeof self.animateCallback !== "function") || done) {

    if(done) {
        self.updateAngle(self.currValue/self.maxValue);
        self.stopAnimation(); //just setting animateCallback to null
    }
}

Upvotes: 0

Tobias Cohen
Tobias Cohen

Reputation: 20000

I've got a feeling the problem has something to do with the line setTimeout(self.animateCallback..., which is accessing the function through a closure and a property. It should be neater, at least, to do it like this:

increment : function(incr, target, tick) {
    var self = this;

    var animateCallback = function()
    {
        var done = Math.abs(self.currValue - target) < Math.abs(incr);
        if(done) {
            self.updateAngle(self.currValue/self.maxValue);
            self.animateTimeout = null;
        }
        else
        {
            self.updateAngle((self.currValue+incr)/self.maxValue);
            self.animateTimeout = setTimeout(animateCallback, tick);
        }

    }
    animateCallback();
},
stopAnimation: function() {
    if (this.animateTimeout) {
        clearTimeout(this.animateTimeout);
        this.animateTimeout = null;
    }
},

Upvotes: 3

Mushegh A.
Mushegh A.

Reputation: 1431

try to pass an anonymous function to setTimeout, like

setTimeout(function(){ self.animateCallback(); }, tick);

hope it'll help.

Upvotes: -1

Related Questions