Cursor Trail Reveal
sora-ui/cursor-trail-revealFreeComponent
Desktop cursor trail that reveals staggered image strips with clip-path wipes as the pointer moves.
Install it
npx shadcn@latest add https://ui.soralabs.io.vn/r/cursor-trail-reveal.jsonSource
1"use client";23import { cn } from "@/lib/utils";4import { cva, type VariantProps } from "class-variance-authority";5import { type ComponentPropsWithoutRef, useEffect, useRef } from "react";6import { usePrefersReducedMotion } from "@/hooks/use-prefers-reduced-motion";78const MASK_LAYER_COUNT = 10;9const DEFAULT_IMAGE_SIZE = 175;1011const cursorTrailRevealVariants = cva(12 "pointer-events-none absolute inset-0 z-[2] overflow-hidden",13 {14 variants: {15 layout: {16 default: "",17 fill: "size-full",18 },19 },20 defaultVariants: {21 layout: "default",22 },23 }24);2526interface TrailConfig {27 easing: string;28 imageLifespan: number;29 inDuration: number;30 mouseThreshold: number;31 outDuration: number;32 slideDuration: number;33 slideEasing: string;34 staggerIn: number;35 staggerOut: number;36}3738interface TrailImageEntry {39 element: HTMLDivElement;40 imageLayers: HTMLDivElement[];41 maskLayers: HTMLDivElement[];42 removeTime: number;43}4445const MathUtils = {46 lerp: (a: number, b: number, n: number) => (1 - n) * a + n * b,47 distance: (x1: number, y1: number, x2: number, y2: number) =>48 Math.hypot(x2 - x1, y2 - y1),49};5051export interface CursorTrailRevealProps52 extends Omit<ComponentPropsWithoutRef<"div">, "children">,53 VariantProps<typeof cursorTrailRevealVariants> {54 /** Viewport width above which the trail is active. */55 desktopBreakpoint?: number;56 /** Trail thumbnail size in pixels. */57 imageSize?: number;58 /** Image URLs cycled as the cursor moves (desktop only). */59 images: readonly string[];60 /** Background color behind each strip during the clip-path reveal. */61 maskColor?: string;62 /** Minimum pointer travel before spawning the next image. */63 mouseThreshold?: number;64}6566function CursorTrailReveal({67 className,68 desktopBreakpoint = 1000,69 imageSize = DEFAULT_IMAGE_SIZE,70 images,71 layout = "default",72 maskColor = "var(--background, #1a1a1a)",73 mouseThreshold = 150,74 ...props75}: CursorTrailRevealProps) {76 const trailContainerRef = useRef<HTMLDivElement>(null);77 const animationStateRef = useRef<number | null>(null);78 const trailRef = useRef<TrailImageEntry[]>([]);79 const timeoutIdsRef = useRef<number[]>([]);80 const currentImageIndexRef = useRef(0);81 const mousePosRef = useRef({ x: 0, y: 0 });82 const lastMousePosRef = useRef({ x: 0, y: 0 });83 const interpolatedMousePosRef = useRef({ x: 0, y: 0 });84 const isDesktopRef = useRef(false);85 const prefersReducedMotion = usePrefersReducedMotion();86// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from Sora UI
All 97 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | Sora UI | Components | Free | 2 deps | |
| Border Trailborder-trail | Sora UI | Components | Free | 1 dep | |
| Bottom Sheetbottom-sheet | Sora UI | Components | Free | 2 deps | |
| Cursor Bubblecursor-bubble | Sora UI | Components | Free | 2 deps | |
| Custom Cursorcustom-cursor | Sora UI | Components | Free | 2 deps | |
| Accordion Demodemo-accordion | Sora UI | Components | Free | no deps | |
| Border Trail Demodemo-border-trail | Sora UI | Components | Free | no deps | |
| Border Trail Loading Card Demodemo-border-trail-loading | Sora UI | Components | Free | no deps |
