← All effects

Image Ripple

BackgroundWebGL · zero dependenciesthe shader IS the code
-- fps
prefers-reduced-motion detected — the ripple is shown frozen
click the surface to drop a ripple

X-ray · layers

the wavefront bends the picture as it spreads (off = flat)
a bright crest rides the wave like a glint of light
red and blue split at the crest — a glassy fringe

Parameters

Strength0.70
Wavelength6.0
Speed1.0
Damping0.50
your version · updates as you tinker

How this effect works

This runs on the GPU. Every click adds a ripple to a small list JavaScript keeps — just an (x, y, age) for each. That list is handed to a fragment shader, a tiny program run once for every pixel in parallel. Each pixel measures its distance to every live ripple and works out how far the expanding wavefront has reached it, then nudges the coordinate it reads the picture from. Bend where you sample and the image appears to bend — that's refraction, the same reason a straw looks broken in a glass of water.

The wave itself is a ring: a sine crest wrapped in a narrow envelope that travels outward as the ripple ages, fading by the damping curve. Turn the Ripple layer off and the surface goes flat — proof the whole effect is just that one coordinate nudge. Highlight adds a bright glint on the crest; Chromatic samples red and blue a hair apart so the crest gets a glassy colour fringe. This is the shader-tier promise: a ripple you can take apart — every slider is one uniform, and the Full-code tab is the real GLSL.

Production notes: respects prefers-reduced-motion (one static frame) · falls back to a CSS gradient where WebGL is unavailable · ripples are a fixed-size list, so cost is bounded no matter how fast you click · the shader is fixed and ours; only numeric uniforms and your own click points feed it — never code from a visitor · the copied snippet is self-contained HTML + GLSL + JS.