I think probably the hardest – and definitely the most stressful – problem of my professional career was implementing a complex scroll animation for a freelance client’s homepage. Technically, it wasn’t a single problem, but a whole project, with many problems.

The client was originally inspired by this site: https://atintell.com/. So I decided to look at that site to see if I could figure out how they accomplished their scroll animation, and follow their lead. I noticed that they were using a JavaScript library called ScrollMagic, so that’s what I used for my client’s site.

ScrollMagic essentially works by freezing certain elements on the page (via fixed positioning), and then moving other elements around on the page (via absolute positioning) while you scroll. As far as your browser is concerned, you really are just scrolling as usual. But because the ScrollMagic script has frozen certain elements on your screen, and is moving other elements horizontally (or however you choose), it looks like the browser is literally scrolling in different directions.

These are pretty clever concepts. But I also found them to be very unintuitive at first.

My client had been inspired by the example site I linked to above. But the animations they wanted me to build were a little different.

The first animation they wanted was a horizontal scroll, with content entering onscreen from the right – similar to the example site. But rather than a continuous scroll, they wanted to gently “snap” to each new section, so that one “slide” would always be centered in the viewport. And there was another animation that looked kind of like a deck of cards. As you scrolled down, the current “card” would stay in place, and another “card” would slide on top of it from the bottom of the screen. My client changed their homepage a couple months ago, so unfortunately I can’t just link to the page – hopefully those descriptions make sense!

Both animations had several challenges, but I’ll focus on the first animation here.

What proved very difficult with this animation was getting the viewport to snap to the right positions, smoothly, at the right times. Technically, what I needed to do was the following:

1. Establish canonical y-coordinate scroll positions for each slide I needed to potentially snap to.

2. Listen for a ‘scroll’ event, and check the current ‘y’ position.

3. Wait a split second, and check the ‘y’ position again, so that I could see how fast, and in which direction – up or down – it was scrolling.

4. Calculate, based on the speed, direction, and current position, whether we should snap to the next canonical slide position or re-center to the previous canonical slide position.

There was fuzziness to all of this. Different thresholds for how long to wait between y-coordinate samplings, and for what speeds and locations (e.g. distances from the canonical positions) to trigger a “snap”, had wildly different results. Some configurations would not trigger a snap at all. Others would snap you all the way to the last slide. Or would get you stuck on one slide, and prevent you from scrolling anywhere else on the site. Or would snap, not to a slide, but to seemingly random points between the slides.

This last problem was the hardest to resolve, and I don’t remember exactly how I solved it. But I know the issue was the result of me incorrectly calculating the canonical slide positions. And the solution had to do with better understanding how ScrollMagic mapped y-coordinates in the browser to “moments” in its animation.

Ultimately, I was able to build a working solution by breaking each part into very small pieces, and through LOTS of trial and error. I also had to figure all of this out in just a couple of days – and it just turned out that there was a lot more for me to learn than I expected when I initially took on the project. The complexity, steep learning curve, and lack of time to learn it, were what made this the hardest project I ever worked on.