Share Posted April 21, 2017 I need to make some calculations for a Tween I want to add. But when I .add() it with a anonymous function returning the Tween, the following tween doesn't wait for it's turn. Like it doesn't know how long it's gonna take. "But Why!?" am I thinking. Dear Elders, help me out here please See the Pen Mmydqd by katerlouis (@katerlouis) on CodePen Link to comment Share on other sites More sharing options...
Share Posted April 21, 2017 Please try it like this: .add(function() { var someCalculations; someCalculations = "blue"; return TweenMax.to("body", 2, { backgroundColor: someCalculations }); }()) That should get you the desired result. Happy tweening. Link to comment Share on other sites More sharing options...
Author Share Posted April 21, 2017 Okay, I am highly confused: 1) Why does parantheses AFTER an anonymous function make the problem disappear? 2) now I added those parantheses, but the calculations I want to make, get ignored (better said: probably calculated at some other time, which is not convenient for me) EDIT: it appears the anonymous function gets calculated before anything else, now? Link to comment Share on other sites More sharing options...
Share Posted April 21, 2017 I'm not sure what you mean. With that change, your demo is exhibiting the behavior I would expect. The box moves, background animates to yellow, background animates to blue, box moves back to 0. Just my two cents worth, but the add() method is best used for nesting timelines into a master. Rather than adding anonymous functions, I'd recommend something like this: var master = new TimelineMax({paused:true}); // child 1 function child1() { var tl = new TimelineMax(); tl.to("#someElement", 1, { x: 100 }); return tl; } // child 2 function child2() { var tl = new TimelineMax(); tl.to("#anotherElement", 1, { x: 100 }); return tl; } master .add( child1() ) .add( child2() ) .play(); Happy tweening. Link to comment Share on other sites More sharing options...
Author Share Posted April 21, 2017 This doesn't work for me; I need to calculate the widths and heights that are applied at that exact moment. tl = new TimelineMax({ repeat: -1 }); tl .from("#box-1", 2, { width: 0 }) .to("#box-1", 2, { width: 400 }) // effect shrink from the left .add(function() { var width = $("#box-1").width(); console.log(width); return TweenMax.to("#box-1", 2, { x: "+="+width, width: 0 }); }()) // with the additional parentheses the timing of the .add() is no longer ignored // but the width calculation fails totally, seems to be 0? Why? .to("body", 2, { backgroundColor: "blue" }) ; The width inside the .add() is zero; which I just can't have :'( I understand that the ".from()" is set at the time the .add(function()) is run through; and nested timelines don't help here as it seems. Is .call() the solution? PS: I'm still curious why .add(function() {}()); works? (+ 2 parantheses) Link to comment Share on other sites More sharing options...
Share Posted April 21, 2017 I see... you need the width of the box after its been tweened. Would something like this work for you? .to("#box-1", 2, { width: 400, onComplete:getWidth }) function getWidth() { var width = $("#box-1").width(); console.log(width); return TweenMax.to("#box-1", 2, { x: "+="+width, width: 0 }); } Blake did a lengthy answer about add, callbacks, etc. which should help: https://greensock.com/forums/topic/16348-multiple-timelines-sharing-addplay-wont-play/ Happy tweening. Link to comment Share on other sites More sharing options...
Author Share Posted April 21, 2017 I need many tweens of these kind chained, mostly regarding the same element. Nesting so many onCompletes doesn't seem right If I misunderstood you on this one, I'd be thankful if you could fork my pen. Link to comment Share on other sites More sharing options...
Author Share Posted April 24, 2017 Sorry, I have to push this again– I solved this now with hardcoding / saving the desired widths, but still am curious how I could dynamically calculate the widths and this exact point. I mean, there must be a way, right? Link to comment Share on other sites More sharing options...
Share Posted April 24, 2017 It sounds like using a function-based value will do the trick for you here as the values are not determined until the animation runs var customHeight = 0; var tl = new TimelineLite() tl.to(".box", 1, {width:500}) .to(".box", 1, {height:customHeight}) // 0 .to(".box", 1, {height:function(){ return customHeight; //500 }}); //change the value of customHeight 0.5 seconds after timeline starts TweenLite.delayedCall(0.5, changeCustomHeight); function changeCustomHeight() { console.log("huh") customHeight = 500; } notice that 2 tweens use the same customHeight value. The first height tween gets a value of 0 and the second gets a value of 500. 3 Link to comment Share on other sites More sharing options...
Share Posted April 24, 2017 oops, forgot to fork: http://codepen.io/GreenSock/pen/eWdRbJ?editors=1111 Link to comment Share on other sites More sharing options...
Author Share Posted April 24, 2017 Thank you, Carl! This works for me, although it would feel more intuitive, if my first CodePen would just work, where I .add() an anonymous function. I see that GSAP needs to run the function "so early" in order to get the duration and offset (and maybe even more I don't know about); Now I know better– Woop Woop! Having another function + delayedCall swirling around is not necessary in my case. I just did this: .to("#box-1", 2, { x: function() { return "+="+ $("#box-1").width(); }, width: 0 }) - Now lets say I want to make the same thing for more than 1 property. Why doesn't the following work? // Return the whole property object with a anonymous function // Doesn't work :'( .to("#box-1", 2, function() { // some calculations... var width = $("#box-1").width(); var someOtherCalculation = 0; // imagine fancy math here var bg = (some_fancy_if) ? "green" : "red"; return { x: width, width: someOtherCalculation, backgroundColor: bg } }) Fork: See the Pen Mmydqd by katerlouis (@katerlouis) on CodePen Link to comment Share on other sites More sharing options...
Share Posted April 24, 2017 Cool. The delayedCall() was just to illustrate that the customHeight variable could change by an "external" factor before the tween runs. If you want to set multiple values, you just need unique functions for each property: TweenLite.to(something, 1, { x:function() { // custom things return someValue }, width:function() { // custom things return someValue }) 2 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now