Skip to documentation

Components

Fluid Image Reveal

A persistent fluid mask that reveals one image through another with pointer-driven motion.

  • pixi.js@^8.20.1

Preparing preview…

Installation

Choose your framework. The registry installs one component file and its PixiJS dependency.

Installation unavailable

This preview is not assigned to the free or paid catalog. Installation is unavailable.

The registry command writes the component to src/lib/components/ui/FluidImageReveal.svelte and installs its dependencies.

The registry command writes the component to src/components/ui/FluidImageReveal.tsx and installs its dependencies.

The registry command writes the component to src/components/ui/FluidImageReveal.vue and installs its dependencies.

Overview

Fluid Image Reveal uses the same curl, vorticity, divergence, pressure, and advection pipeline as Fluid Simulation, with transported dye serving as the reveal mask.

A softly thresholded density field reveals the second fitted image while pointer movement continuously injects motion and mask density.

Basic usage

The shader fills its parent. Your layout decides whether that parent is a card, hero, or viewport.

Hero.svelte
<script lang="ts">
	import FluidImageReveal from '$lib/components/ui/FluidImageReveal.svelte';
</script>

<section class="relative h-128 overflow-hidden">
	<FluidImageReveal
		class="absolute inset-0"
		baseImage="/images/your-image.jpg"
		revealImage="/images/your-image.jpg"
	/>

	<div class="relative z-10">Your content</div>
</section>
<script lang="ts">
	import FluidImageReveal from '$lib/components/ui/FluidImageReveal.svelte';
</script>

<section class="relative h-128 overflow-hidden">
	<FluidImageReveal
		class="absolute inset-0"
		baseImage="/images/your-image.jpg"
		revealImage="/images/your-image.jpg"
	/>

	<div class="relative z-10">Your content</div>
</section>
import { FluidImageReveal } from '@/components/ui/FluidImageReveal';

export function Hero() {
	return (
		<section className="relative h-128 overflow-hidden">
			<FluidImageReveal
				className="absolute inset-0"
				baseImage="/images/your-image.jpg"
				revealImage="/images/your-image.jpg"
			/>

			<div className="relative z-10">Your content</div>
		</section>
	);
}
import { FluidImageReveal } from '@/components/ui/FluidImageReveal';

export function Hero() {
	return (
		<section className="relative h-128 overflow-hidden">
			<FluidImageReveal
				className="absolute inset-0"
				baseImage="/images/your-image.jpg"
				revealImage="/images/your-image.jpg"
			/>

			<div className="relative z-10">Your content</div>
		</section>
	);
}
<script setup lang="ts">
import FluidImageReveal from '@/components/ui/FluidImageReveal.vue';
</script>

<template>
	<section class="relative h-128 overflow-hidden">
		<FluidImageReveal
			class="absolute inset-0"
			baseImage="/images/your-image.jpg"
			revealImage="/images/your-image.jpg"
		/>

		<div class="relative z-10">Your content</div>
	</section>
</template>
<script setup lang="ts">
import FluidImageReveal from '@/components/ui/FluidImageReveal.vue';
</script>

<template>
	<section class="relative h-128 overflow-hidden">
		<FluidImageReveal
			class="absolute inset-0"
			baseImage="/images/your-image.jpg"
			revealImage="/images/your-image.jpg"
		/>

		<div class="relative z-10">Your content</div>
	</section>
</template>
  • Move the pointer across the canvas to reveal the second image.
  • The first pointer move establishes history without injecting a jump from the canvas origin.
  • Higher pressure iterations and target resolutions improve fidelity but increase GPU work.

Component API

Types below match the selected Svelte component.

Property Type Default Range / values
class
string
baseImage
string Image URL or data URL
revealImage
string Image URL or data URL
imageFit
"cover" | "fit" | "stretch" "cover" cover, fit, stretch
simulationResolution
number 256 32–256
dyeResolution
number 1024 128–1024
densityDissipation
number 1 0–4
velocityDissipation
number 0.05 0–4
pressure
number 0.8 0–1
pressureIterations
number 1 1–40
curl
number 0 0–50
splatRadius
number 0.87 0.01–1
splatForce
number 6000 0–10000
blendSoftness
number 0.22 0.01–0.49
paused
boolean false
interactive
boolean true
maxDpr
number 2 1–3
resolutionScale
number 1 0.25–1
onReady
(backend: ShaderBackend) => void webgpu, webgl
onRendererChange
(backend: ShaderBackend, reason: string) => void webgl
onError
(error: Error) => void
bind:this
Component public instance pause, resume, reset, resize, destroy

Types below match the selected React component.

Property Type Default Range / values
className
string
baseImage
string Image URL or data URL
revealImage
string Image URL or data URL
imageFit
"cover" | "fit" | "stretch" "cover" cover, fit, stretch
simulationResolution
number 256 32–256
dyeResolution
number 1024 128–1024
densityDissipation
number 1 0–4
velocityDissipation
number 0.05 0–4
pressure
number 0.8 0–1
pressureIterations
number 1 1–40
curl
number 0 0–50
splatRadius
number 0.87 0.01–1
splatForce
number 6000 0–10000
blendSoftness
number 0.22 0.01–0.49
paused
boolean false
interactive
boolean true
maxDpr
number 2 1–3
resolutionScale
number 1 0.25–1
onReady
(backend: ShaderBackend) => void webgpu, webgl
onRendererChange
(backend: ShaderBackend, reason: string) => void webgl
onError
(error: Error) => void
ref
FluidImageRevealHandle pause, resume, reset, resize, destroy

Types below match the selected Vue component.

Property Type Default Range / values
class
string
baseImage
string Image URL or data URL
revealImage
string Image URL or data URL
imageFit
"cover" | "fit" | "stretch" "cover" cover, fit, stretch
simulationResolution
number 256 32–256
dyeResolution
number 1024 128–1024
densityDissipation
number 1 0–4
velocityDissipation
number 0.05 0–4
pressure
number 0.8 0–1
pressureIterations
number 1 1–40
curl
number 0 0–50
splatRadius
number 0.87 0.01–1
splatForce
number 6000 0–10000
blendSoftness
number 0.22 0.01–0.49
paused
boolean false
interactive
boolean true
maxDpr
number 2 1–3
resolutionScale
number 1 0.25–1
@ready
(backend: ShaderBackend) => void webgpu, webgl
@rendererchange
(backend: ShaderBackend, reason: string) => void webgl
@error
(error: Error) => void
ref
Component public instance pause, resume, reset, resize, destroy