Sign in
Log inSign up
Destructuring Scroll Animations :: Array of solutions

Destructuring Scroll Animations :: Array of solutions

ughhh, I hate absolute positioning

Aman Tulsyan's photo
Aman Tulsyan
·Jun 19, 2022·

5 min read

Animations are cool,

While it may be difficult to implement, I think it is necessary skill to have in order to be good at frontend interactions.

Let's destructure the most common one: Scroll Animations


Desired Outcome

Now you must have seen this awesome, apple site, if not do check this out, Apple surely doesn't disappoint.

Apple Website

At this point it is not wrong to think that apple and good design are synonyms, but I want you guys to zoom out a bit.

Let's talk about outcomes,

As a frontend engineer, my job is to make your life easier by creating better experiences, Interaction of a user with the product is what matters the most. Maximizing on these metrics is one way of contributing towards shaping the habitat we now call as the Internet.

To have an end goal in mind is surely very useful while doing anything in web, and thus my adventure with web animations.


Approaches

There are multiple ways of animating web components, among which I tried a handful, namely:

  1. CSS Animations (transform property to be very specific)
  2. Intersection Observer( Browser API)
  3. Third party Libraries and Packages
  4. React Framer Motion (why not? abstractions are the way to go)

Let me walk through all these egg shells to give you a mental picture of how I achieved my desired outcome


CSS Animations

First Solution

General Concept:

  1. Converting the Hero section into a canvas with large enough height, so as to allow enough scrolling bandwidth for us to play around

  2. Creating a Function that returns image file path, depending on the index Value passed

  3. Tracking user scroll progress and multiplying it with the number of Images we have to generate frames

  4. Updating the canvas with different images as the user scrolls based on the scroll position

It correctly tracks the scroll progress, which is something I needed in order to scale Images, but the fundamental idea behind this is very different from what I wanted, which was to scale images on the basis of scroll progress.

Second Solution

General Concept:

  1. Tracking the scroll position and converting it into an css custom property
 const onScroll = () => {
      document.body.style.setProperty(
        "--scroll",
        (
          window.pageYOffset /
          (document.body.offsetHeight - window.innerHeight)
        ).toString()
      );


  window.addEventListener("scroll", onScroll, false);
  1. Using CSS animation keyframe, to delay the motion of animation on the basis of scroll value.

I did use this solution to track the scroll position but parted ways with the rest of the logic, though it seemed pretty solid but this is the major issue I faced

  1. Scaling Images gradually, as I was just oscillating between the initial scale and final scale.

After dabbling around with CSS transform properties and animation keyframes, I stumbled upon Intersection Observer.


Intersection Observer

Intersection Observer is a browser api which helps in asynchronous observation of various sections, this is the most efficient solution for animations involving different sections but since the positioning of my Images were not that far from each other it was quite unhelpful in the core aspect.


Third party Libraries

Screenshot (346).png

Welcome to the npmverse of packages, a world where repetitive solutions are in abundance.

As you can see I had 132 other alternatives to try out for my particular use case but, there are some issues which comes with these go to solutions

  1. Most of the packages are not maintained anymore which makes my application very fragile if I depend on them.

  2. Most of the packages are intended for a certain set of use cases and I didn't had the bandwidth to try each one of them out.

  3. I find it to be a good idea in general to have minimum dependencies in my applications, makes them more robust and less error prone.

Abstractions are great but, wasting too much time on too many abstractions is like picking a needle in from the haystack


React Framer Motion

React framer motion is the most popular abstraction in the react ecosystem for animations on web,

While framer motion has certain set of out of the box features for scroll based animations,

Scroll-linked animations

I used a tiny portion of it's capabilities to achieve what I wanted.

i.e., Images disappearing after a certain scroll height

  <motion.div
        animate={{ opacity: scrollValue > 36 ? 0 : 1 }}
      >
        <ImageComponent
          scrollVal={scrollValue}
          imgSrc="images.unsplash.com/photo-1535223289827-42…"
          width={612}
          height={612}
          cName="fixed top-0 right-0 "
        />
  </motion.div>

animate is a framer motion property, which helps us in controlling the opacity of the Image elements, which would have been a little lengthier with CSS


Remixing all the solutions

Now that I had a way to track scroll progress and make images disappear after a certain scroll height the only thing left was to position images and scale them according to the scroll value, which was a fairly simple task.

 style={{
          transform: `scale(${
            scrollVal * 0.2 > 1 ? 1 : scrollVal * 0.2 + 0.02
          })`,
        }}

Conclusion

Oftentimes there are no clear solutions, the best solution in such cases is to create one of your own by remixing others.

The animation is still janky, but it's good to have a rough path.

This task was a part of my first internship at Hallparty, I was uncomfortable in the beginning but learned a lot of things ++ received a lot of help from the hallparty team especially Kush in reaching to the desired solution

Hassle-free blogging platform that developers and teams love.
  • Docs by Hashnode
    New
  • Blogs
  • AI Markdown Editor
  • GraphQL APIs
  • Open source Starter-kit

© Hashnode 2024 — LinearBytes Inc.

Privacy PolicyTermsCode of Conduct