Jump to content
GreenSock

kaplan

How to use vars, to better understand what's happening?

Recommended Posts

Hi,

 

I'm just wondering how to use TweenLite to tween a css property without using the CSSPlugin? I know this is probably really dumb, but I'm trying to get a better sense of what's going on in the Tween.

 

What would I use to do this without the CSSPlugin? 

element = document.getElementById("element")
TweenLite.to(element, 1, { css:{opacity:0.5} });

Thanks for reading.

 

Link to comment
Share on other sites

Sure, let me try to break it down for you...

 

Every animation at its core is simply about interpolating between two numbers over time, and applying the appropriate value at the appropriate time (usually 60 times per second). You can tween a generic object like this:

var obj = {opacity:0};
TweenLite.to(obj, 2, {opacity:0.5, onUpdate:report});
function report() {
    console.log(obj.opacity);
}

You'll see that obj.opacity goes from 0 to 0.5 over 2 seconds. Great. 

 

To animate CSS properties, however, it's a bit more tricky. Not only are they not directly attached to the object/target itself (they're in the object's "style", like element.style.opacity), but they often need suffixes, and sometimes they're composed of complex values like background-color:rgb(255,0,51) or background-position:25px 32px. That's the whole point of CSSPlugin - it smooths over all that stuff for you and does the hard work of getting current values, parsing them, checking for browser compatibility, implementing workarounds when necessary, etc. 

 

Let's take your opacity example. We could do this:

var element = document.getElementById("yourID"),
    obj = {opacity:0};
TweenLite.to(obj, 2, {opacity:0.5, onUpdate:applyOpacity});
function applyOpacity() {
    element.style.opacity = obj.opacity;
}

That should work great in most browsers, but unfortunately IE8 and earlier doesn't recognize "opacity" as a valid property. Instead, Microsoft uses their own proprietary filter, so you must set the filter to something like "alpha(opacity=50)". Yuck, right? 

//IE8 and earlier:
element.style.filter = "alpha(opacity=50)";
//everybody else:
element.style.opacity = "0.5";

On top of that, IE uses filters to accomplish other things, like rotations, skews, scales, etc., so if you do an opacity fade on an object that's rotated, you must have BOTH filters represented. And they have to be in a certain order to work effectively. For example, to have an image rotated and partially transparent, it might look like this:

//IE8 element with a rotation and opacity
element.style.filter = "progid:DXImageTransform.Microsoft.Matrix(M11=0.85414, M12=0.214, M21=0.85414, M22=0.3142, sizingMethod='auto expand') alpha(opacity=50)";

Fun, right?

 

There are a bunch of bugs and little quirks to work around in IE8. So again, this is why it's so useful to just use CSSPlugin - it does all the hard work for you so that you can simply write this code:

TweenLite.to(element, 2, {opacity:0.5, rotation:30}); 

And it'll work consistently across browsers. 

 

The other thing you'll need to do if you're handling this manually is figure out what the CURRENT value is of the css property you're trying to animate so that you can set the starting value appropriately. And you cannot simply check element.style.opacity (or whatever property) because that assumes it was set inline rather than in a style sheet. So you end up needing to use document.defaultView.getComputedStyle() on the element to grab its current values. But again, IE8 and earlier use a completely different mechanism, element.currentStyle. 

 

Oh, and dealing with transforms (scale, rotation, x, y, skew, etc.) is a whole different ball of wax - to get current values you must parse a matrix (which could be 2D or 3D) and make sure you handle the components independently. Firefox has bugs related to rendering 3D transforms that start at a scale of 0 and change less than 0.005 in a frame render, and Safari has bugs related to transformOrigin that can make things act very strangely. IE8 and earlier requires a ton of extra effort to compose the matrix values to a filter and then offset with margins to basically fake transformOrigin functionality (I haven't seen any other tools do it reliably). CSSPlugin works around all those issues for you. 

 

Lastly, you must "clean" your numeric values before applying them as a string to css properties because if, for example, you have a value of 0.000000001 and you concatenate a suffix to it (like "px" or any string), it ends up as "1e-9px" which usually causes an error in the browser when you apply it to a css property. So you must either use toFixed() on your numbers (which is slow) or run conditional logic and round things only when necessary. Yeah, it's a pain. 

 

So to answer your question, you can certainly animate the properties of a generic object and use an onUpdate to then apply them in whatever way you please to the element's style, thus you get the css animation you want. Just be careful about all the caveats.

 

Oh, and what happens when you want to manage overwriting or killTweensOf(), etc.? It can balloon into a clunky mess pretty quickly unless you're only doing very simple stuff. That's why GSAP has gotten so popular with cutting-edge designers/developers out there - it makes an animator's workflow much smoother and avoids headaches. Less code, more reliable, and far more flexible.

 

Of course I know you weren't arguing against using CSSPlugin at all. You're probably just trying to get a feel for how the very basics work of animating a CSS property, and I think that's fantastic. I wish every developer did that because it can really help you understand what the heck is going on and how to effectively leverage tools (and know WHY they're valuable). 

 

Good luck!

  • Like 6
Link to comment
Share on other sites

Wow, thanks Jack!!! Great explanation! That was exactly what I was wondering, what's going on there?! Love it!

 

I'm looking forward to digging into the Javascript version. I've used the AS version for a few years, this is going to be fun!!

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