jlmakes / scrollreveal

Animate elements as they scroll into view.
https://scrollrevealjs.org/
22.39k stars 2.26k forks source link

Centered elements using transform #500

Closed evoactivity closed 5 years ago

evoactivity commented 5 years ago

https://jsbin.com/yalacogiyu/edit?html,js,output

The blue box should show the moment it's first pixel is in the viewport but because of the top: 50% it seems scroll reveal is thinking it's not in the viewport until half of it is. Seems the negative transform is not accounted for in viewport calculations?

Environment

jlmakes commented 5 years ago

You're right, the element's true position is used instead of its transformed position.

This is actually by design, because otherwise element reveal animations themselves throw off geometry calculations. For example, if we did honor transformed positions, and we were to write code like this:

reveal(el, { origin: 'right', distance: '500px' })
reveal(el, { origin: 'right', distance: '500px' })
reveal(el, { origin: 'right', distance: '500px' })

Each call to reveal takes the current/transformed position and transforms it again. Our el would be 1500 pixels off from its true position. What's more, it's possible that this element would never be considered visible because its transformed position is off screen!

ScrollReveal also recalculates element position on window resize events, which could happen in the middle of a reveal animation. The el transformed position captured in this case is even weirder.


I really tried to get around this in ScrollReveal 3, because APIs like el.getBoundingClientRect() and IntersectionObserver are really nice, but all factor in transformed position and lead to the issues I described above.

In an effort to improve things, ScrollReveal 4 leverages Rematrix to preserve transforms, so while the animation is triggered at the "wrong" time — your element does retains its transform and remains vertically center after it reveals.

Maybe I’ll crack this egg for ScrollReveal 5 :)

P.S.

I wanted to mention that the centering technique you are using causes elements with odd height values to render on a sub‑pixel, which blurs the element/content. For example, an element with height 101px is rendered 50.5px above its true position.

You can avoid this problem (and ScrollReveal’s behavior as outlined above) by centering your element using Flexbox, which is supported by nearly 99% of all browsers.

Best of luck!