Skip to content

COMPONENT / pixelated-image-trail

Pixelated Image Trail_

Drops image tiles behind the mouse that resolve from coarse pixels to sharp, then step back out. Off for touch and under reduced motion. Requires @cybr/tokens.

Install

  1. 1. Map the @cybr namespace, once per project. Add this inside your components.json, or into its existing "registries" object. No components.json yet? Run npx shadcn@latest init first to create one.

    "registries": { "@cybr": "https://cybr-ui.com/r/{name}.json" }
  2. 2. Add components:

    $ npx shadcn@latest add @cybr/pixelated-image-trail

If shadcn reports Unknown registry "@cybr", step 1 is missing from that project's components.json.

Preview

MOVE THE
CURSOR_

Props

Component props
PropTypeDefaultDescription
imagesstring[]—Image URLs, used in order and repeated. Any image the browser can load works, cross-origin included. Images that fail to load are skipped.
spacingnumber80Pointer travel in px before the next tile drops.
size{ width: number; height: number }{ width: 160, height: 120 }Tile size in CSS px. Images are cropped to fill it.
maxnumber8Most tiles on screen at once. The oldest goes first.
childrenReactNode—The host content. It stays readable and clickable under the trail.
classNamestring—Extra classes, merged after the defaults with cn(). Give the host a size.
...propsComponentProps<"div">—Every other native <div> attribute and ref is forwarded. Your onPointerMove runs before the trail's.

Usage

Needs the stylesheet from @cybr/tokens; @cybr/use-reduced-motion arrives with it. After the install, import it in app/globals.css:

@import "tailwindcss";
@import "../styles/cybr-tokens.css";
import { PixelatedImageTrail } from "@/components/ui/pixelated-image-trail";

export function Hero() {
  return (
    <PixelatedImageTrail className="h-96" images={["/work/01.jpg", "/work/02.jpg"]}>
      <h1>Selected work</h1>
    </PixelatedImageTrail>
  );
}

Behaviour

Accessibility