Jump to content
Search Community

OnComplete callback fires immediately

JoeC test
Moderator Tag

Go to solution Solved by OSUblake,

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

Hello,

 

I've set up a timeline which has several nested animations within it. On one of the nested animations I'd like to fire an onComplete callback function so that I can change a bit of code. The problem is, the onComplete function triggers as soon as the animation begins, rather than after it. I've attached the code so you can see what I mean:

function playScene1() {

    var tl = new TimelineLite();

    tl.to(hand, .6, {
        x: "-= 100%",
        y: "+= 0%",
        repeat: 1,
        yoyo: true,
        repeatDelay: 0,
        ease: Power1.easeInOut
    }, 0);

    tl.to(globe, .6, {
        x: "+= 160%",
        y: "+= 0%",
        repeat: 0,
        yoyo: false,
        repeatDelay: 0,
        delay: .6,
        ease: Power1.easeInOut
    }, 0);

    tl.to(hand, .6, {
        x: "-= 100%",
        y: "+= 0%",
        repeat: 1,
        yoyo: true,
        repeatDelay: 0,
        ease: Power1.easeInOut
    }, 1.2);

    tl.to(globe, .6, {
        x: "-= 160%",
        y: "+= 0%",
        repeat: 0,
        yoyo: false,
        repeatDelay: 0,
        delay: .6,
        ease: Power1.easeInOut,
        onComplete: exampleCallback()
    }, 1.2);

    tl.play();
}

exampleCallback() is fired as soon as the timeline begins, I'd like to inject my own function after it's finished animating. Sorry if I've missed something very simple here :)

Link to comment
Share on other sites

Edit: I was having a problem Googling the right words :) onCompleteParams: ["param1", 2] solves the following problem too: 

 

Thanks for this, but I also need to add some parameters too, I should have added that to the original post, sorry.

 

Is there a way to do the following:

onComplete: exampleCallback("Example String", 1)
Link to comment
Share on other sites

For paramaters, put them inside an array (even if there is only 1), under onCompleteParams.

onComplete: exampleCallback,
onCompleteParams: ["Example String", 1]

You can also bind a function and do it all 1 line, but using the onCompleteParams syntax is going to be better performance wise.

onComplete: exampleCallback.bind(null, "Example String", 1)

Here's an example of both.

See the Pen 721d6eab468a0c53cec28c472c45e6f8 by osublake (@osublake) on CodePen

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

  • 2 years later...

Ok, but I have this, and it still fires immediately:

 

        function close_main_menu () {

            TweenLite.to('.menu-my-main-menu-container', 0.35, { height: '0', ease: Power1.easeIn, onComplete: hideMenu } );

        }

        function hideMenu () {
            $('.menu-my-main-menu-container').hide();
        }

 

What am I doing wrong?

Link to comment
Share on other sites

This is the entire class, nothing fancy going on:

 

class Navigation {
	constructor () {
		this.addEventListeners();
	}

	addEventListeners () {
		let _this = this;
		let logo = $('.logo');
		let nav_icon_burger = $('a.nav_icon.burger');

		nav_icon_burger.on('click', function ( e ) {
			e.preventDefault();
			e.stopPropagation();

			$(this).toggleClass('open');

			if ( $(this).hasClass('open') ) {
				open_main_menu();

				$('body').addClass('no_scroll');
			} else {
				close_main_menu();

				$('body').removeClass('no_scroll');
			}
		});

		function open_main_menu () {
			if ( window.matchMedia( "(max-width: 840px)" ).matches ) {
				TweenLite.to('.menu-my-main-menu-container', 0.35, { left: 0, height: "100%", ease: Power1.easeIn} );
			} else {
				TweenLite.to('.menu-my-main-menu-container', 0.35, { height: "100%", ease: Power1.easeIn} );
			}
		}

		function close_main_menu () {
			nav_icon_burger.removeClass('open');

			TweenLite.to('.menu-my-main-menu-container', 0.35, { height: '0', ease: Power1.easeIn, onComplete: hideMenu } );
		}

		function hideMenu () {
			$('.menu-my-main-menu-container').hide();
		}
	}
}

export default Navigation;

 

Link to comment
Share on other sites

It'll probably take half a day to 'remove' the code from the context. I will record a video to explain further, as I thought it had to do with the nested elements being 'moved around' by the 'collapsing' height. That seem not to be the issue, but rather 'when' gsap fires the 'onComplete' handler ...

Link to comment
Share on other sites

I changed to close time to 5 sec. for being able to see what's going on. If I animate the height property with GSAP it doesn't work. But if I do it in the inspector it behaves as expected (do not disappear before complete collaps).

 

It's as if if fires the second the container hits the content.

 

See it in action here: http://www.blaasvaer.dk/oncomplete.mov

Link to comment
Share on other sites

Interesting that it hides it part way through the animation. It looks like it's stopping around the time it meets the height of the menu items - perhaps a height:auto type of thing. Maybe changing 0 to 0% would help?

 

I also noticed that it's jumping from 58px to 9px in the demo and then the height is changed to 0 and the display: none is added. 

 

Maybe there's some other code that is affecting this element somehow that you haven't shared. Overall it's hard for us to help without seeing more things for ourselves.

Link to comment
Share on other sites

Well, I'm sure you're right. 'Cause that behaviour would be what I would expect. But I simply cannot figure out what part of the 'height' is causing this ...

 

This is the css for the menu container:

 

.menu-my-main-menu-container {
	display: block;
	position: fixed;
	background-color: pink;
	width: 100%;
	height: 0%;
	overflow: hidden;
	z-index: 2;

	ul#primary-menu {
		padding: 10% 15%;

		li {
			a {
				font-size: 1.25em;
				font-weight: 100;
				line-height: 2.5em;
				text-transform: uppercase;
				color: $black;
				text-decoration: none;
			}

			ul.sub-menu {
				display: none;
				position: relative;
				left: 10%;
				top: 0;

				@media screen and (max-width: 800px) {
					position: relative;
					left: 5%;
				}

				li {
					a {
						color: $black;
					}
				}
			}
		}

		li.inactive {
			a {
				color: lightgrey;
			}
		}
	}
}

 

Link to comment
Share on other sites

7 hours ago, blaasvaer said:

Ok, but I have this, and it still fires immediately:

 

        function close_main_menu () {

            TweenLite.to('.menu-my-main-menu-container', 0.35, { height: '0', ease: Power1.easeIn, onComplete: hideMenu } );

        }

        function hideMenu () {
            $('.menu-my-main-menu-container').hide();
        }

 

What am I doing wrong?

 

For the tween in close_main_menu to run, something has to call it first. Find out what is calling it. Functions don't run on their own (technically they can, but you're not doing that).

 

5 hours ago, blaasvaer said:

It must have something to do with WHEN GSAP thinks the height is 0. Just don't know what ...

 

If you think the problem is with GSAP, then comment out all your GSAP code, replace it with jQuery .css() code if needed, and run your solution again. If the problem still persists, it's safe to assume that it has nothing to with GSAP.

 

  • Like 2
Link to comment
Share on other sites

Erm, thanks. But I do know that. This was just partial code to illustrate that it didn’t have anything to do with () at the end. The issue isn’t solved, but has to do with some weird height behaviour of some kind. But you can only spend so much time trying to figure weird stuff out. And then think of another solution.

Link to comment
Share on other sites

12 minutes ago, blaasvaer said:

This was just partial code to illustrate that it didn’t have anything to do with () at the end. 

 

Nobody said it did. The OP posted code that clearly showed the () as the problem. The code you posted doesn't. My guess is that you might have CSS transitions on some of those elements, or some of your event handlers are being called more than once for the same action.

 

  • Like 1
Link to comment
Share on other sites

Thanks, but that seems to not be the case. I'm pulling all relevant code out of the spaghetti it's in at the moment to create an isolated version. To see if that can get me any closer. But there's really not that much going on in this case, as you can see in the above CSS and JS (further up the post).

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...