{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "cursorimagetrail",
  "type": "registry:ui",
  "title": "Cursor ImageTrail",
  "description": "mouse trail component with animated image effects on hover.",
  "author": "Ahdeetai <https://aditya.is-cool.dev>",
  "registryDependencies": [],
  "dependencies": ["motion"],
  "files": [
    {
      "type": "registry:ui",
      "path": "components/ui/cursorimagetrail.tsx",
      "content": "'use client';\n\nimport React, { useRef, ReactNode, MouseEventHandler } from 'react';\nimport { motion, useAnimate } from 'motion/react';\n\ninterface CursorImageTrailProps {\n  children: ReactNode;\n  images: string[];\n  renderImageBuffer: number;\n  rotationRange: number;\n  animationStyle?: 'dynamic' | 'minimal';\n}\n\nconst CursorImageTrail = ({\n  children,\n  images,\n  renderImageBuffer,\n  rotationRange,\n  animationStyle = 'dynamic',\n}: CursorImageTrailProps) => {\n  const [scope, animate] = useAnimate();\n  const lastRenderPosition = useRef({ x: 0, y: 0 });\n  const imageRenderCount = useRef(0);\n\n  const calculateDistance = (\n    x1: number,\n    y1: number,\n    x2: number,\n    y2: number,\n  ) => {\n    const deltaX = x2 - x1;\n    const deltaY = y2 - y1;\n    return Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n  };\n\n  const renderNextImage = () => {\n    const index = imageRenderCount.current % images.length;\n    const selector = `[data-mouse-move-index=\"${index}\"]`;\n    const el = document.querySelector(selector) as HTMLElement;\n    if (!el || !scope.current) return;\n\n    const containerRect = scope.current.getBoundingClientRect();\n    const relativeX = lastRenderPosition.current.x - containerRect.left;\n    const relativeY = lastRenderPosition.current.y - containerRect.top;\n\n    el.style.left = `${relativeX}px`;\n    el.style.top = `${relativeY}px`;\n    el.style.zIndex = `${imageRenderCount.current}`;\n\n    const rotation = Math.random() * rotationRange;\n\n    if (animationStyle === 'dynamic') {\n      const scale = 0.8 + Math.random() * 0.4;\n      const skewX = Math.random() * 10;\n      const skewY = Math.random() * 10;\n\n      animate(\n        selector,\n        {\n          opacity: [0, 1],\n          transform: [\n            `translate(-50%, -30%) scale(${scale}) rotate(${\n              index % 2 === 0 ? rotation : -rotation\n            }deg) skew(${skewX}deg, ${skewY}deg)`,\n            `translate(-50%, -50%) scale(1.1) rotate(${\n              index % 2 === 0 ? -rotation : rotation\n            }deg) skew(0deg, 0deg)`,\n          ],\n        },\n        { type: 'spring', stiffness: 150, damping: 20 },\n      );\n\n      animate(\n        selector,\n        {\n          opacity: [1, 0],\n          y: ['0%', '-40%'],\n        },\n        {\n          duration: 0.8,\n          ease: 'easeOut',\n          delay: 2,\n        },\n      );\n    } else {\n      animate(\n        selector,\n        {\n          opacity: [0, 1],\n          transform: [\n            `translate(-50%, -30%) scale(0.5) rotate(${\n              index % 2 === 0 ? rotation : -rotation\n            }deg)`,\n            `translate(-50%, -50%) scale(1.2) rotate(${\n              index % 2 === 0 ? -rotation : rotation\n            }deg)`,\n          ],\n        },\n        { type: 'spring', stiffness: 150, damping: 20 },\n      );\n\n      animate(\n        selector,\n        {\n          opacity: [1, 0],\n          y: ['0%', '-40%'],\n        },\n        {\n          duration: 0.8,\n          ease: 'easeOut',\n          delay: 2,\n        },\n      );\n    }\n\n    imageRenderCount.current += 1;\n  };\n\n  const handleMouseMove: MouseEventHandler<HTMLDivElement> = (e) => {\n    const { clientX, clientY } = e;\n    const distance = calculateDistance(\n      clientX,\n      clientY,\n      lastRenderPosition.current.x,\n      lastRenderPosition.current.y,\n    );\n    if (distance >= renderImageBuffer) {\n      lastRenderPosition.current = { x: clientX, y: clientY };\n      renderNextImage();\n    }\n  };\n\n  return (\n    <div\n      ref={scope as React.RefObject<HTMLDivElement>}\n      className='relative w-full h-full overflow-hidden'\n      onMouseMove={handleMouseMove}\n    >\n      {children}\n\n      {images.map((img, index) => (\n        <motion.img\n          key={index}\n          data-mouse-move-index={index}\n          src={img}\n          alt={`Mouse move image ${index}`}\n          className={\n            animationStyle === 'dynamic'\n              ? 'pointer-events-none absolute h-48 w-auto rounded-xl border border-black/30 bg-white/70 dark:border-white/20 dark:bg-neutral-900 opacity-0 shadow-md transition-all duration-300'\n              : 'pointer-events-none absolute h-48 w-auto rounded-xl border border-black bg-neutral-100 opacity-0 dark:border-neutral-800 dark:bg-neutral-900 backdrop-blur-md saturate-150'\n          }\n          initial={false}\n        />\n      ))}\n    </div>\n  );\n};\n\nexport default CursorImageTrail;\n"
    }
  ]
}
