Kinetic SVG Parallax Grid Mask
See the Pen Kinetic SVG Parallax Grid Mask.
Tech & Dependencies
Features
- ✓ Parallax Masking
- ✓ Cursor Tracking
- ✓ Turbulence Filter
Browser Support
Core
This is a Kinetic SVG Parallax Grid Mask. It utilizes mathematical cursor tracking to offset a vectorized masking layer, revealing a secondary layer of animated, stepped shapes beneath. Its function is to create a playful, exploratory spatial interaction that rewards user movement without relying on heavy WebGL contexts.
Specs
- Weight: ~3 KB (Dependencies: GSAP Core).
- Performance: High. The layout operations are offloaded to SVG attributes (
cx,cy,x,y) modified by GSAP, keeping DOM reflows minimal. However, the rapid<feTurbulence>repaints consume some GPU overhead. - Theming / Customization: SVG fills and radii are defined entirely in JS and HTML parameters.
- Responsiveness: Scales seamlessly via SVG
viewBoxcoordinates without relying on CSS media queries. - Web APIs: Pointer Events.
- Graceful Degradation: [!] Complete failure without JavaScript. The screen will render static, overlapping SVG shapes with no interactivity or grid alignment.
Anatomy
- HTML: A single
<svg>element containing a<filter>for shadows, a<mask id="m">, and a grouped<g id="masked">structure housing the colorful circles. - CSS: Extremely sparse. Used only to remove scrollbars, eliminate default margins, and force the SVG to fill the viewport dimensions.
- JS: The logic brain. It dynamically clones DOM nodes to create drop shadows, plots the initial 3x3 layout using modulo math, and loops the
<feTurbulence>seed for a grainy aesthetic. It binds toonpointermoveto calculate wrapped, interpolated positional offsets for both the mask and background elements.
Logic
The standout mechanism is the continuous generation of “noisy” shadows combined with GSAP’s native value wrapping utility.
// animate the noise in the drop shadows
gsap.to(window, {duration:0.2, repeat:-1, onRepeat:()=>{
gsap.set('feTurbulence', { attr:{seed:Math.ceil( Math.random()*99 )} })
}})
// inside the pointermove mapping...
x:(i)=>{
const n = gsap.utils.wrapYoyo(0, 0.5, e.x/innerWidth)
return gsap.utils.interpolate(0, 400-i%3*400, n)
}
Instead of using static drop shadows, the code rapidly alters the seed of an SVG <feTurbulence> filter every 200ms, creating a boiling, film-grain texture on the shadows. For movement, it calculates the normalized mouse position and utilizes gsap.utils.wrapYoyo along with interpolate to seamlessly push and pull the mask coordinates across an elastic, bounded range.
Feel
Fluid and mechanical. The stepped, vertical bouncing of the foreground shapes contrasts with the smooth, elastic horizontal and vertical panning of the grid mask. The boiling, grainy shadows give the vector graphics a raw, tactile paper-cutout feel, bridging the gap between digital precision and analog imperfections.


