Jump to content
JoeC

OnComplete callback fires immediately

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 :)

Share this post


Link to post
Share on other sites

Easy fix. Just remove the parentheses. That calls the function immediately, which is not what you want.

onComplete: exampleCallback
  • Like 4

Share this post


Link to post
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)

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

@blaasvaer There's not enough information in your post in order for us to help you. How are you calling those functions?

 

Could you please create a minimal demo in a CodePen or something like that? For more information about how to do so, see this post.

 

 

 

Share this post


Link to post
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;

 

Share this post


Link to post
Share on other sites

@blaasvaer Thanks for providing some additional code. From what I can tell your logic in the class itself is fine. Can you please provide a minimal working demo that shows the issue you're having? 

Share this post


Link to post
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 ...

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Unfortunately that video won't open in QuickTime for me. 

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

I agree, unless you see all the code it's hard. But sharing a complete wordpress website seem overkill. And picking out the parts will become an umanageable nightmare. So, there we are ; )

Share this post


Link to post
Share on other sites

As this demo shows your logic is fine. It's got to be something else that we don't have access to.

 

See the Pen EBEyYJ by ZachSaucier (@ZachSaucier) on CodePen

  • Like 4

Share this post


Link to post
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;
			}
		}
	}
}

 

Share this post


Link to post
Share on other sites

My guess is that it's some conflicting JS. Maybe start your search in those files.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
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

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
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).

Share this post


Link to post
Share on other sites

You clearly have a some sort of transition in your CSS. Try removing that.

 

XqjZh9x.png

 

 

  • Like 1

Share this post


Link to post
Share on other sites

Yes, I was aware of that. And that was removed. But the problem persists. Unfortunately.

Share this post


Link to post
Share on other sites

As said, I'm about to completely isolate it. But being a Wordpress solution using SASS, it's a pretty nightmare to extract the relevant code.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.