Skip to content
Free for Aperveil 1.0 WebGPU shader

Water Ripple: Touch the water.

An interactive water ripple background for React: rain rings and the cursor's wake spread over clear water, refracting the floor or your own image, rendered live in WebGPU.

Part of the Free collection for Aperveil 1.0. Public live preview and Color Looks are open. Free Export Kits do not require an account. Purchasing is not available yet.

Color Looks

Free for Aperveil 1.0React · Vue · HTML · WordPress · FramerRaw WGSL

Inside Water Ripple.

Water Ripple is clear water seen from above, over a pale stone floor or over an image or video you choose. Every ring is a capillary wave packet, the kind a raindrop makes on a puddle: two to four crests that widen as they travel, the short ones running ahead, fading within a second and a half. Drops fall on their own, the cursor leaves a wake as it moves and a drop where it arrives, and because the waves are linear they simply add up where they meet. You see them the way you see real ripples: the floor bends beneath them, a low sun glints on their slopes, and a slow swell focuses a net of caustic light on the floor that every ring lenses as it passes.

Water Ripple draws its own water over a stone floor or one image or video you choose; it cannot ripple the live HTML of your page, and its waves do not reflect off the edges of the frame. A click is not a separate drop: the cursor's path and its arrival are what touch the water.

2.884 ms GPU timestamp median; p95 3.473 ms. 1440x900 @ dpr 1.25; Apple M2 (8-core GPU), Metal driver on macOS Version 26.6.2 (Build 25G83); measured 2026-10-22. This is a recorded headless sample, not a browser FPS or mobile-performance guarantee.

Ripple size

Wavelength and travel of every ring and swell. Larger reads as a closer view.

Strength

How steep the waves are: more refraction, brighter glints, sharper caustics.

Depth

How far below the floor lies. Deeper water bends the floor further, tints it more and focuses the caustics.

Caustics

The net of focused sunlight on the floor.

Color Looks preserve these settings. Open the editor for all 15 controls.

From preview to your project.

Choose a Look, tune it in the editor, then download the Export Kit. Install the runtime and copy the generated component into your project.

Every control in the editor is a typed prop. Leave a prop out to keep the value you exported; change one and the running shader updates without restarting. Give the surface a size and pass fallback for browsers without WebGPU.

The component is already marked "use client": in Next.js, import it into any page or layout and give its container an explicit size. Keep headings, links and accessible content in HTML above the decorative canvas.

Part of the Free collection for Aperveil 1.0. Public live preview and Color Looks are open. Free Export Kits do not require an account. Purchasing is not available yet.

Open editor & export
Markdown guide

Usage example — download WaterRipple.tsx from the editor first. This example imports that local file; it is not the shader component itself.

Terminal
npx @aperveil/cli add shader water-ripple --framework react
WaterRipple usage
"use client";

import WaterRipple from "./components/aperveil/water-ripple/WaterRipple";

export default function Hero() {
  return (
    <WaterRipple
      className="hero-shader"
      src="/videos/your-clip.mp4" scale={1} waterColor="#06b2e0"
      fallback={<div className="hero-shader-fallback" />}
    />
  );
}

// .hero-shader { width: 100%; height: 560px; }

Add it with npx @aperveil/cli add shader water-ripple, or download the Export Kit from the editor and copy the component into your project.

Usage example for vue/WaterRipple.vue from the Export Kit. Vue 3.5 or newer, Nuxt included: it renders an empty canvas on the server and starts in the browser, so it needs no <ClientOnly>.

Terminal
npx @aperveil/cli add shader water-ripple --framework vue
WaterRipple usage
<script setup lang="ts">
import WaterRipple from "./components/aperveil/water-ripple/vue/WaterRipple.vue";
</script>

<template>
  <WaterRipple class="hero-shader" src="/videos/your-clip.mp4" :scale="1" water-color="#06b2e0">
    <template #fallback><div class="hero-shader-fallback" /></template>
  </WaterRipple>
</template>

<!-- .hero-shader { width: 100%; height: 560px; } -->

Same props and values as the React component.

Usage example for html/aperveil-water-ripple.js from the Export Kit. No install and no build step: keep the two files of the kit's html folder together.

index.html
<script type="module" src="./aperveil-water-ripple.js"></script>

<aperveil-water-ripple class="hero-shader" src="/videos/your-clip.mp4" scale="1" water-color="#06b2e0">
  <div slot="fallback" class="hero-shader-fallback"></div>
</aperveil-water-ripple>

<style>
  .hero-shader { display: block; width: 100%; height: 560px; }
</style>

Same props and values as the React component.

Download aperveil-shader-water-ripple.zip from the editor: Install, then WordPress. WordPress 6.5 or newer: a plugin with a block that holds your own content in front of the shader, and a shortcode for page builders.

Shortcode
[aperveil_water_ripple height="560px" overlay="20" src="https://example.com/your-clip.mp4"]
  <h2>Your headline</h2>
  <p>Your text, in front of the shader.</p>
[/aperveil_water_ripple]

The values you choose in the editor are baked into the plugin.

Copy WaterRipple.tsx from the editor: Install, then Framer. It opens on the values you chose.

  1. In Framer, open Assets, then Code, and add a new code file named WaterRipple.
  2. Replace its sample code with your copy and save.
  3. Drag Water Ripple onto the canvas. Its Color Looks and every control are in the property panel.

The same controls as the React component, in Framer's panel. Framer guide

waterColor · `#${string}` = "#06b2e0"
Water. The color the water takes on with depth, and scatters back. Accepts #RRGGBB.
floorColor · `#${string}` = "#f4ead6"
Floor. The stone floor under the water. Hidden when an image or video is chosen. Accepts #RRGGBB.
lightColor · `#${string}` = "#fff1cc"
Sunlight. The sun's glint on the ripples and the caustic light on the floor. Accepts #RRGGBB.
skyColor · `#${string}` = "#9fdcff"
Sky. The sky the slopes of each ring reflect. Accepts #RRGGBB.
scale · number = 1
Ripple size. Wavelength and travel of every ring and swell. Larger reads as a closer view. Accepts 0.4–2.5, step 0.01.
strength · number = 1
Strength. How steep the waves are: more refraction, brighter glints, sharper caustics. Accepts 0–2.5, step 0.01.
depth · number = 0.7
Depth. How far below the floor lies. Deeper water bends the floor further, tints it more and focuses the caustics. Accepts 0–2, step 0.01.
caustics · number = 0.8
Caustics. The net of focused sunlight on the floor. Accepts 0–2, step 0.01.
swell · number = 0.7
Swell. A slow swell from several directions, which draws the caustic net. Accepts 0–2, step 0.01.
rain · number = 0.25
Rain. How often drops fall on their own. Zero leaves only the cursor. Accepts 0–1, step 0.01.
gloss · number = 1
Gloss. Sky and sun reflected in the slopes of the waves. Accepts 0–2, step 0.01.
flowSpeed · number = 1
Speed of the swell and the rain. Accepts 0–3, step 0.01.
interaction · number = 1
Touch. How much water the cursor moves: its wake, and the drop where it arrives. Accepts 0–2, step 0.01.
tailLength · number = 4
Wake length. How long the cursor's wake keeps spreading after it passes. Accepts 0–4, step 0.05.
opacity · number = 1
Opacity of the whole effect over the page. Accepts 0–1, step 0.01.
src · string
The video or image it plays. A URL to an MP4, WebM, MOV, JPG, PNG or WebP, on your own site or on a server that allows it (CORS). Left out, it plays its own clip; an empty string shows its own scene.
mediaFocus · readonly [number, number]
Where the subject sits. Its place in the picture, from the top left, kept in view when the picture is cropped to fill. Accepts 0–1 for each.
mediaKind · "video" | "image"
Video or image. Only needed when the URL does not end in a file extension. Accepts "video" or "image".
className · string
Size and place the surface. The canvas fills this box, so give it a width and a height.
style · CSSProperties
Inline styles for the surface box.
paused · boolean = false
Holds the current frame. Use it for a pause control or for sections scrolled out of view.
fallback · ReactNode = null
Shown instead of the canvas without WebGPU. Also shown if rendering fails. A poster image or a CSS gradient works well.
onReady · () => void
The first frame has been drawn.
onError · (error: unknown) => void
Rendering failed; the fallback is shown.

Every prop is optional. Numbers are clamped to their range; an invalid value keeps the default.

Made for a real interface.

Give a spa, a swimming school, a summer campaign or a calm product launch a surface that answers the visitor: the hero stays readable over still water, and every move of the cursor sets rings running under the heading.

Water Ripple used behind an example interface
TIDEWELLExample composition

Thermal baths

Still water, warm stone.

An illustrative spa front page over clear, rippling water.

Pools

Indoor, outdoor, cold plunge

Open

Daily, 7 to 22

Illustrative layout, not a customer project. The image is a still preview of the selected Look.

An illustrative layout. Your content stays in HTML; the shader sets the atmosphere.

Try this surface in the editor

Before you ship.

What this surface does, where it fits, and where it stops.

Yes. Choose an image or video in the editor, or pass one to the component: it lies under the water and every ring refracts it. Depth and the water color set how much the water tints it.

It does the same job without a simulation texture: each ring is a capillary wave packet computed in closed form, so drops, the cursor's wake and the swell add up exactly, in WebGPU, with caustics on the floor and the sun's glint on the waves.

Yes. Rain sets how often drops fall without the cursor, and zero leaves only the cursor's touch. Swell draws the slow caustic net on the floor; Caustics sets how bright it is.

This landing shows a still poster of your selected Color Look. The raw WGSL needs a WebGPU host. Landing posters are not bundled in the Export Kit: add your own fallback around the exported component.

Part of the Free collection for Aperveil 1.0. Public live preview and Color Looks are open. Free Export Kits do not require an account. Purchasing is not available yet. Follow the license notices supplied with the source you download. The planned Free collection permits personal and commercial interface projects.
All water & fluid shaders

Make Water Ripple yours.

Open editor