# Liquid Ripple Image

> A liquid image hover effect: dragging the cursor over an image distorts the pixels like water, rippling from the pointer and settling back to a crisp, calm pool.

Canonical: https://gsapvault.com/effects/liquid-ripple-image
Live demo: https://gsapvault.com/demos/liquid-ripple-image/index.html

| Property | Value |
|----------|-------|
| Type | effect |
| Tier | paid |
| Price | £5 |
| Difficulty | intermediate |
| Plugins | Core GSAP only |
| Techniques | svg-filters, hover-effect, cursor-effects |
| Uses Lenis | No |

## Overview

A liquid distortion effect that turns any image into water under the cursor. An inline SVG feTurbulence and feDisplacementMap warp the pixels, and GSAP feeds the filter from pointer velocity, so a slow drag ripples gently while a fast flick spikes a big watery splash.

The disturbance eases back to a perfectly crisp rest with no snap, and a cyan glow tracks the pointer so the ripple reads localised over a global displacement. The filter is wired up only by JavaScript, so with no script or under reduced motion the image renders sharp and undistorted.

## Features

- SVG feTurbulence + feDisplacementMap distortion driven entirely by GSAP, no canvas or WebGL
- Displacement scale tracks cursor speed: slow drag ripples softly, fast flick spikes a splash
- Turbulence baseFrequency shifts under speed so the ripple texture gets busier as you move faster
- Pointer-tracking cyan glow and a subtle image swell layer over the same input for depth
- Smooth power-style settle back to a crisp scale-zero rest, so calm and disturbed read as opposites
- Pointer events cover mouse, pen and touch; a tap drops a one-shot splash that calms on its own
- Filter is gated behind JavaScript, so no-JS and reduced-motion visitors get the sharp original image
- Data-attribute config for splash strength, resting frequency, gain and an optional idle micro-ripple

## Use Cases

- Hero and portfolio images that reward the visitor for touching them
- Product or artwork showcases where a tactile, watery hover adds a premium feel
- Photography and agency sites wanting an award-style interaction on a single key image
- Landing-page feature images that invite play with a clear "drag to ripple" prompt
- Event or music pages where a liquid, reactive visual matches the mood

## How It Works

An inline SVG filter pairs feTurbulence (fractalNoise) with a feDisplacementMap whose scale attribute starts at zero, so the image is crisp until JavaScript runs. Pointer velocity is measured on pointermove and fed into a decaying energy value; a GSAP ticker writes that value onto the displacement scale and the turbulence baseFrequency each frame with setAttribute, never rebuilding the filter.

The energy decays smoothly toward zero so the water calms rather than snapping, a tap injects a one-shot impulse, and gsap.matchMedia skips the whole wiring under reduced motion so the un-filtered image is the fallback.

## 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 before the closing `</body>` tag:**

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

**3. Add the effect HTML anywhere in your `<body>`:**

The wrapper needs `data-liquid-ripple`. Inside it, a `.ripple-frame` holds a `.ripple-svg` whose scene group carries the filter, plus the filter definition itself. The class names below are what the script queries, so keep them.

```html
<figure class="ripple" data-liquid-ripple>
  <div class="ripple-frame">
    <svg class="ripple-svg" viewBox="0 0 800 500" preserveAspectRatio="xMidYMid slice" role="img" aria-label="Describe your image here">
      <defs>
        <filter id="lr-filter" x="-30%" y="-30%" width="160%" height="160%" color-interpolation-filters="sRGB">
          <feTurbulence class="ripple-turb" type="fractalNoise" baseFrequency="0.009 0.012" numOctaves="2" seed="6" result="lr-noise"/>
          <feDisplacementMap class="ripple-disp" in="SourceGraphic" in2="lr-noise" scale="0" xChannelSelector="R" yChannelSelector="G"/>
        </filter>
      </defs>

      <!-- Your image or drawn scene. Keep the .ripple-scene class and data-filter-id. -->
      <g class="ripple-scene" data-filter-id="lr-filter">
        <image href="path/to/your-image.jpg" x="-40" y="-40" width="880" height="580" preserveAspectRatio="xMidYMid slice"/>
      </g>
    </svg>
    <span class="ripple-glow" aria-hidden="true"></span>
  </div>
</figure>
```

That is all you need. The optional `.ripple-caption` with a `.ripple-splash-btn` button (see the demo `index.html`) gives keyboard users a way to trigger the splash.

### Options

Set these as data attributes on the `data-liquid-ripple` wrapper.

| Attribute | Values | Default | Description |
|-----------|--------|---------|-------------|
| `data-ripple-strength` | Any number (px) | `62` | Peak displacement a hard flick can reach. Above ~90 the edges tear; below ~30 the splash reads timid. |
| `data-ripple-frequency` | `0.004`–`0.02` | `0.009` | Resting turbulence frequency. Higher makes finer, busier ripples. |
| `data-ripple-gain` | Any number | `0.85` | How strongly cursor speed maps to displacement. Raise for a twitchier surface. |
| `data-ripple-idle` | `true`, `false` | `false` | Adds a gentle idle micro-ripple. Off by default so rest reads crisp. |

### Accessibility

This effect is built to degrade cleanly:

- **No JavaScript**: the filter is never attached, so the image shows crisp and undistorted. The distortion is purely an enhancement.
- **Reduced motion**: under `prefers-reduced-motion: reduce` the script skips all wiring; the image stays static and sharp and the glow is hidden.
- **Keyboard**: the optional `.ripple-splash-btn` triggers the same splash a tap does, so the signature moment is reachable without a pointer. Give it a clear label.
- **Touch**: pointer events cover touch, so a finger drag ripples and a tap splashes. The frame sets `touch-action: none` only once JS is live, so no-JS visitors keep normal scrolling.

### Dependencies

**Required:**
- GSAP 3.12+ (core only, no plugins)

**Optional:**
- None

## 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
- `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 Ripple Image](https://gsapvault.com/effects/liquid-ripple-image)
- [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):

- [Hover Underline](https://gsapvault.com/effects/hover-underline.md): Animated link underlines with three GSAP variants: an exit-through slide, a marker-style fill sweep, and a hand-drawn SVG wave. One data attribute per link.
- [Image Clip Reveal](https://gsapvault.com/effects/image-clip-reveal.md): Images reveal on scroll with an animated clip-path wipe and a Ken Burns settle, the inner image easing from 1.25 scale down to 1 as the mask opens.

---

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