Frame Drift
A photo-card cursor trail that reveals images with every gesture, layering tilted frames before they gently fade away.
Overview
About the Frame Drift
A photo-card cursor trail that reveals images with every gesture, layering tilted frames before they gently fade away. It is delivered as editable TypeScript for React. No Tailwind CSS required. All component styles are inline. Its focused API can be adapted to your own content and visual system.
Usage
When to use it
- Photography and creative portfolios with an interactive first impression.
- Editorial and team pages that reveal a collection through pointer movement.
What’s included
Files in the product ZIP
Frame Drift source
components/frame-drift.tsxEditable React and TypeScript component source.
Working example
examples/example.tsxA minimal import and render example that matches the packaged API.
Installation guide
README.mdManual ZIP installation, styling, compatibility, asset, and usage notes.
Usage
Import and render
Copy the packaged source to the documented path, then use the public API shown below.
import { FrameDrift } from "@/components/frame-drift";const images = [{ src: "/photos/one.jpg" }, { src: "/photos/two.jpg" }];
<FrameDrift images={images} height={480} spacing={64} />Props
Component API
| Prop | Type | Default | Description |
|---|---|---|---|
| images | readonly FrameDriftImage[] | — | Required list of image sources. Keep the array stable between renders; an empty array renders only the container content. |
| cardWidth / cardHeight | number | 150 / 210 | Card dimensions in pixels; widths are limited to 40–400 and heights to 40–500. |
| spacing | number | 64 | Travel distance before another card appears, limited to 12–240 pixels. |
| lifetime | number | 2 | Card lifetime in seconds, limited to 0.3–8. |
| rotation | number | 12 | Maximum rotation in degrees, limited to 0–45. |
| radius / frameWidth | number | 10 / 0 | Corner radius and frame padding in pixels. |
| frameColor / backgroundColor | string | "#faf8f4" / "#09090f" | Frame and container colors. |
| shadow | number | 0.5 | Shadow opacity from 0 to 1. |
| fit | "cover" | "contain" | "cover" | Image fit within its card. |
| order | "sequence" | "random" | "sequence" | How images are selected. |
| stacking | "newest" | "oldest" | "newest" | Which cards appear in front. |
| maxCards | number | 20 | Maximum number of simultaneous cards, limited to 1–40. |
| mode | "pointer" | "auto" | "pointer" | Optional idle demonstration path. |
| paused | boolean | false | Freeze animation and pointer spawning. |
| height | number | string | 480 | Container height. |
| children / className / style | ReactNode / string / CSSProperties | — | Overlay content and container styling. |
Images are decorative and hidden from screen readers. Render a separate accessible gallery when photos convey meaningful content. Pointer effects preserve child interactions and touch scrolling. Reduced motion displays one still card on movement.
Compatibility
Verified project setup
- ReactLoom's preview is tested with Next.js 16.3.8 App Router, React 19.2.8, TypeScript 5.9.3, and Tailwind CSS 4.3.3. This describes the store environment, not the product's minimum requirements.
- This interactive component includes the "use client" directive and must remain behind a Client Component boundary in the Next.js App Router.
- No Tailwind CSS required. All component styles are inline.
- Images
- Photos are not included in the ZIP. Supply your own licensed local or remote image URLs. The store preview uses remote Unsplash images.
- Fonts
- No font files are included. The component uses system font fallbacks unless your app supplies a matching font.
Installation
Add it to your project
Download the Frame Drift ZIP, place the source file at src/components/frame-drift.tsx, and copy the example into your own page or feature folder.
Target path
src/components/frame-drift.tsxNo additional npm runtime packages are required beyond the React host; follow the styling requirements below.
Styling requirements
- Provide your own image URLs; no photos are distributed in the ZIP.
- Uses the Web Animations API and IntersectionObserver.
- Reduced motion shows still cards. Animation pauses offscreen and in hidden tabs.