Pen Cursor
Physics-driven ribbon trail rendered on canvas — a chain of linked points follows the mouse with spring-damping inertia, width scales with speed, and colors interpolate head-to-tail. Inspired by obsidianassembly.com.
UniqueUI CLI
npx uniqueui add pen-cursor
shadcn CLI
npx shadcn@latest add https://uniqueui.com/r/pen-cursor.json -y
shadcn path expects @/lib/utils (run shadcn init first). Same source file is installed to components/ui/.
Preview
Ribbon trail
Move your mouse — a physics-driven ribbon trails the pointer.
Usage
"use client";
import { useRef } from "react";
import { PenCursor } from "@/components/ui/pen-cursor";
export default function Example() {
const containerRef = useRef<HTMLDivElement>(null);
return (
<div
ref={containerRef}
className="h-[400px] w-full relative bg-neutral-950 overflow-hidden flex items-center justify-center"
>
<h3 className="text-white text-2xl font-bold uppercase tracking-widest pointer-events-none">
Move your mouse
</h3>
<PenCursor
containerRef={containerRef}
trailLength={40}
maxWidth={1}
colorHead="159, 175, 155"
colorTail="198, 167, 106"
alphaHead={0.95}
damping={0.55}
/>
</div>
);
}Props
| Prop | Type | Description |
|---|---|---|
trailLength | number | Number of chain-linked trail points. Default 60. |
maxWidth | number | Maximum ribbon width in px (scales with speed). Default 1. |
minWidth | number | Minimum ribbon width in px at the tail. Default 1. |
damping | number | Spring damping for the head point (0–1). Default 0.6. |
speedInfluence | number | How much mouse speed widens the ribbon (0–1). Default 0.9. |
colorHead | string | RGB string for the ribbon head color. Default "159, 175, 155" (sage green). |
colorTail | string | RGB string for the ribbon tail color. Default "198, 167, 106" (warm gold). |
alphaHead | number | Opacity at the ribbon head (0–1). Default 0.9. |
alphaTail | number | Opacity at the ribbon tail (0–1). Default 0. |
hideSystemCursor | boolean | Hide the system cursor while mounted. Default false. |
containerRef | RefObject<HTMLElement | null> | Optional. Limits drawing to this element; parent should be `relative`. Omit for full-window tracking. |
className | string | Extra classes on the canvas element. |