Jump to content
GreenSock

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

Tween from Relative to Absolute

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

I'd like to have some table cells animate from their automatically laid out relative position, to certain designated absolute positions to highlight them, and then have them return to their position in the table.

 

In particular I have a Gantt chart with three selectable cells which I would like to tween from its initial...

{top:"0%",left:"0%",width:"auto",height:"auto",position:"relative"}
{top:"0%",left:"0%",width:"auto",height:"auto",position:"relative"}
{top:"0%",left:"0%",width:"auto",height:"auto",position:"relative"}

to a temporary...

{top:"0%",left:"0%",width:"100%",height:"33%",position:"absolute"}
{top:"33%",left:"0%",width:"100%",height:"33%",position:"absolute"}
{top:"66%",left:"0%",width:"100%",height:"33%",position:"absolute"}

...and then tween them back to their initial relative values again.

 

Is there a Greensock way of doing this?

 

If I use a regular to(...) tween with the values above, the 'position' value is toggled monolithically to 'absolute', with the top and left set to 0 so the cells jump to the top left corner immediately, then tween their location and width from there, rather than tweening smoothly from their initial (relative) location.

 

There's probably a workaround, involving JQuery calculating the starting positions for the tween from the rendering engine, but perhaps someone has an elegant way of doing this, as I'm sure I'm not the only one who needs the behaviour.

Link to comment
Share on other sites

Hello.. usually the default CSS position of a table cell (td) is static.. are you setting your table cells initial position to relative in your CSS?

 

do you have a jsfiddle or

See the Pen by pen (@pen) on CodePen

example so we see your code in action and how it is behaving in the browser..

 

thanks :)

Link to comment
Share on other sites

Have you considered just using transforms instead? Remember, when you tween "x" and "y" it refers to the css transform which is relative to the normal position in the layout (think of them as offsets). Granted you'd probably still need to do some calculation of the original positions so that you can figure out what the offset(s) should be, but in general transforms can tend to be cheaper performance-wise because they don't affect layout meaning the browser doesn't have to concern itself with figuring out how the document flow would change.

 

I'm not aware of any simplistic way to accomplish what you're after, though (changing from relative position to absolute seamlessly). It's definitely possible to do though with some JS - we do this sort of thing in our SpiltText tool for breaking apart text into individual <div>'s for each letter and/or word and/or line and mapping its position. It's not something we've got in as a canned solution, though, that you can just point at any old element (yet). 

 

If you need more help and want to talk to us about consulting services, shoot me a PM or e-mail. 

  • Like 1
Link to comment
Share on other sites

@jonathan thanks for the codepen suggestion it's really fun. This shows the problem, and I'll knock together a solution in a bit.

 

See the Pen GEBvh by anon (@anon) on CodePen

Link to comment
Share on other sites

OK, this is a codepen which I believe _should_ work, but doesn't work either in Chrome or in Firefox. Any ideas what's wrong with my logic (or JQuery's offset(), width() and height() implementations)...

 

See the Pen cfsIv by anon (@anon) on CodePen

Link to comment
Share on other sites

@Greensock thanks for the suggestion. I don't know how transforms would help me exactly, as I need to tween from its current location to a target location relative to the viewport, and I don't know how a transform's coordinate system could help me achieve this (especially given that I can't seem to work out where the element actually is to begin with).

Link to comment
Share on other sites

How about using the element's getBoundingClientRect() method?

Link to comment
Share on other sites

OK, my stupid. There could be an initial problem to do with the fact that changing individual cells to absolute positioning could affect the position of other cells (because they no longer take up the same space in the layout). If that's true I may need to do a caching run (storing positions) followed by a positioning run (setting positions).

 

The updated version of the Codepen takes account of this, and yet is still doing junk positioning owing to a bug in JQuery width() when applied to table cells I think.

 

The following codepen includes a workaround, ignores JQuery's width, and substitutes a hard-coded value, and finally works, but in a roundabout fashion.

 

See the Pen ewAby by anon (@anon) on CodePen

Link to comment
Share on other sites

I had a go at using getBoundingClientRect() but this junks the width information too...

 

See the Pen xzFBc by anon (@anon) on CodePen

 

...I suspect this is a bug in Chrome or could be my misinterpretation of what width value I need to be querying.

Link to comment
Share on other sites

So in conclusion, the least worst approach seems to be to rely on JQuery's css methods, but then override its junked "width" value with a known assignment, as suggested by this codepen which works fairly well.

 

See the Pen rtuyo by anon (@anon) on CodePen

 

Ideally it would be possible to also revert to the original values without having to manage this information explicitly. Is there a reliable strategy in Greensock to get back to initial values?

Link to comment
Share on other sites

Do you mean reverse() the tween? Or you can jump to the beginning by calling seek(0). Or put all your tweens into a TimelineLite so that you can control them as a whole, and just call seek(0) on that (or actually, pause(0) if you want it to jump to the beginning and pause). 

 

(I may have misunderstood your question)

Link to comment
Share on other sites

In practice I'm calling quite a few tweens and hoping to be able to have a single point in the timeline as a place I can tween back to, regardless of what the last tween happened to be.

 

It could be the only way to do this is manually store all the relevant CSS through JQuery data(...), but this seems like a bit of a nightmare. I'm guessing that reversing a from(...) will only reverse the attributes which that from(...) tween was actively manipulating, and if other tweens have run in the meantime, they won't be reversed.

 

As it turns out the place I want to revert to is the same place the elements were when the page was loaded if that helps simplify the problem at all.

Link to comment
Share on other sites

You're correct about tweens only recording the data that you're actually tweening (otherwise, it'd be pretty wasteful memory-wise and performance-wise). You could just grab the element's className and style.cssText and store them so that you can easily revert those later. That'd probably be better than iterating through every property and storing each one. Just an idea. 

 

Also, if you're using GSAP to do all of your changes, you could just create a TimelineLite for each element (or maybe just a master one) into which you place your tweens so that you could just pause(0) to get back to the original state. Maybe storing the className and style.cssText would be easier for you though. 

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.

×