npm install @caustics/distortion-hover <script> import { DistortionHover } from '@caustics/distortion-hover'; </script> <DistortionHover preset="ripple" />
npm install @caustics/distortion-hover import { DistortionHover } from '@caustics/distortion-hover/react'; return <DistortionHover preset="ripple" />;
npm install @caustics/distortion-hover import { mount } from '@caustics/distortion-hover'; mount(document.querySelector('#hero'), { preset: 'ripple' });
| Prop | Type | Default | Description |
|---|---|---|---|
| preset | string | "ripple" | Named preset. Overrides individual props when set. |
| colors | string[] | undefined | Override palette. Accepts hex, hsl, or CSS custom properties. |
| reducedMotion | 'pause' | 'static' | 'pause' | Behavior when prefers-reduced-motion is active. |
| class | string | undefined | Additional CSS classes applied to the root element. |
caustics-distortion-hover/ ├── svelte/ DistortionHover.svelte · index.ts · types.ts ├── react/ DistortionHover.tsx · index.ts · types.ts ├── vanilla/ distortion-hover.ts · compiled .js ├── docs/ README.md · API.md · CHANGELOG.md ├── LICENSE.md Caustics Commercial License └── package.json
Distortion Hover renders an image on a WebGL plane and warps its sample UVs on cursor hover, driven by a displacement shader. The result is the liquid, organic distortion you see on Awwwards-winning agency and portfolio sites — the cursor is the center of the effect, and the intensity ramps in smoothly on enter and back out on leave.
Four effects ship in, each a distinct preset: ripple sends an expanding ring of displacement out from the cursor like a stone dropped in water; noise warps the image with an organic, flowing noise field that drifts over time; swirl twists the image into a liquid vortex around the pointer; and bulge is a smooth magnetic lens that tracks the cursor. Every effect is tunable — intensity, radius, speed, hover smoothing — and an optional chromatic-aberration split fringes the distorted edges with color the way a real lens does.
It runs on its own single-pass WebGL engine — no Three.js, no runtime dependencies — so the vanilla bundle is around 10 KB gzipped. Attach it to an existing <img>, to any element holding one, or hand it an image URL. The engine carries the full Caustics lifecycle: the render loop idles to zero frames when the image is at rest, pauses off-screen, caps device-pixel-ratio at 2, survives WebGL context loss, and releases its GPU context on teardown. It degrades cleanly everywhere it must — reduced-motion and touch devices get the plain, untouched image, a CORS-tainted cross-origin image falls back to the original rather than a broken canvas, and destroy() restores the <img> exactly as it was. Ships as plain ESM for Svelte, React, and vanilla JS, with a [data-distortion] auto-init for no-build pages.
Caustics Commercial License · lifetime updates within v1