Jump to content
Search Community

Using timeline, how to expand height from auto to 100% using runtime properties?

jmca test
Moderator Tag

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'm trying to expand an element's height from 'auto' to '100%', and reverse it. By just using `to()` percent height, there's a slight jolt in height due to percent-to-pixel rounding. So in order to circumvent that, there was another post that suggested to predetermine the heights before starting the tween.


The two issues I'm having right now are:

  1. Timeline is compiled ahead of time, but I thought the whole point of a property function was that it was executed during runtime (deferred).
  2. During reverse, I would like to do the opposite, swapping the starting and ending property values, but the property function is not executed during runtime.


What is the method for calculating runtime start values? I saw some posts suggesting to create a new timeline, but that seems heavy handed since one would have to cache the playback position, recreate the timeline, resume from the cached position in reverse, and possible do this multiple times if the user decides to change the window size or hide other elements affecting the height value during other parts of the tween.


Is Timeline at all capable of runtime start values?


Here's an excerpt of the timeline:


let startHeight
let toHeight
return new TimelineLite({paused: true})
    ...other tweens
    .to(this.elSpinnerWrapper, tweenDuration, {...tweenProps, opacity: 0})
    .set(this.elSpinnerAndPickerWrapper, {height: '100%'}) // <--- This is the element to expand/contract
    .call(() => toHeight = this.elSpinnerAndPickerWrapper.offsetHeight)
    .set(this.elSpinnerAndPickerWrapper, {height: 'auto'})
    .call(() => startHeight = this.elSpinnerAndPickerWrapper.offsetHeight)
    .set(this.elSpinnerAndPickerWrapper, {height: startHeight})
    .to(this.elSpinnerAndPickerWrapper, tweenDuration, {...tweenProps, height: () => toHeight})
    // ...other tweens


Any suggestions would be appreciated.


Link to comment
Share on other sites

We had similar question yesterday, where @Carl posted the following solution.




I tried to implement it for height, though there is 1 problem. You still need to record 'auto' height and you can't do that without pausing ongoing animation. You can solve this by using a wrapper, and use height of child as 'auto' height and animate wrapper to expand or shrink.


See the Pen GOaPYK?editors=0010 by Sahil89 (@Sahil89) on CodePen



Another demo with slight adjustments to calculate paused animation.


See the Pen aVrXrb?editors=0010 by Sahil89 (@Sahil89) on CodePen


  • Like 1
Link to comment
Share on other sites

@Sahil I like the idea of `modifiers`. I was looking into that before but I didn't totally understand it's application in this scenario since I thought it was more for snap/clamping points. Looking at your pen, I see your direction. I have to brain-parse your `map()` function a bit so I totally understand it, but I like your idea and it gives me a good jumping off point. Thanks.

Link to comment
Share on other sites

Ya, modifiers plugin gives you access to access calculated value on each frame, it gives you opportunity to modify these values before applying them. You can read more about in docs. It is really powerful feature. Following is thread with countless examples by @OSUblake, he basically requested this plugin and has done a lot of work to demonstrate all the crazy possibilities. 



Again the mapping function is something Blake posted, it lets you map two values in ratio. I am using it to avoid excluding height 'auto' of child element. Here is what happens if you don't use it. If you have played a lot with timelines, progress etc you will quickly understand what is going on.


See the Pen mqZJJy by Sahil89 (@Sahil89) on CodePen


I don't fully understand mapping function either but I can see myself using it a lot in future, if you play with absolute values you will understand what is going on. Blake might explain it in detail once he reads it.


  • Like 2
Link to comment
Share on other sites

Map converts the value in one range to a value in another range. It normalizes the value, converts it to a value usually in the range of [0, 1], and then uses linear interpolation.


For more info about how it works, check out the normalization, linear interpolation, and map videos posted here.



  • 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.
  • Create New...