Liquid Ripple Image

Pro

A photo under simulated water where waves spread, cross and bounce off edges.

canvasimageripplewatersimulationraincursorfull bleed
Liquid Ripple Image component preview

Overview

Liquid Ripple Image is a React and Tailwind CSS water ripple effect over a photo, in Next.js or any React app, with no WebGL. The surface is a height field advanced by the 2D wave equation on a canvas, so ripples spread as rings, interfere where they cross, and bounce off the edges, while each pixel is refracted and lit by the slope. Disturb it with a pointer wake, a stone per press, or rain. It parks when calm, and reduced motion shows a still photo. Serve the photo from your own domain or a CORS enabled host.

Installation

Run the following command

~/your-project
pnpm dlx wensity@latest add liquid-ripple-image

Usage

Import LiquidRippleImage from @/components/wensity/liquid-ripple-image and render it anywhere in your React or Next.js app. The source lands in your own repo, so every prop, class and animation below is yours to edit.

app/example.tsx
import { LiquidRippleImage } from "@/components/wensity/liquid-ripple-image";
export default function Example() {
return (
<LiquidRippleImage
className="h-[560px] w-full"
imageUrl="/images/cover.jpg"
alt="Cover art under moving water"
interaction="hover"
dropRadius={22}
viscosity={0.15}
refraction={60}
shine={0.5}
>
<div className="grid h-full place-items-center text-center text-white">
<h2 className="font-heading text-5xl font-bold">Touch the surface.</h2>
</div>
</LiquidRippleImage>
);
}

Props

PropTypeDefaultDescription
imageUrlstring-Photo under the water. Must be same-origin or CORS-enabled.
altstring-Accessible name. Omit for a purely decorative backdrop.
interaction"hover" | "tap" | "rain""hover"What disturbs the water: a wake behind the pointer, a stone per press, or rain on its own.
dropRadiusnumber22Radius of a single disturbance, in CSS pixels.
impactnumber1Height of every disturbance. Higher throws bigger waves.
viscositynumber0.15How quickly waves lose energy, 0 to 1. 0 rings for a long time.
refractionnumber60How far the slope of the surface bends the photo, in CSS pixels.
shinenumber0.5Strength of the light caught on wave crests, 0 to 1.
rainnumber6Raindrops per second in "rain" mode. Ignored by the other modes.
waveSpeednumber2Simulation steps per frame, 1 to 4. Higher waves travel faster.
resolutionnumber1Render scale against CSS pixels. Lower is softer and cheaper.
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.
pausedbooleanfalseFreeze the water on its current frame.
childrenReact.ReactNode-Content layered above the water.
  • Split-Flap Display component preview

    Split-Flap Display

    A ceramic and graphite split-flap device that ripples each flap into your message.

  • Interactive 3D Globe component preview

    Interactive 3D Globe

    A 3D Earth lit day and night from the real sun position, wrapped in a soft atmosphere, with smooth drag-to-orbit controls.

  • Animated Code Diff Viewer component preview

    Animated Code Diff Viewer

    Inline or toggled code diffs rendered inside the same polished code block frame, flipping between before and after.

  • Animated Terminal component preview

    Animated Terminal

    A terminal UI with self-typing commands, CRT phosphor glow and scanlines, streaming output that never re-renders a line.