Start a project
Writing
Scroll-driven video in Webflow, and the four things that break
I wanted 3D letters flying at the screen on scroll, the way that North Face ad does it. Getting the animation was the easy half. Getting a browser to scrub a video frame by frame, at a quality worth looking at, took three dead ends and a specific encode.
Two of the three obvious routes in Webflow do not work for this, and neither fails in a way that tells you why. Writing down where each one stops, and what the working version actually needs, is most of the value in this post.
Building the animation
The text was set in Illustrator in Bubblegum from dafont, then expanded so it could leave as an SVG and come into Blender as real geometry rather than a font reference.
The inflated look is cloth physics with collisions. The letters start slightly ahead of the logo outline, so they expand into the shape before they fly forward. That offset matters: with the text sitting inside the outline it gets absorbed instead of inflating, which took a while to diagnose and is fixed by raising the collision’s outer thickness.
Rendered as a PNG sequence with alpha, taken into After Effects for a white background, and exported to mp4.




Dead end one: the background video element
The first attempt did not even reach the scrolling part. Webflow’s background video element compresses hard, and at full width the result is not worth shipping. This is not a setting you have missed. The compression is applied on upload and there is no way around it from inside Webflow.

Dead end two: Lottie
Lottie handles scroll-linked playback properly and Webflow supports it directly, so this looked like the answer. The problem is file size. Anything past 15 to 20MB is already too heavy to serve, and this animation came out at 45MB after compression. A JSON file is the wrong container for something with this much per-frame detail.
What worked, and the encode it needs
The working approach scrubs a real video file against scroll position with GSAP and ScrollTrigger. There is a Codepen by Shaw that does exactly this, and the important part is buried in its comments: the video has to be encoded for it, or seeking is not frame-accurate and the scrub stutters.
That means FFMPEG. The flags that matter are -movflags faststart, so playback can begin before the whole file arrives, and -g 1, which makes every frame a keyframe so any frame can be sought directly. On Windows, add the FFMPEG bin folder to the Path system variable first, or the command is not found.
ffmpeg -i "D:/test/whitebg-1080p.mp4" -vf scale=1920:1080 -movflags faststart -vcodec libx264 -crf 20 -g 1 -pix_fmt yuv420p "D:/test/output.mp4"Quote both paths and keep them short. Editing the Codepen’s own command in place, with an unquoted path and the directory split from the filename, is what was throwing errors.


Two more failures worth knowing about
With the encoded file on Dropbox the video still would not render. A Dropbox share link ends in dl=0, which serves a preview page rather than the file. Changing it to raw=1 serves the file itself and the element starts working.
Then the script threw an error on currentSrc being null. The Codepen JS uses querySelector to find the video, and placing that script in the page head means it runs before the element it is looking for exists. Moving the script into the same HTML embed, after the video element, fixes it. GSAP and ScrollTrigger have to load ahead of it.
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/ScrollTrigger.min.js"></script>Both of these load before the Codepen script, not after it.

The result
This is the finished thing, running on the old palle.ca homepage. The letters inflate into the mark and fly at the screen, and every frame of it is tied to scroll position rather than to a clock.
Where it still falls short
Dropbox is the weak link. It serves the file, but not at a quality that does the render justice, and it is not meant to be a video host. Vimeo was the obvious alternative and appears to re-encode on upload, which undoes the FFMPEG work the whole technique depends on. Somewhere that serves the exact bytes you uploaded is what this needs, and that generally costs money.
