0

I have a very simple animation with svg.js that I would like to run on a loop as long as the page is open. I haven't been able to find any thing while looking through either the github, documentation, or stack overflow pages. A working version of the animation without looping can be found here. The important js is:

//create the svg element and the array of circles
var draw = SVG('canvas').size(300, 50);
var circ = [];

for (var i = 0; i < 5; i++) {
    //draw the circles
    circ[i] = draw.circle(12.5).attr({
        fill: '#fff'
    }).cx(i * 37.5 + 12.5).cy(20);

    //first fade the circles out, then fade them back in with a callback
    circ[i].animate(1000, '<>', 1000 + 100 * i).attr({
        opacity: 0
    }).after(function () {
        this.animate(1000, '<>', 250).attr({
            opacity: 1
        });
    });
}

I know this would be pretty easy to do without a js library, but I'm looking at this as just a first step into using svg.js. Later I plan on using it for much more robust animations. Thanks for any advice or pointers.

Community
  • 1
  • 1
kjones603
  • 33
  • 2
  • 4
  • whats your error? have you checkout d3.js? – agconti Nov 14 '13 at 04:15
  • There's no error, I'm easily able to make it fade in and fade out once. What I'm looking for is how to repeat it indefinitely. And I've used d3 for a few charts in the past, but I was looking to use svg.js specifically to broaden my horizons ad because it's such a small library to include. If it can't be done with svg.js then I'll certainly be looking into d3 some more. – kjones603 Nov 14 '13 at 04:35
  • got ya, why can you use your or my example, and use While(x) instead of your for loop and never set x to false? – agconti Nov 14 '13 at 04:51
  • Or simply change your for loop to an infinite loop? – agconti Nov 14 '13 at 04:57
  • I tried that, but it just freezes the page, – kjones603 Nov 14 '13 at 05:30

3 Answers3

2

From version 0.38 of svg.js on the loop() method is built in:

https://github.com/wout/svg.js#loop

I'm also planning on creating a reverse() method in one of the upcoming releases. Right now the loop() method restarts the animation from the beginning.

wout
  • 2,477
  • 2
  • 21
  • 32
  • 1
    Great stuff. Thanks for the work on this project and taking the time to update this small question. Glad to see the loop function added in there. P.S. Good luck on v1.0 – kjones603 Feb 01 '14 at 23:42
  • The documentation currently stats that loop(int, bool) takes in a second bool param that indicates whether the loop should reverse. It's not working for me :) – Lzh Jun 22 '15 at 06:34
0

I'm not sure if its possible just with svg.js attributes, as its not clear from svg.js if its creating typical svg animation elements or not. Whatever, it could be done with a loop though. So...

function anim( obj,i ) {
        obj.animate(1000, '<>', 1000 + 100 * i).attr({
            opacity: 0
        }).after(function () {
            obj.animate(1000, '<>', 250).attr({
                opacity: 1
            });
        });

};

function startAnims() {
   for( var i = 0; i< 5; i++ ) {
        anim( circ[i],i );
    }
    setTimeout( startAnims, 5000 ); // Or possibly setInterval may be better
};

jsfiddle here http://jsfiddle.net/8bMBZ/7/ As its not clear if its adding elements each time behind the scenes (you may want to store the animation and just start that if so). There are other libs that tie in differently to SVG if you need like Raphael, snap, d3, Pablo.js that you could try as alternatives if you need to look at animation from a slightly different way.

Ian
  • 13,724
  • 4
  • 52
  • 75
  • In the fiddle you used setInterval to keep it going, I assume that's what you meant to do instead of setTimeout on here. Either way, this looks like exactly the answer to my situation. I'm relatively novice at js so I didn't even know those two functions existed. Thanks. Marking as the answer. – kjones603 Nov 17 '13 at 05:54
  • Hi, yes I think I started with setTimeout, but then thought setInterval may be more appropriate. I'll add a comment to the answer so people are aware. Thanks for spotting it. – Ian Nov 17 '13 at 10:33
0

I used after to call a function that start the animation recursively. This way I was able to achieve both infinite looping and reversing. Of course you can count to avoid infinite looping but the general idea is as follows:

 //custom animation function whose context is the element animated
function myCustomAnimation(pos, morph, from, to) {
    var currentVal = morph(from, to); //do morphing and your custom math
    this.attr({ 'some prop': currentVal });
}

var animationStart = 0; //just extra values for my custom animation function
var animationEnd = 1; //animation values start at 0 and ends at 1

line.attr({ 'stroke-width': 2, stroke: 'red' });
animateMeRepeatedly.apply(line);

function animateMeRepeatedly()
{
    this.animate(1500)
        .during(function (pos, morph) {
            myCustomAnimation.apply(this, [pos, morph, animationStart, animationEnd]);
        })
        .after(function () {
            this.animate(1500).during(function (pos, morph) {
                myCustomAnimation.apply(this, [pos, morph, animationEnd, animationStart]);
            }).after(animateMeRepeatedly);
        });
}
Lzh
  • 3,585
  • 1
  • 22
  • 36