Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
roblevintennis

Do TimelineMax Constructor Properties Behave as Fallbacks?

Go to solution Solved by Carl,

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

Please note that I'm heavily editing my pen, so I just put some code below too.

 

Sorry if this is a silly question, but is my assumption in the comments below correct? That I can set ```transformOrigin``` in the constructor as a default fallback property? Yes, I realize that it would be the normal way, but don't have time to set up a test and I'm being lazy hehe ;)

function targetReady() {
  var tl = new TimelineMax(); 
  
  //If I pass a property to constructor like this origin:
  //var tl = new TimelineMax({transformOrigin: "center center"}); 
  //Is my assumption correct that this will be an overridable default fallback, such that any .to, .from, etc., that supplies it's own will take precedent? Also, if it supplied a svgOrigin property...would that take precedence over transformOrigin set in the constructor?


  
  //Trying to "DRY up" this sort of redundant setting of transform origin:
  tl.addLabel('targetReady')
    .from(finger, .7, {opacity: 0, x: -400, ease: Linear.easeNone}, "targetReady-=.5")
    .from(circleStroke, .7, {opacity: 0, x: 400, ease: Linear.easeNone}, "targetReady-=.5")
    .to(finger, .1, {scale: .99, transformOrigin: "center center", ease: Linear.easeNone}, "targetReady+=.7")  
    .to(circleStroke, .1, {scale: .98, y:1, transformOrigin: "center center", ease: Linear.easeNone}, "targetReady+=.7") 
    .to(finger, .1, {scale: 1, transformOrigin: "center center", ease: Linear.easeNone}, "targetReady+=.85") 
    .to(circleStroke, .1, {scale: 1, y: 0, transformOrigin: "center center", ease: Linear.easeNone}, "targetReady+=.85") 
    .from(glass, 2, {opacity: 0, transformOrigin: "center center", ease: Linear.easeNone}, "targetReady+=2")  
    .to(circle, 1, {scale: 30, opacity: 0, transformOrigin: "center center", ease: Linear.easeNone}, "targetReady+=1")
    .set(circle, {scale: 0, opacity:0, transformOrigin: "center center", ease: Linear.easeNone}, "targetReady+=2.2")
    .to(circle, .5, {scale: 1, opacity: .4, transformOrigin: "center center", ease: Power2.easeOut}, "targetReady+=2.4")
    .to(uxTest, 2, {opacity: 0, scale: 0, svgOrigin: "center center", ease: Linear.easeNone}, "targetReady+=3")
    .from(checkmark, 2.5, {opacity: 0, scale: 0, transformOrigin: "center center", ease: Back.easeOut.config(1.7)}, "targetReady+=4.5")
  
  return tl;
}

See the Pen qZQxJz by roblevin (@roblevin) on CodePen

Link to comment
Share on other sites

  • Solution

Hi Rob,

 

Nice to see you!

 

Sorry, but you can not set transformOrigin in the timeline constructor vars, it needs to be set on individual tweens. 

However if you set transformOrigin to "center center" in one tween for your circle, you do not need to set it again on subsequent tweens of circle. 

  • Like 4
Link to comment
Share on other sites

Hi Rob :)

 

In addition to Carl's great advice about setting the transformOrigin on those elements once, you can also define a default ease to help 'DRY up' your code. I think that gets missed sometimes, but when you're using the same ease over and over, it can be helpful to define a default. It looks like Linear is used on the majority of your tweens so you could add this code:

TweenLite.defaultEase = Linear.easeNone; 
// you can still override it on individual tweens, but unless you specify otherwise, you'll get the default

There's my 2 cents worth of advice. 

 

Happy tweening.

:)

  • Like 3
Link to comment
Share on other sites

Thanks guys!

 

>if you set transformOrigin to "center center" in one tween for your circle, you do not need to set it again on subsequent tweens of circle. 

 
Certainly useful and helpful to know. Thanks Carl!
 
>TweenLite.defaultEase = Linear.easeNone;
 
Right, I saw that. Seems odd that eases have that but not other properties.
 
I'll close this solved as you guys gave me the 411, thanks! But here's what my "least surprised" expectation as a user would be–with absolutely no expectation that Greensock implements this–I definitely empathize with how much effort it'd take ;)
 
TweenLite.defaultEase = Linear.easeNone; // Most global. Least specific–overridable by all

TweenLite(foo,1, {ease: Linear.easeOut}); // Overrides global. Less specific than tween methods

to.to(foo,1, {ease: Linear.easeInOut}); // Overrides global and constructor
Maybe something for a couple years out  :-P
Link to comment
Share on other sites

And fwiw, I DID go ahead and update my pen per both of your suggestions and it did DRY up the code quite a bit...thanks: 

See the Pen qZQxJz by roblevin (@roblevin) on CodePen

  • Like 2
Link to comment
Share on other sites

Thanks for the suggestions, Rob. Sounds almost like a cascading way of defining properties. Ha. "Cascading GreenSock" (CGS) instead of CSS. :) 

  • Like 4
Link to comment
Share on other sites

Hi @roblevintennis
 
I made something that might help you out...
 
I've always wanted the ability to select and set an element at the same time. You can kind of do this with jQuery, but SVG has been on jQuery's Won't Fix list since 2009, so I came up with something that was a little more SVG friendly. A selector engine that uses TweenLite.set(). It's only 11 lines of code, and should work in any modern browser.
 
Here's the basics. Using $ returns a single element. Using $$ returns an array of elements. And you can pass in an optional config object just like TweenLite.set()

// Returns the first circle
var circle = $(".circle");

// Returns an array of all circles
var circles = $$(".circle");

// Returns an array of all circles and sets their transform origin
var circles = $$(".circle", { transformOrigin: "center center" });

You can check out the code with some additional examples here.

See the Pen JYLyRN?editors=0010 by osublake (@osublake) on CodePen


 
I modified your demo to use it. I tried to set as many properties as possible upfront so your timelines would be a little cleaner, using only .to() tweens. This may or may not be what you wanted, but it's only an example. I also set the transform origins individually, but you could have grouped them together like this.

TweenLite.set([checkmark, circle, circleStroke, finger, persons], {
  transformOrigin: "center center"
});

I was thinking about a way to do an alternate default ease by changing the scope of some things, but I didn't want to throw anything super complicated at you, so I just passed the Power2.easeOut as a normal parameter.

 

See the Pen BKvGgx by osublake (@osublake) on CodePen

  • Like 6
Link to comment
Share on other sites

OSUblake how do you at mention lol I'm lost!

 

I do like the result of your refactor of my code. If I understand, the core to your trickery is the fact that, as Carl mentioned, once a particular element has been .set, it will retain those properties on subsequent use. Clever, and it does DRY up the code to look how I would have hoped.

 

Seems like overriding dollar signs would, in long term be unfortunate since so many jquery users out there, but I assume that was more for demonstration purposes. Hrm, not sure how to keep it short and sweet though. 

 

Maybe if jQuery's on page, you could add it to it's proto, then usage like:

var check = $(".checkmark").preset({ opacity: 0, scale: 0, transformOrigin: center });

But if jQuery's not you'd have to map $ to get query selector and build up it's prototype. Then do you make arrays presetArray? I dunno  :?

 

Definitely impressive idea either way OSUblake. It really does make my code much more tolerable so I'd think folks would like a way to achieve this.

Link to comment
Share on other sites

You know, as I reread your code and my last comment, it really seems like the best take away for me is that it's a best practice to favor .set and .to combination for this as opposed to .from, and accomplishes what I was after (presetting overridable properties) without any new methods to add. Thoughts?

Link to comment
Share on other sites

Seems like overriding dollar signs would, in long term be unfortunate since so many jquery users out there, but I assume that was more for demonstration purposes. Hrm, not sure how to keep it short and sweet though. 

 

You're right, it probably would confuse a lot of people. I was using the dollar signs to make it short and familiar looking, but you can name it whatever. So maybe something like select and selectAll. That's what @chrisgannon uses as aliases for document.querySelector/querySelectorAll.

 

No more confusion...

See the Pen KzJVwJ?editors=0010 by osublake (@osublake) on CodePen

 

Your jQuery idea is actually pretty good! I never thought about how easy it would be to do that.  

$.fn.preset = function(config) {
  TweenLite.set(this, config);
  return this;
};

jQuery + preset

See the Pen LNqGER?editors=0010 by osublake (@osublake) on CodePen

 

Pretty Nice! Although I'm not sure how I would handle jQuery missing. You just have to make sure it's loaded first.

 

About your last comment...

I wouldn't say using .set and .to is a best practice. Using .from does serve a purpose, and it can be really convenient to use as the first animation, but you need to be careful about using it more than once on the same element in a timeline. Doing so may cause some unexpected behavior, which can usually be resolved by setting the immediateRender property.

 

If you're not familiar with immediateRender, you should check out this video.

 

  • Like 3
Link to comment
Share on other sites

Yeah, I'm all in on that preset refactor OSUblake! Also, I liked the way you passed in an alternate ease from the master timeline calls too. The immediateRender stuff makes sense and Carl's video was crystal clear. I guess the thing I like about .from is it's fast use for a sort of "discovery" when you're designing the initial interaction. I could see a workflow like:

  1. Experiment using .from to "spike" on the idea
  2. Set a default ease if default easeOut doesn't suite
  3. Refactor redundant properties back in to that .preset method
  4. Pass in the second most used ease from master to nested timelines (like your example)

I'm amazed at how much I've learned from one forum post...wow!

  • Like 2
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.
×