{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "image-text",
  "type": "registry:component",
  "title": "Image Text",
  "description": "Text with a dynamic, animated image mask background.",
  "dependencies": [
    "motion"
  ],
  "files": [
    {
      "path": "registry/new-york/animations/specials/image-text.tsx",
      "content": "\"use client\";\n\nimport React, { useState, useEffect } from \"react\";\nimport { motion, HTMLMotionProps, AnimatePresence } from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\n\ninterface ImageTextProps extends HTMLMotionProps<\"h1\"> {\n    text: string;\n    imageUrl: string | string[] | { src: string } | { src: string }[];\n    className?: string;\n    direction?: \"horizontal\" | \"vertical\" | \"diagonal\" | \"none\";\n    interval?: number;\n}\n\nexport function ImageText({\n    text,\n    imageUrl,\n    className,\n    direction = \"horizontal\",\n    interval = 3000,\n    ...props\n}: ImageTextProps) {\n    const images = Array.isArray(imageUrl) ? imageUrl : [imageUrl];\n    const [currentImageIndex, setCurrentImageIndex] = useState(0);\n\n    useEffect(() => {\n        if (!Array.isArray(imageUrl) || imageUrl.length <= 1) return;\n\n        const timer = setInterval(() => {\n            setCurrentImageIndex((prev) => (prev + 1) % images.length);\n        }, interval);\n\n        return () => clearInterval(timer);\n    }, [imageUrl, interval, images.length]);\n\n    // Helper to handle both string URLs and StaticImageData objects\n    const getCurrentImageUrl = () => {\n        const img = images[currentImageIndex];\n        return typeof img === \"string\" ? img : img.src;\n    };\n\n    const getAnimation = () => {\n        switch (direction) {\n            case \"horizontal\":\n                return {\n                    backgroundPosition: [\"0% 50%\", \"100% 50%\", \"0% 50%\"],\n                };\n            case \"vertical\":\n                return {\n                    backgroundPosition: [\"50% 0%\", \"50% 100%\", \"50% 0%\"],\n                };\n            case \"diagonal\":\n                return {\n                    backgroundPosition: [\"0% 0%\", \"100% 100%\", \"0% 0%\"],\n                };\n            case \"none\":\n                return {\n                    backgroundPosition: \"center\",\n                }\n            default:\n                return {\n                    backgroundPosition: [\"0% 50%\", \"100% 50%\", \"0% 50%\"],\n                };\n        }\n    };\n\n    return (\n        <span className={cn(\"inline-block relative\", className)}>\n            {/* Invisible layout placeholder ensuring size doesn't collapse */}\n            <h1 className={cn(\"text-9xl font-serif italic font-bold tracking-tighter inline-block invisible\", className)}>\n                {text}\n            </h1>\n\n            <AnimatePresence>\n                <motion.h1\n                    key={currentImageIndex} // Re-render for image change\n                    className={cn(\n                        \"text-9xl font-serif italic font-bold tracking-tighter inline-block absolute inset-0\",\n                        className\n                    )}\n                    style={{\n                        backgroundImage: `url(${getCurrentImageUrl()})`,\n                        backgroundSize: direction === \"none\" ? \"cover\" : \"150% auto\",\n                        backgroundClip: \"text\",\n                        WebkitBackgroundClip: \"text\",\n                        WebkitTextFillColor: \"transparent\",\n                        color: \"transparent\",\n                    }}\n                    initial={{ opacity: 0 }}\n                    animate={{\n                        ...getAnimation(),\n                        opacity: 1\n                    }}\n                    exit={{ opacity: 0 }}\n                    transition={{\n                        // Smooth opacity fade for texture change\n                        opacity: { duration: 1 },\n                        // Continuous background movement\n                        backgroundPosition: {\n                            duration: 15,\n                            ease: \"linear\",\n                            repeat: Infinity,\n                        }\n                    }}\n                    {...props}\n                >\n                    {text}\n                </motion.h1>\n            </AnimatePresence>\n        </span>\n    );\n}\n",
      "type": "registry:component"
    }
  ]
}