# Liquid Fill Reveal

> A scroll-scrubbed liquid fills a frame behind your content, with a simulated wave surface that sloshes on a fast scroll and inverts everything below the waterline.

Canonical: https://gsapvault.com/effects/liquid-fill-reveal
Live demo: https://gsapvault.com/demos/liquid-fill-reveal/index.html

| Property | Value |
|----------|-------|
| Type | effect |
| Tier | paid |
| Price | £5 |
| Difficulty | advanced |
| Plugins | ScrollTrigger |
| Techniques | scrub, pinning, canvas, clip-path, velocity-reactive, physics, fluid-surface |
| Uses Lenis | Yes |

## Overview

A scroll-scrubbed liquid that fills a frame behind your own markup, with a surface that behaves like water rather than a moving line. Fill height follows scroll position. The wave on top follows scroll speed, so a slow read keeps the surface level while a hard flick tilts the whole body against the walls and sends it rolling back.

Everything below the waterline switches to the submerged colour scheme and shears with the surface tilt, which is what sells the fluid as something the page is sitting in rather than a shape drawn over it. The boundary is a live clip-path built from the same samples the fluid is drawn from, so the colour changes exactly at the wave.

Your content stays real DOM throughout. Headings, links and buttons are yours to write and style; the effect copies them into an inert layer instead of redrawing them on canvas.

## Features

- Height-field water surface: 48 coupled spring columns trade height with their neighbours each frame, so an impulse at the wall travels across the tank and reflects
- Scroll position drives the fill and scroll speed drives the wave, so one gesture produces two separate readings
- Live clip-path polygon built from the same samples as the drawn fluid, which puts the colour boundary on the wave itself rather than near it
- Refraction on the submerged layer: a capped sideways shift and shear taken from the surface tilt, measured in pixels so tall containers do not over-shear
- Meniscus highlight rides the surface, and crests throw spray once the scroll is fast enough, on fine pointers only
- Your markup stays real DOM. The submerged copy is inert and aria-hidden, so nothing is duplicated for assistive tech or the tab order
- Damped settle into a slow idle ripple that never fully flattens, in place of a linear snap back
- Coarse pointers get the same scroll-driven fill on a lighter 24 column surface with spray switched off

## Use Cases

- Swim, surf and watersport landing pages that need the water to actually do something
- Drinks, brewing and bottling brands where the liquid is the product
- Charity and campaign heroes about water, flooding or sea level
- Spa, pool and wellness sites where the hero should feel like immersion
- Agency and studio statement panels built around one memorable scroll moment

## Vibe-Code Ready Setup

This effect includes `START-HERE-AI.md`, a product-specific copy-paste setup prompt for Cursor, Claude Code, ChatGPT, GitHub Copilot, Windsurf, and other coding assistants. It tells the assistant to inspect the existing stack, integrate the supplied files, preserve the design, scope selectors, retain accessibility and responsive behaviour, add framework-appropriate GSAP cleanup, and report what it tested.

[How AI-assisted setup works](https://gsapvault.com/vibe-coding)

## How It Works

One pinned, scrubbed ScrollTrigger drives a proxy value from 0 to 1 across roughly 1.8 viewport heights. That value sets the fill level directly, and its rate of change is read on GSAP's ticker as the impulse fed into the surface, which means the response already carries the scrub smoothing and behaves the same with or without Lenis.

The surface is an array of columns, each a damped spring pulled toward the rest level. A fixed 1/60s step integrates the springs, then two passes trade a fraction of each column's height with its neighbours, which is what turns an impulse into a travelling wave that reflects off the walls and interferes with itself. Scroll speed pushes one wall up and the other down, and a pair of off-centre kicks stops the two halves mirroring each other.

The fluid body, its meniscus and any spray are drawn on a canvas sized to the container with devicePixelRatio handling and re-measured on every ScrollTrigger refresh. The same column samples become a clip-path polygon on a cloned, inert copy of your content, so the submerged scheme starts precisely at the wave. gsap.set applies the refraction shift and shear to the copy's child rather than the clipped wrapper, which keeps the shear from dragging the waterline sideways with it.

gsap.matchMedia runs a lighter surface on coarse pointers and a designed still under reduced motion, with no ticker and no pin. The ticker callback, both ScrollTriggers, the resize listener and the two injected layers are all removed in cleanup.

## Integration Preview

How this effect integrates into a page. The full documentation (examples, events, programmatic API, customization guide) ships with the download.

### Quick Start

**1. Add to your HTML `<head>`:**

```html
<link rel="stylesheet" href="path/to/style.css">
```

**2. Add the scene to your `<body>`:**

```html
<section class="hero" data-liquid-fill data-liquid-color="#22d3ee">
  <div class="hero-inner" data-liquid-content>
    <h1>Get in the water before sunrise</h1>
    <p>Harbour steps at six, every morning through the winter.</p>
    <button type="button">Join a swim</button>
  </div>
</section>
```

**3. Add before the closing `</body>` tag:**

```html
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/ScrollTrigger.min.js"></script>
<script src="path/to/script.js"></script>
```

The script finds every `[data-liquid-fill]` scene, inserts a canvas for the fluid, clones `[data-liquid-content]` into an inert copy stacked on top, and pins the scene for the configured scroll runway.

**4. Write the submerged scheme:**

The copy keeps every class from your original markup, so the below-water look is a set of overrides:

```css
.liquid-invert h1 { color: #04171d; }
.liquid-invert p  { color: #062028; }
.liquid-invert button { background: #04171d; color: #8ce9f8; }
```

Without these the submerged half stays in your normal colours, and light text on a bright fill is unreadable. This step is not optional.

### Options

Every option goes on the `[data-liquid-fill]` element.

| Attribute | Values | Default | Description |
|---|---:|---:|---|
| `data-liquid-fill` | marker | required | Identifies a liquid scene |
| `data-liquid-content` | marker | first child | The element that is copied and clipped |
| `data-liquid-color` | hex | `#22d3ee` | Fluid colour. The crest, body and floor tones are derived from it |
| `data-liquid-from` | `0`-`1` | `0.08` | Fill level at the start of the runway |
| `data-liquid-to` | `0`-`1` | `0.86` | Fill level at the end of the runway |
| `data-liquid-rest` | `0`-`1` | `0.55` | The level shown under reduced motion |
| `data-liquid-runway` | viewport heights | `1.8` | Pinned scroll distance |
| `data-liquid-scrub` | seconds | `0.4` | Scrub smoothing. Also sets how sharp a flick feels |
| `data-liquid-columns` | integer | `48` / `24` | Surface samples. Defaults to 24 on coarse pointers |
| `data-liquid-tension` | number | `0.021` | Spring pull back to level. Higher is tighter chop |
| `data-liquid-damping` | `0`-`1` | `0.968` | Velocity kept per step. Lower settles faster |
| `data-liquid-impact` | multiplier | `1` | How hard scroll speed hits the walls |
| `data-liquid-refract` | multiplier | `1` | Strength of the shift and shear below the line. `0` switches it off |
| `data-liquid-droplets` | `true`, `false` | `true` | Spray off the crests. Always off on coarse pointers |

### Accessibility

- **Reduced motion:** the `gsap.matchMedia` branch creates no pin, no ScrollTrigger and no ticker. It draws one still frame: fluid at `data-liquid-rest`, a level surface, the submerged scheme applied. The result is a designed composition, not a disabled one.
- **No JavaScript:** neither the canvas nor the copy exists, and your content is displayed exactly as written. Nothing on the page depends on JavaScript to become visible.
- **Screen readers:** the copy is `inert` and `aria-hidden`, and its `id` attributes are stripped, so the page still has one of everything and no duplicate targets.
- **Keyboard:** the effect is scroll-driven and adds no controls. Because the copy is `inert` and the canvas is `pointer-events: none`, links and buttons in your content keep their focus behaviour and their clicks whether they are above or below the waterline.
- **Contrast:** the fluid is opaque, so the submerged half needs its own palette. Check both schemes; the two ends of the fill gradient are different enough that text passing at the top and text sitting at the bottom should be measured separately.

### Dependencies

**Required:**

- GSAP 3.12+
- ScrollTrigger

**Optional:**

- Lenis 1.x for smooth scrolling. If present, the script runs Lenis from GSAP's ticker so both systems share one clock.

## What You Get

- `index.html`: working demo page
- `assets/script.js`: commented, readable source
- `assets/style.css`: effect styles
- `README.md`: full documentation with examples and framework integration notes
- `START-HERE-AI.md`: product-specific copy-paste prompt for AI-assisted setup
- `LICENSE.txt`: standard license terms
- Lifetime updates: re-download anytime from your library

## Get the Code

This is a premium effect. The standard license costs £5 one-time and covers unlimited personal and commercial projects with no attribution required. The only restrictions: no redistribution of the code itself and no competing effect libraries.

- [Buy Liquid Fill Reveal](https://gsapvault.com/effects/liquid-fill-reveal)
- [Effects & Templates Vault (£39 one-time, best value): every current and future effect and template](https://gsapvault.com/effects)

## Judge the Code Quality First

These related effects are free with complete source published, written to the same production standard (cleanup functions, reduced-motion support, framework-agnostic):

- [Scroll Progress Indicator](https://gsapvault.com/effects/scroll-progress.md): A precise GSAP reading-progress instrument with bar, ring, side rail, percentage, and active chapter feedback.
- [CSS Scroll Reveal](https://gsapvault.com/effects/css-scroll-reveal.md): Native CSS scroll-driven reveals for crisp fade, slide, and scale entrances with accessible static fallbacks and no animation JavaScript.
- [Parallax Hero](https://gsapvault.com/effects/parallax-hero.md): A pinned hero that separates its background photograph, copy, and foreground card into distinct scroll depths from a single scrubbed ScrollTrigger.

---

From [GSAP Vault](https://gsapvault.com): production-ready GSAP animation effects. Full catalog for agents: https://gsapvault.com/llms-full.txt
