Jump to content
Search Community

callback

Lacika1981 test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hi,

 

I am a having a bit problem to set a callback function.

Here is what I am doing.

 

function animateSkeleton() {
        rotateSkeleton = tl.staggerTo(images, .1, { opacity: 1, onComplete: function () { this.target.style.opacity = 0; this.target.classList.remove('played'); }, onStart: function() {this.target.className += 'played'} }, .035);
        TweenMax.to('.image-sequence', 1, {left: '15%'});
        rotateSkeleton.tweenTo(1);
        setTimeout(function() {
            removeElemWithNoFullOpacity();
        }, 1000)
    }

 

It works fine once but when I call this 'animateSkeleton' function again then the setTimeout function is not working it animates backward (from 3 seconds to 1 second).

I tried to add callback function to the onComplete method but it fires after each completed animation.

I tried to add the onCompleteAll method but it did not work either.

 

What I really need is a method that fires when the whole animation has just finished and my custom cb function can be invoked.

Edited by Lacika1981
Link to comment
Share on other sites

Hey Lacika,

 

Could you give us a bit more context? I mean, Looking at this one function is a tad hard as I don't know where that 'tl' is coming from, why you are using a timeline and then, a TweenMax and why you have a timeline already set as a 'tl' but also set as 'rotateSkeleton'. Also, GSAP doesn't really know when/if a setTimeout is fired or not...

 

Could you show us a reduced case of what you are trying to achieve? The bare minimum is enough, because from what I am seeing here, you're mixing up too many things and that's what's causing your issue.

  • Like 2
Link to comment
Share on other sites

Yeah, I'm confused for the same reasons as Dipscom.

 

The one thing that jumps out as a red flag is this:

 

 rotateSkeleton = tl.staggerTo(images, .1, { opacity: 1, ...})

 

This means every time your function is called you are putting a NEW staggerTo() on the end of the tl timeline. Your tl timeline is just getting longer and longer and longer each time

  • Like 1
Link to comment
Share on other sites

Thanks Dipscom,

 

I try to give more details

 

var tl = new TimelineMax();
var rotateSkeleton;

function animateSkeleton() {
        images.removeClass('played');
        rotateSkeleton = tl.staggerTo(images, .1, { opacity: 1, onUpdate: function() {this.target.className = 'played'}, onComplete: function () { this.target.style.opacity = 0; this.target.classList.remove('played'); } }, .035, 0, removeElemWithNoFullOpacity);
        TweenMax.to('.image-sequence', 1, {left: '15%'});
        rotateSkeleton.tweenTo(1);
        // setTimeout(function() {
        //     removeElemWithNoFullOpacity();
        // }, 1000)
    }

function finishSkeletonAnimation() {
        if(mySwiper.previousIndex < mySwiper.realIndex) {
            TweenMax.fromTo('.image-sequence', 2, {left: '15%'}, {left: '-30%'});
            rotateSkeleton.tweenFromTo(1, 4);
        }
        // setTimeout(function() {
        //     removeElemWithNoFullOpacity();
        // }, 2000)
    }

 

I added the tl to 'rotateSkeleton' because I wanted to use the 'tweenTo' and 'tweenFromTo' methods to stop the animation at a certain time and continue when I call the 'finishSkeletonAnimation' function

Link to comment
Share on other sites

Still, you don't need to create another variable to use the tweenTo method. Also, not what Carl has said up there, you don't want to keep adding a brand new staggerTo every time you call the animateSkeleton.

 

 

The firs thing I say you need to do is understand the difference between creating your timeline and controling your timeline. They are separate things, you don't want to be triggering changes to your timeline (well, sometimes you do but, in your case here, I don't think so) when controlling the playhead.

 

So, really, you want to build the animation in one set of functions and control it with a different set.

 

var tl = new TimelineMax();

function createTimeline() {
  // Sudo code guessing game
  tl.to({}, 1, {}); // blah
  tl.staggerTo(
    images,
    .1,
    {
      opacity: 1,
      onUpdate: function() {
        this.target.className = 'played' // Are you aware this is running on every single frame of the animation?
      },
      onComplete: function () {
        // I'm pretty sure these two lines bellow do not work as in this scope 'this' is the timeline itself
        this.target.style.opacity = 0;
        this.target.classList.remove('played');
      }
    },
    .035,
    0,
    removeElemWithNoFullOpacity
  );
  
}

function animateSkeleton() {
        images.removeClass('played');
        TweenMax.to('.image-sequence', 1, {left: '15%'});
        tl.tweenTo(1);

    }

function finishSkeletonAnimation() {
        if(mySwiper.previousIndex < mySwiper.realIndex) {
            TweenMax.fromTo('.image-sequence', 2, {left: '15%'}, {left: '-30%'});
            tl.tweenFromTo(1, 4);
        }

    }

 

Now, if what you you want is to control that little section of the total animation that you named 'rotateSkeleton', that will be a bit more convoluted. You'll probably be better off assigning labels to the sections you want to tween to and tween to those sections as needed.

 

Does that help?

  • Like 4
Link to comment
Share on other sites

I am back

 

I have dig up the forum and found a solution.

It seems to be working and not adding extra element to the timeline.

 

var fp = TweenMax.staggerTo(images, .1, { opacity: 1, onComplete: function () { this.target.style.opacity = 0; } }, .035);
    var sp = TweenMax.fromTo('.image-sequence', 3, {left: '60%'}, {left: '-30%'});
    tl.add([fp, sp], 0);
    tl.add('a', tl.duration() * .2);
    tl.add('b', tl.duration() * .99);

    // window.addEventListener('')

    function animateSkeleton() {
        if(mySwiper.previousIndex === 0 || mySwiper.previousIndex !== 2) {
            if($('.image-sequence').hasClass('first-part-played')) {
                tl.progress(.2);
            } else {
                tl.tweenTo(tl.duration() * .2);
                $('.image-sequence').addClass('first-part-played')
            }
        }
        if(mySwiper.previousIndex === 2) {
                tl.tweenFromTo('b', 'a');
        }
    }
    
    function finishSkeletonAnimation() {
        if(mySwiper.previousIndex !== 1) {
            tl.progress(.99);
        } else {
            tl.tweenFromTo('a', 'b');
        }
    }

 

This animation works on a slider. So if I go to a different slide than it continues the animation or reverse it back. And if I go to any slide where the skeleton is but the previous slide was not part of the animation than it just set the progress of the timeline to '.99' or '.2' . It depends on which slide you click on. It will be 1 but not yet now.

 

thank you for the help guys

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...