Simulated Cursor
A synthetic mouse cursor that travels between waypoints and fires a click ripple, for narrating a UI on screen
$ pnpm dlx shadcn@latest add @remocn/simulated-cursorUsage
The cursor walks the points array in order. Each leg takes a fixed 24 frames of travel, then rests
for that point's hold (default 15). A point marked click fires a ripple when the cursor
arrives.
// src/Root.tsx
import { Composition } from "remotion";
import { SimulatedCursor } from "@/components/remocn/simulated-cursor";
const CursorScene = () => (
<SimulatedCursor
points={[
{ x: 200, y: 150, hold: 20 },
{ x: 800, y: 360, hold: 25, click: true },
{ x: 1050, y: 560, hold: 20 },
]}
color="#171717"
size={28}
/>
);
export const RemotionRoot = () => (
<Composition
id="SimulatedCursor"
component={CursorScene}
durationInFrames={150}
fps={30}
width={1280}
height={720}
/>
);Over a screenshot
The component renders transparent, so layer it above whatever it is pointing at.
import { AbsoluteFill, Img, staticFile } from "remotion";
import { SimulatedCursor } from "@/components/remocn/simulated-cursor";
const DemoScene = () => (
<AbsoluteFill>
<Img src={staticFile("dashboard.png")} style={{ width: "100%", height: "100%" }} />
<SimulatedCursor
points={[
{ x: 320, y: 210, hold: 18 },
{ x: 760, y: 420, hold: 24, click: true },
]}
color="#171717"
/>
</AbsoluteFill>
);Timing
Budget the Sequence from the waypoints: 24 frames per leg plus each point's hold. The default
three-point path runs about 93 frames; leave headroom for the click ripple to finish.
Props5
| Prop | Type | Default |
|---|---|---|
| points | CursorPoint[]DEFAULT_POINTS Waypoints the cursor travels through, in order. Each is { x, y, hold?, click? } in absolute canvas pixels. | |
| color | string"#ffffff" Fill color of the cursor arrow. Use a dark value over light UI screenshots. | |
| size | number32 Height of the cursor arrow in pixels. | |
| speed | number1 Time multiplier applied as frame × speed. Above 1 the cursor completes its path sooner. | |
| className | string— Optional className passed to the wrapper element. | |
- pointsCursorPoint[]
Waypoints the cursor travels through, in order. Each is { x, y, hold?, click? } in absolute canvas pixels.
Default
DEFAULT_POINTS - colorstring
Fill color of the cursor arrow. Use a dark value over light UI screenshots.
Default
"#ffffff" - sizenumber
Height of the cursor arrow in pixels.
Default
32 - speednumber
Time multiplier applied as frame × speed. Above 1 the cursor completes its path sooner.
Default
1 - classNamestring
Optional className passed to the wrapper element.
CursorPoint
| Prop | Type | Default |
|---|---|---|
| xrequired | number— Horizontal position in canvas pixels. | |
| yrequired | number— Vertical position in canvas pixels. | |
| hold | number15 Frames the cursor rests at this point after arriving, before starting the next leg. | |
| click | booleanfalse Fires a click ripple when the cursor arrives at this point. | |
- xrequirednumber
Horizontal position in canvas pixels.
- yrequirednumber
Vertical position in canvas pixels.
- holdnumber
Frames the cursor rests at this point after arriving, before starting the next leg.
Default
15 - clickboolean
Fires a click ripple when the cursor arrives at this point.
Default
false