Scroll Morph Mask Video
A looping video that never stops playing, seen through a vector mask that scroll morphs from a mark into the letterforms of a word, then zooms through the X to full bleed. Flick and the mask breathes: it inflates, the edge splits cyan and pink, and the footage speeds up.
About This Effect
A video hero where the film keeps playing and scroll changes only the shape you see it through. One real <video> element loops underneath a vector clip-path, and MorphSVG morphs that path along a sequence you author: a small mark, the letterforms of your word, then a zoom straight through one letter until its solid stroke fills the screen and hands off to your headline and call to action. Every frame of that exit is still the real letterform, just closer.
Read the full effect overview
The mask is alive rather than mechanical. At rest it breathes gently. Flick the wheel and it inflates and tilts with your scroll velocity, the edge splits into a cyan and pink fringe, a displacement ripple runs along the cut, and the footage itself speeds up, before the whole thing settles back with an elastic overshoot.
Because the video plays rather than scrubs, it needs no special encoding: any muted, looping MP4 works, and the mask shapes are ordinary SVG paths you can export from Figma or Illustrator.
What's Included
- Real <video> playing continuously under a morphing SVG clip-path (no canvas, no frame sequence, no scrubbed encode)
- MorphSVG morphs through any number of authored shapes in order, then zooms through a point you choose on the last shape to exact full bleed
- Velocity-reactive inflate and tilt with an elastic settle, plus a gentle idle breath so the mask is never static
- Chromatic edge split: cyan and pink echoes clipped by the same mask slide apart with scroll speed
- Footage playbackRate rises with velocity (capped via data attribute) and eases back to real time
- Desktop-only SVG displacement ripple along the mask edge, removed at rest so idle frames cost nothing
- Design-space fitting: shapes authored in one viewBox are centred and scaled to any stage without distortion
- Touch-friendly: the same morph runs on a shorter pin; reduced motion gets a designed still over the poster frame
- Replay button scrolls back to the start of the journey through Lenis when present
Perfect For
- Brand and campaign heroes where a looping film should feel alive rather than scrubbed
- Studio and agency intros that reveal the name in the footage before the page opens up
- Product launches that want an Awwwards-grade scroll moment from one MP4 and one word
- Film, music and event sites with strong motion footage worth showing through type
- Portfolio landings where the mark morphs into the name and then into the work
How It Works
The stage holds three full-size layers, two solid colour echoes and the film, all pointing at one SVG <clipPath> in userSpaceOnUse units. The shapes you author live in a hidden SVG with a design viewBox; on every ScrollTrigger refresh the script measures the stage, computes a contain-fit transform, and writes it onto the clip path together with the live inflate, breath and tilt values, so the word is never stretched and the animation needs no per-breakpoint paths.
A pinned, scrubbed timeline morphs the clip path with MorphSVG from shape to shape using fromTo tweens (so invalidateOnRefresh never re-records a mid-morph start), then zooms the clip path about a point on the last shape (data-mask-zoom) in log space, with the required scale computed on refresh from the farthest stage corner, so the solid stroke covers the stage exactly at the end of the tween. The same timeline pushes the video's scale out slowly, fades the grade layer, and reveals the content.
Scroll velocity from getVelocity() feeds one decaying smear value on the GSAP ticker. That value drives the echo offsets through quickSetter, the video's playbackRate, the feDisplacementMap scale (applied to the layer wrapper only while there is velocity), and a tilt on the clip transform; a hard flick also kicks an inflate value that an elastic tween brings home. Every live channel is multiplied by (1 - bleed) so the full-bleed frame never shows a gap.
gsap.matchMedia splits desktop, touch and reduced motion. Reduced motion sets the word shape on the poster frame with no pin and the content visible; cleanup removes the ticker, the refreshInit listener, the replay handler and the ScrollTrigger, and restores the video's playback rate.