Jump to content
Search Community

Best approach for animating width utilizing TimelineMax?

jodriscoll 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

Hi all! 

I'm working on finding the "best way" to approach animating the width of an object using the current implementation of GSAP TimelineMax paired with ScrollMagic: 

 

As most of you may know, animating the width of an element does not leverage the GPU, causing a reflow of the DOM, which is bad for performance, can break with bad JavaScript, reduces the 60hz/fps target, etc., etc. Unfortunately, I noticed the way the TimelineMax animates an object's property is through transform: matrix3d(). Which in turn, prevents the explicit usage/designation of transform: scaleX() to alter the width to/from through the TimelineMax().to properties.

 

A summarized snippet of where I'm managing this configuration can be seen below:

 

// ...

const ScrollLines = new TimelineMax()
.to( animate.down, 1, {
  x:            animate.neg,
  y:            animate.pos,
  width:        0,
  repeat:       1.25,
  ease:         Sine.easeOut,
  yoyoEase:     true
}, "together" )
.to( animate.up, 1, {
  x:            animate.pos,
  y:            animate.neg,
  width:        0,
  repeat:       1.25,
  ease:         Sine.easeOut,
  yoyoEase:     true
}, "together");

// ...

 

Actual question: Is there a way to alter the width of an element while still utilizing the core matrix3d calculation in TimelineMax?

 

You can see the current implementation of this animation on youcanwa.org, or view the demonstration here. Any suggestions or help would be much appreciated!

See the Pen PRPmem by jodriscoll (@jodriscoll) on CodePen

Link to comment
Share on other sites

14 minutes ago, jodriscoll said:

As most of you may know, animating the width of an element does not leverage the GPU, causing a reflow of the DOM, which is bad for performance,

 

I hope you realize that getting the scroll position causes a reflow, so using ScrollMagic can negate some of those benfits. ?

https://gist.github.com/paulirish/5d52fb081b3570c81e3a

 

And scaling isn't as optimized as most people like to think. The browser can rasterize the content, limiting the amount of scaling you can do before it starts looking like crap, or it can repaint the content on every animation frame. Using will-change will cause rasterization. 

https://greensock.com/will-change

https://dassur.ma/things/forcing-layers/

 

To scale x, simply scaleX.

 

.to( animate.down, 1, {
  x:            animate.neg,
  y:            animate.pos,
  scaleX:        0,
  repeat:       1.25,
  ease:         Sine.easeOut,
  yoyoEase:     true
}, "together" )

 

 

To prevent squashing/stretching of children during a scale animation, you can apply a counter scale. 

 

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

 

 

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

 

  • Like 4
Link to comment
Share on other sites

4 minutes ago, OSUblake said:

 

I hope you realize that getting the scroll position causes a reflow, so using ScrollMagic can negate some of those benfits. ?

https://gist.github.com/paulirish/5d52fb081b3570c81e3a

 

Baby steps, but I am aware and it's something on my list of pursuing for additional improvements as well. If you have any recommendations, I'm all ears :)

 

I've implemented the approach you suggested and noticed that any property which can be managed through matrix3d() is combined into a single definition, which I was unaware of until now! Thanks for the recommendation and I'm already noticing an improvement in the scrolling experience.

  • Like 1
Link to comment
Share on other sites

17 minutes ago, jodriscoll said:

Baby steps, but I am aware and it's something on my list of pursuing for additional improvements as well. If you have any recommendations, I'm all ears :)

 

You can use the intersection observer for scrolling, and there are polyfills for IE and Safari. It's asynchronous, so some of your code might be deferred under heavy load, but performance should generally be better. 

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

 

 

17 minutes ago, jodriscoll said:

I've implemented the approach you suggested and noticed that any property which can be managed through matrix3d() is combined into a single definition, which I was unaware of until now! Thanks for the recommendation and I'm already noticing an improvement in the scrolling experience.

 

Yes, check out the docs for the CSSPlugin. That's where most of the magic happens if you're animating the DOM.

https://greensock.com/docs/Plugins/CSSPlugin

 

Also, using CSS Containment can help with reflows/repaints, but browser support isn't that good at the moment.

https://developer.mozilla.org/en-US/docs/Web/CSS/contain

  • Like 5
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...