Skip to main content

Overview

LiquidWave runs a real-time fluid simulation on a WebGL canvas using Three.js — computing advection, divergence, pressure, and viscosity passes every frame. Mouse movement injects force vectors into the fluid, creating organic wave trails. When idle, an autonomous demo driver animates the fluid automatically.
This component is designed as a full-bleed background container. Set its parent to position: relative with an explicit width and height (e.g. 100vw / 100vh). The canvas fills its container automatically.

Installation

npx rareui@latest add liquid-wave
Requires three as a peer dependency.
npm install three

Usage

import LiquidWave from "@/components/rareui/interactive-background/LiquidWave";

export default function HeroBackground() {
  return (
    <div style={{ width: "100%", height: "100vh", position: "relative" }}>
      <LiquidWave />
      {/* Your content layered on top */}
    </div>
  );
}

Props

color1
string
default:"orange"
Primary fluid color. Accepts any valid CSS color string ("#5227FF", "rgb(100,200,255)", named colors).
color2
string
default:"orange"
Secondary fluid color blended into the palette gradient.
color3
string
default:"orange"
Tertiary fluid color for a richer multi-tone gradient effect.
mouseForce
number
default:"20"
Strength of force injected at the cursor position. Range 0100; higher values create more dramatic wave displacement.
cursorSize
number
default:"100"
Radius of the force injection area around the cursor in simulation units.
isViscous
boolean
default:"false"
Enables viscous fluid behavior. When true, a viscosity diffusion pass is applied each frame.
viscous
number
default:"30"
Viscosity coefficient used when isViscous is true. Higher values produce thicker, slower-moving fluid.
iterationsViscous
number
default:"32"
Number of Jacobi iterations for the viscosity solver. More iterations increase accuracy at a performance cost.
iterationsPoisson
number
default:"32"
Number of Jacobi iterations for the pressure (Poisson) solver.
dt
number
default:"0.014"
Simulation time step per frame. Smaller values increase stability; larger values speed up the simulation.
BFECC
boolean
default:"true"
Enables Back and Forth Error Compensation and Correction advection for improved numerical stability and detail.
resolution
number
default:"0.5"
Simulation resolution as a fraction of canvas size (0.11.0). Higher values are sharper but more GPU-intensive.
isBounce
boolean
default:"false"
When true, fluid velocity reflects off the boundary walls instead of dissipating.
autoDemo
boolean
default:"true"
Enables the autonomous movement driver that animates the fluid when the user is idle.
autoSpeed
number
default:"0.5"
Movement speed of the autonomous demo cursor in normalized units per second.
autoIntensity
number
default:"2.2"
Force multiplier applied to the autonomous demo movement.
takeoverDuration
number
default:"0.25"
Duration in seconds for the smooth takeover transition when the user resumes control from auto-demo.
autoResumeDelay
number
default:"3000"
Milliseconds of user inactivity before the autonomous demo driver resumes.
autoRampDuration
number
default:"0.6"
Duration in seconds for the auto-demo speed ramp-up on activation.
style
React.CSSProperties
Inline styles applied to the mount container div.
className
string
Additional CSS classes applied to the container.

Examples

Custom color palette

<LiquidWave
  color1="#5227FF"
  color2="#FF9FFC"
  color3="#B19EEF"
/>

High-force interaction

<LiquidWave
  mouseForce={30}
  cursorSize={150}
/>

Viscous fluid

<LiquidWave
  isViscous={true}
  viscous={50}
  iterationsViscous={64}
/>

Features

Real Fluid Simulation

Runs advection, divergence, pressure, and optional viscosity passes on the GPU every frame using Three.js WebGL.

Multi-Color Gradients

Three color stops are sampled from a dynamically generated palette texture for fluid color rendering.

Auto-Demo Mode

An autonomous cursor driver keeps the fluid animated when the user is idle, resuming gracefully on interaction.

Visibility Optimization

Uses IntersectionObserver and document.visibilitychange to pause the render loop when off-screen or hidden.

Build docs developers (and LLMs) love