suazi
suazi

Reputation: 454

Snap SVG: Suspending an event listener during the course of an animation

I'm trying to suspend the event listener of this animation I made such that the click event won't trigger another animation until the previous one is completed. I tried using booleans (as in the example) but I don't understand why it won't work.

Note: Can't use jquery.

Example: Jsfiddle

var speed = 250,
suspend = true;

[].slice.call( document.querySelectorAll( '.arrow_button' ) ).forEach( function( el ) {

    var s = Snap( el.querySelector( 'svg' ) ),
        path = s.select( 'path' ),
        returnPath = path.attr('d'),
        route = el.getAttribute( 'data-path-route' ),
        callback = function () {
            path.animate( { 'path' : returnPath }, speed, mina.easeout );
            suspend = true;
        };

    el.addEventListener( 'click', function() {
        if( suspend ) {
            suspend = false;
            path.animate( { 'path' : route }, speed, mina.easein, callback );
        };
    } );

} );

Upvotes: 0

Views: 282

Answers (1)

John
John

Reputation: 11429

The problem is that you set suspend to true right away in your callback-function. You could set a timeout inside the callback-function, and set suspend to true after around 250ms (the length/speed of the animation). Updated fiddle

var speed = 250,
suspend = true;

[].slice.call( document.querySelectorAll( '.arrow_button' ) ).forEach( function( el ) {

    var s = Snap( el.querySelector( 'svg' ) ),
        path = s.select( 'path' ),
        returnPath = path.attr('d'),
        route = el.getAttribute( 'data-path-route' ),
        callback = function () {
            path.animate( { 'path' : returnPath }, speed, mina.easeout );
            setTimeout(function(){
                 suspend = true;      
            },speed)
        };

    el.addEventListener( 'click', function() {
        if( suspend ) {
            suspend = false;
            path.animate( { 'path' : route }, speed, mina.easein, callback );
        };
    } );

} );

EDIT: after having a closer look at snapsvg.io's documentation, I figured a better way of handling the situation you are facing. Instead of using a timeout, you can add a callback function in your easeout-animation like this updated plunkr:

var speed = 250,
    suspend = true;
[].slice.call( document.querySelectorAll( '.arrow_button' ) ).forEach( function( el ) {
    var s = Snap( el.querySelector( 'svg' ) ),
        path = s.select( 'path' ),
        returnPath = path.attr('d'),
        route = el.getAttribute( 'data-path-route' ),
        callback = function () {
            path.animate( { 'path' : returnPath }, speed, mina.easeout, function(){
               suspend=true;
            });
        };
    el.addEventListener( 'click', function() {
  console.log("test",suspend);
        if( suspend ) {
            suspend = false;
            path.animate( { 'path' : route }, speed, mina.easein, callback );
        };
    } );
} );

This callback function will be called when the animation ends, making it unnecessary to set your own timeout. From the snapsvg.io docs

Upvotes: 1

Related Questions