Cursor Flow
A realistic mouse that arcs along cubic Bezier paths, pauses, and clicks targets that dip in response.
A more sophisticated cousin of SimulatedCursor. Instead of moving on straight lines between waypoints, the cursor follows per-segment cubic Bezier curves whose control points are offset perpendicular to the chord, so the trajectory always has a "belly". An ease-in-out function shapes velocity inside each segment so the cursor accelerates, glides, and decelerates before arrival. At click moments, an independent spring drives a hard 4-frame 1 → 0.85 → 1 press while the click target dips to 0.98 in sync — that's the moment that sells the impact.
Installation
$ pnpm dlx shadcn@latest add @remocn/cursor-flowUsage
// src/Root.tsx
import { Composition } from "remotion";
import { CursorFlow } from "@/components/remocn/cursor-flow";
const CursorFlowScene = () => (
<CursorFlow
waypoints={[
{ x: 200, y: 180 },
{ x: 540, y: 240, click: true, label: "Generate" },
{ x: 880, y: 360, hold: 8 },
{ x: 1040, y: 520, click: true, label: "Publish" },
]}
/>
);
export const RemotionRoot = () => (
<Composition
id="CursorFlow"
component={CursorFlowScene}
durationInFrames={180}
fps={30}
width={1280}
height={720}
/>
);Props
| Prop | Type | Default | Description |
|---|---|---|---|
waypoints | CursorWaypoint[] | — | Ordered list of points the cursor visits. Each waypoint has `x`, `y`, and optional `hold`, `click`, and `label`. |
cursorColor | string | "#fafafa" | Cursor SVG fill color. |
cursorSize | number | 28 | Cursor SVG side length in pixels. |
segmentDuration | number | 36 | Frames spent traversing one segment between two waypoints. |
background | string | "#0a0a0a" | Page background color. |
showTargets | boolean | true | Render the click target chips at clickable waypoints. |
speed | number | 1 | Playback speed multiplier. |
className | string | — | Optional className passed to the root container. |
Notes
Per-segment perpendicular control points alternate sign every other segment so the path snakes naturally. If you flatten the offset to 0 you get robotic straight lines — keep it.
Curves are computed inline with a small cubicBezier evaluator to avoid pulling in d3-shape (~30KB) just for path math.
Variant: Simulated Cursor
A simpler primitive that renders a macOS-style cursor (inline SVG, no external assets) and moves it between a list of points on straight lines. Each waypoint can hold for a configurable number of frames and optionally trigger a click animation: a brief scale dip plus an expanding SVG ripple. Use this when you don't need the realistic Bezier-arc trajectory of CursorFlow.
Installation
$ pnpm dlx shadcn@latest add @remocn/simulated-cursorUsage
import { SimulatedCursor } from "@/components/remocn/simulated-cursor";
<SimulatedCursor
points={[
{ x: 200, y: 150, hold: 20 },
{ x: 800, y: 360, hold: 25, click: true },
{ x: 1050, y: 560, hold: 20 },
]}
color="#ffffff"
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
points | Array<{ x: number; y: number; hold?: number; click?: boolean }> | 3 sample waypoints | Cursor waypoints in pixel coordinates. hold = frames to pause at the point, click = trigger click ripple. |
color | string | "#ffffff" | Cursor fill color. The cursor always has a thin black outline for contrast. |
size | number | 32 | Cursor size in pixels (SVG width and height). |
background | string | "#0a0a0a" | Background color of the frame the cursor lives in. |
className | string | — | Optional className passed to the outer container. |
The cursor is drawn as inline SVG, so you don't need to copy anything into public/. Drop the component into any composition and it just works.