Getting Started
Scroll Animations
Text Animations
Hover & Cursor
Sliders & Carousels
Galleries & Grids
Menus & Navigation
Preloaders & Intros
Page Transitions
3D & WebGL
"use client"
import { ImageExplosionFooter } from "@/registry/tween/image-explosion-footer"
export function ImageExplosionFooterDemo() {
return (
<div
className="relative w-full overflow-hidden"
style={{ backgroundColor: "#0f0f0f" }}
>
<section
className="relative flex w-full items-center justify-center bg-[#0f0f0f] text-white"
style={{ height: "var(--preview-h, 100vh)" }}
>
<div className="max-w-[60ch] px-8 text-center">
<p className="font-mono text-[0.7rem] tracking-[0.2em] text-white/60 uppercase">
Index — 2019 to 2026
</p>
<h2
className="mt-4 text-[clamp(1.5rem,4cqi,3rem)] leading-[1.15] font-medium uppercase"
style={{ letterSpacing: "-0.02em" }}
>
Forty-one campaigns, nine cities, and a new backdrop colour for
every single one.
</h2>
<p className="mt-6 font-mono text-[0.7rem] tracking-[0.2em] text-white/50 uppercase">
Scroll for the contact sheet
</p>
</div>
</section>
<ImageExplosionFooter />
</div>
)
}
import { ImageExplosionFooter } from "@/components/ui/image-explosion-footer"<ImageExplosionFooter
headline="The hard ones, please"
images={[
"https://images.example.com/campaign-01.jpg",
"https://images.example.com/campaign-02.jpg",
"https://images.example.com/campaign-03.jpg",
"https://images.example.com/campaign-04.jpg",
]}
/>When the footer scrolls into view, every image is launched from the
headline as a particle with an initial upward velocity. Each frame,
gravity pulls particles back down while friction decays their velocity,
so they arc up, slow, and fall — a lightweight physics simulation rather
than a fixed keyframe path. horizontalForce, verticalForce, and
rotationSpeed control how wide the burst spreads and how fast particles
tumble, so small tweaks change the whole character of the explosion. Once
the particles have cleared, the component waits resetDelay milliseconds
and re-arms, so scrolling away and back triggers a fresh blast. The
headline, topSlot, and bottomSlot render as normal footer content
above and below the particle layer, making this a drop-in replacement for a
standard site footer with a memorable entrance.
| Prop | Type | Default | Description |
|---|---|---|---|
images | string[] | 7 defaults | URLs of the particle images. |
headline | ReactNode | Default copy | Large headline shown above the explosion. |
topSlot | ReactNode | — | Custom content rendered at the top of the footer. |
bottomSlot | ReactNode | © line | Custom content rendered at the bottom of the footer. |
gravity | number | 0.25 | Downward acceleration applied each frame. |
friction | number | 0.99 | Per-frame velocity decay (closer to 1 = floatier). |
imageSize | number | 150 | Width of each particle in pixels. |
horizontalForce | number | 20 | Spread of initial horizontal velocity. |
verticalForce | number | 15 | Base initial upward velocity (a random extra is added). |
rotationSpeed | number | 10 | Spread of initial angular velocity. |
resetDelay | number | 600 | Milliseconds to wait before re-arming the explosion. |
scroller | HTMLElement | null | — | Override scroller; defaults to the ambient usePreviewScroller(). |
background | string | "var(--background)" | Footer background color. |
ink | string | "var(--foreground)" | Foreground color used for headline and bottom slot. |
className | string | — | Extra classes on the outer footer. |