Skip to content
WANCRAFT

E.79Backgrounds & Effects

Water Ripple

A refractive water surface: pointer and raindrops send ripples across a tinted, tiled pool.

NewReactCanvasTailwindadvanced

Overview

Water Ripple runs the classic two-buffer height-map simulation at a reduced resolution and upscales it with smoothing onto a DPR-aware canvas. Every frame, the slope of the surface refracts a background buffer (a theme-aware tinted gradient with an optional tile floor, or an image you pass in) and adds specular light from the top-left. Moving the pointer trails soft wakes, clicks and taps drop bigger ripples, and optional raindrops keep the pool alive. The loop runs at a fixed 60Hz step, sleeps when the water is calm, offscreen or in a hidden tab, and reduced motion renders a still surface.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/water-ripple.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/water-ripple.json

Method 02 · Copy and paste

  1. 1. No extra dependencies — React and Tailwind CSS only.
  2. 2. Copy the source from the Code tab into components/ui/water-ripple.tsx.
  3. 3. Import it and adjust props.
Dependencies
None
Peer
react ≥ 18, tailwindcss ≥ 4
Added
13 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { WaterRipple } from "@/components/ui/water-ripple";

export function WaterRippleExample() {
  return (
    <div className="relative h-80 w-full overflow-hidden rounded-xl">
      <WaterRipple />
    </div>
  );
}

03Props

PropTypeDefaultDescription
dampingnumber0.975Energy kept per simulation step (clamped to 0.9–0.995).
resolutionnumber0.25Simulation cells per CSS pixel (0.1–0.5). Capped at 160k cells.
dropRadiusnumber14Radius of a click/tap drop in CSS px; pointer wakes use 60% of it.
refractionnumber22Background displacement per unit of surface slope, in CSS px.
rainbooleantrueIdle raindrops every 0.35–1.45s.
pattern"tiles" | "plain""tiles"Procedural floor drawn beneath the water when no src is given.
colorstring"#B6F3D1"Water tint (any CSS colour), mixed toward the theme's background.
highlightstring"#FFFFFF"Specular highlight colour.
srcstring—Optional image to refract instead of the gradient. Must be same-origin or served with CORS.
interactivebooleantrueDrop ripples on pointer move (mouse/pen), click and tap.
childrenReactNode—Optional content layered above the water.
...propsHTMLAttributes<HTMLDivElement>—Forwarded to the root, which is absolute inset-0 — place it inside a positioned parent.

04Features

  • 01Two-buffer height-map wave simulation at reduced resolution, smoothly upscaled
  • 02Slope-based refraction of a gradient, tile floor or image, plus specular light
  • 03Pointer wakes, click/tap drops and optional idle raindrops
  • 04Theme-aware palette derived from a single tint colour
  • 05Fixed 60Hz step; the loop sleeps when calm, offscreen or in hidden tabs
  • 06DPR-aware canvas (capped at 2) with ResizeObserver
motion · continuousinput · pointerinput · clickinput · viewport

05Accessibility

  • The canvas is aria-hidden and ignores pointer events; layered content stays fully interactive.
  • prefers-reduced-motion renders a single still surface and disables pointer ripples.
  • Only mouse and pen movement makes wakes; touch only drops a ripple on tap, so scrolling is never hijacked.
  • Purely decorative: no information is conveyed by the water.

06Limitations

  • Images are sampled at simulation resolution, so they appear softened; raise resolution for sharper images.
  • Cross-origin images without CORS cannot be read, so the gradient is used instead.