1

I've got several looping animations (up/down) which are defined by the following functions.

Looping interval

function Cycler(f) {
    if (!(this instanceof Cycler)) {
        // Force new
        return new Cycler(arguments);
    }
    // Unbox args
    if (f instanceof Function) {
        this.fns = Array.prototype.slice.call(arguments);
    } else if (f && f.length) {
        this.fns = Array.prototype.slice.call(f);
    } else {
        throw new Error('Invalid arguments supplied to Cycler constructor.');
    }
    this.pos = 0;
}

Cycler.prototype.start = function (interval) {
    var that = this;
    interval = interval || 1000;
    this.intervalId = setInterval(function () {
        that.fns[that.pos++]();
        that.pos %= that.fns.length;
    }, interval);
}

Function 1 (upwards)

function unpeekTile() {

    var peekAnimation = WinJS.UI.Animation.createPeekAnimation([tile1, tile2]);
    tile1.style.top = "0px";
    tile2.style.top = "0px";

    peekAnimation.execute();
}

Function 2 (downwards)

function peekTile() {

    var peekAnimation = WinJS.UI.Animation.createPeekAnimation([tile1, tile2]);
    tile1.style.top = "-120px";
    tile2.style.top = "-120px";

    peekAnimation.execute();

}

Start

        function c() { Cycler(peekTile, unpeekTile).start(); }
        setTimeout(c, 0);

        function c2() { Cycler(peekTile2, unpeekTile2).start(); }
        setTimeout(c2, 500);

        function c3() { Cycler(peekTile3, unpeekTile3).start(); }
        setTimeout(c3, 2000);

The animations now start at 1000 (interval time) + 0/500/2000 (setTimeout), but I'd like them to start in 0, 500 and 2000 millis. Can anybody help?

Betsy
  • 33
  • 1
  • 4

2 Answers2

0

If I've understood right you're effectively saying you want the interval callback not only to be bound to the interval, but also executed once between the time-out ending and the interval being set.

This means modifying Cycler.prototype.start:

Cycler.prototype.start = function (interval) {
    var that = this, int_callback;  //<-- added var
    interval = interval || 1000;
    this.intervalId = setInterval(int_callback = function () {
        that.fns[that.pos++]();
        that.pos %= that.fns.length;
    }, interval);
    int_callback(); //<-- added line - call the func immediately, once
}
Mitya
  • 33,629
  • 9
  • 60
  • 107
  • I *think* that will put `int_callback` into the Global namespace. Probably want to throw a `var` in there. – Dancrumb Jul 07 '12 at 23:10
  • Thanks a lot - that worked out for me! Just a little change: The int_callback var have to be declared separately: var that = this; var int_callback; – Betsy Jul 08 '12 at 07:04
  • That will do exactly the same as my current code does - it's a local function. Try it - inaccessible outside `Cycle.prototype.start`. – Mitya Jul 08 '12 at 09:34
  • @Betsy: Actually, `int_callback` does not have to be declared in a separate statement. However, there's debate as to whether it should. You can read some opinions on [SO here](http://stackoverflow.com/questions/694102/declaring-multiple-variables-in-javascript) – Dancrumb Jul 08 '12 at 14:28
0

One solution would be:

Cycler.prototype.start = function (interval,executeImmediately) {
    var that = this;
    interval = interval || 1000;
    var driverFunction = function () {
        that.fns[that.pos++]();
        that.pos %= that.fns.length;
    }
    this.intervalId = setInterval(driverFunction , interval);
    if(executeImmediately) {
        driverFunction();
    }
}

This keeps your function defined once and you simply feed it to setInterval and also call it directly.

Dancrumb
  • 26,597
  • 10
  • 74
  • 130