We're live on Product Hunt today

Liquid Ripple Image

Pro

Pointer trails bloom into concentric ripples that refract a photo in WebGL.

webglimagerippledistortionrefractioncursorfull bleed
Liquid Ripple Image component preview

Props

PropTypeDefaultDescription
imageUrlstring-Photo the ripples refract. Must be same-origin or CORS-enabled.
altstring-Accessible name. Omit for a purely decorative backdrop.
trigger"hover" | "click" | "both""hover"What lays down ripples.
brushSizenumber150Diameter of a freshly spawned ripple, in CSS pixels.
spreadnumber5How far a ripple grows before it dies, as a multiple of brushSize.
fadenumber3Seconds a ripple takes to fade out.
spacingnumber15Pointer travel between spawns, in CSS pixels. Lower draws a denser trail.
clickStrengthnumber2Size multiplier for a ripple spawned by a click.
strengthnumber0.2Peak refraction offset, in UV units.
swirlnumber1Rotation applied to the refraction, in turns. 0 pushes straight outward.
ringsnumber4Concentric wavefronts inside one ripple.
dispersionnumber0Chromatic split between the red and blue samples. 0 is off.
glintnumber0Specular highlight strength on the wave crests. 0 is off.
highlightColorstring"#ffffff"Hex colour of that highlight.
tintstring"#ffffff"Hex colour pushed into the displaced pixels.
tintAmountnumber0.1How much of tint to push in, 0-1.
grayscalenumber0Desaturation of the whole photo, 0-1.
quality"low" | "medium" | "high""low"Displacement field resolution as a share of the canvas.
maxRipplesnumber100Ripples alive at once. The oldest is recycled past this. Clamped to 200.
fit"cover" | "contain""cover"How the photo maps into the frame, as object-fit would.
backgroundColorstring"transparent"Hex fill behind the photo, or "transparent" to show the page through.
interactivebooleantrueTurn off ripple spawning without unmounting the context.
pausedbooleanfalseFreeze the field on its current frame.
dprnumber-Render scale. Defaults to the device ratio, capped at 2.