# ImageTrailCursor

> Trail of images that spawn and animate along the cursor's path, powered by GSAP timelines, with 9 selectable variants spanning simple fades, momentum drift, rotation flings, 3D perspective tilt, and a hard-edge pixelated snap.

- Package: `fancy-ui-svelte` (Svelte 5 + Tailwind CSS v4)
- Category: Effects
- Tags: cursor, animation, images, trail, interactive
- Docs: https://fancy-ui.rama.app/docs/components/image-trail-cursor
- Source: https://github.com/RamaHerbin/fancy-ui/tree/main/src/lib/fancy-ui/image-trail-cursor

## Import

```svelte
<script lang="ts">
  import { ImageTrailCursor } from 'fancy-ui-svelte';
</script>
```

Setup (once per project): `npm install fancy-ui-svelte`, then add `@import "fancy-ui-svelte/tailwind.css";` after `@import "tailwindcss";` in your main CSS file. Full guide: https://fancy-ui.rama.app/llms.txt

React: `import { ImageTrailCursor } from 'fancy-ui-react';` (same prop names; `class` becomes `className`, snippets become `ReactNode`).

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `images` | `string[]` | `[]` | Array of image URLs to show in the trail |
| `variant` | `"type1" \| "type2" \| ... \| "type8" \| "pixelated"` | `"type1"` | Animation variant controlling how images appear and move |

## Examples

### Basic Usage

```svelte
<script lang="ts">
	import { ImageTrailCursor } from "fancy-ui-svelte";
	import type { VariantType } from "fancy-ui-svelte";

	const images = [
		"https://picsum.photos/seed/trail1/400/440",
		"https://picsum.photos/seed/trail2/400/440",
		"https://picsum.photos/seed/trail3/400/440",
		"https://picsum.photos/seed/trail4/400/440",
		"https://picsum.photos/seed/trail5/400/440",
		"https://picsum.photos/seed/trail6/400/440",
		"https://picsum.photos/seed/trail7/400/440",
		"https://picsum.photos/seed/trail8/400/440",
	];

	const variants: { type: VariantType; label: string }[] = [
		{ type: "type1", label: "Fade & Scale" },
		{ type: "type2", label: "Brightness" },
		{ type: "type3", label: "Float-up" },
		{ type: "type4", label: "Momentum" },
		{ type: "type5", label: "Rotation" },
		{ type: "type6", label: "Speed-reactive" },
		{ type: "type7", label: "Stacking" },
		{ type: "type8", label: "3D Perspective" },
	];

	let selectedVariant: VariantType = $state("type1");
</script>

<div class="w-full">
	<div class="mb-4 flex flex-wrap gap-2">
		{#each variants as v}
			<button
				class="rounded-lg border px-3 py-1.5 text-sm transition-colors {selectedVariant === v.type
					? 'border-primary bg-primary text-primary-foreground'
					: 'border-border bg-card hover:bg-accent'}"
				onclick={() => (selectedVariant = v.type)}
			>
				{v.label}
			</button>
		{/each}
	</div>
	<div class="relative h-[500px] cursor-crosshair overflow-hidden rounded-lg border">
		<ImageTrailCursor {images} variant={selectedVariant} />
		<div class="pointer-events-none absolute inset-0 flex items-center justify-center">
			<p class="text-muted-foreground text-lg font-medium select-none">Move your cursor here</p>
		</div>
	</div>
</div>
```

### Animation Variants

9 different trail animation styles, including a hard-edge pixelated snap.

```svelte
<script lang="ts">
	import { ImageTrailCursor } from "fancy-ui-svelte";
	import type { VariantType } from "fancy-ui-svelte";

	const images = [
		"https://picsum.photos/seed/trail1/400/440",
		"https://picsum.photos/seed/trail2/400/440",
		"https://picsum.photos/seed/trail3/400/440",
		"https://picsum.photos/seed/trail4/400/440",
		"https://picsum.photos/seed/trail5/400/440",
		"https://picsum.photos/seed/trail6/400/440",
	];

	const variants: { type: VariantType; label: string }[] = [
		{ type: "type1", label: "Fade & Scale" },
		{ type: "type2", label: "Brightness" },
		{ type: "type3", label: "Float-up" },
		{ type: "type4", label: "Momentum" },
		{ type: "type5", label: "Rotation" },
		{ type: "type6", label: "Speed-reactive" },
		{ type: "type7", label: "Stacking" },
		{ type: "type8", label: "3D Perspective" },
		{ type: "pixelated", label: "Pixelated" },
	];

	let selectedVariant: VariantType = $state("type1");
</script>

<div class="mb-4 flex flex-wrap gap-2">
	{#each variants as v}
		<button
			class="rounded-lg border px-3 py-1.5 text-sm transition-colors {selectedVariant === v.type
				? 'border-primary bg-primary text-primary-foreground'
				: 'border-border bg-card hover:bg-accent'}"
			onclick={() => (selectedVariant = v.type)}
		>
			{v.label}
		</button>
	{/each}
</div>
<div class="relative h-[400px] cursor-crosshair overflow-hidden rounded-lg border">
	<ImageTrailCursor {images} variant={selectedVariant} />
	<div class="pointer-events-none absolute inset-0 flex items-center justify-center">
		<p class="text-muted-foreground/50 text-lg select-none">Move your cursor here</p>
	</div>
</div>
```
