Search code examples
javascriptanimationsnap.svgsvg-animate

Animation in callback not firing, SnapSVG


I'm trying to create a bounce animation that repeats forever. Problem I'm having is that snap doesn't seem to execute animations I put in callbacks. There seem to be some issues on github describing this problem with Snap back at 0.1.1, but they've since been closed. Has anyone else see anything like this?

Current code, which will run the first part of the animation and then stop:

var slight_bounce = function(body_part, transform1, transform2){
    body_part.stop().animate({ 
      transform: transform1
    }, 1000,
    function() { 
      body_part.animate({ 
        transform: transform2
      });
      slight_bounce(body_part, transform1, transform2); // Repeat this animation so it appears infinite.
    }
    );
  }

  slight_bounce(hat, bounce, bounce_back);

Solution

  • There's a few mistakes in your code...

    Firstly in your parameters, you missed the easing method (like mina.bounce), so that needs to be included.

    The 2nd inner function doesn't have the callback as part of the animation parameters, so wouldn't get called at the right time either, so all of that is a bit bracketed wrong.

    jsfiddle

    var s = Snap(400, 620);
    
    var slight_bounce = function(body_part, transform1, transform2 ){
        body_part.stop().animate({ 
           transform: transform1
        }, 1000, mina.bounce,
    
          function() { 
              body_part.animate({ 
                  transform: transform2
              },1000,mina.bounce,
                function() {
                     slight_bounce(body_part, transform1, transform2);
                })
    
           }
       );
    };
    
    var hat = s.rect(100,100,100,100);
    var bounce = 't0,100';
    var bounce_back = 't0,0';
    
    slight_bounce(hat, bounce, bounce_back);
    

    As this is quite a common question, I'm just going to give a slight alternative rewrite, as I find the callback function method when written like that a bit clunky to follow.

    This does exactly the same, but I find it a little more structured.

    jsfiddle

    function startBounce( body_part, transform1, transform2 ) {
        body_part.stop().animate({ 
                    transform: transform1
        }, 1000, mina.bounce, endBounce.bind(null, body_part, transform1, transform2));
    }
    
    function endBounce( body_part, transform1, transform2 ) {   
        body_part.animate({ 
                    transform: transform2
        }, 1000, mina.bounce, startBounce.bind(null, body_part, transform1, transform2));
    }        
    
    var hat = s.rect(100,100,100,100);
    var bounce = 't0,100';
    var bounce_back = 't0,0';
    
    startBounce(hat, bounce, bounce_back);