{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "preloader",
  "type": "registry:block",
  "title": "Preloader",
  "description": "Preloader",
  "files": [
    {
      "path": "components/usages/preloaderusage.tsx",
      "content": "\"use client\";\n\nimport React, { useEffect, useState } from \"react\";\n\nimport { AnimatePresence } from \"motion/react\";\n\nfunction Page({ children }) {\n\tconst [loader, setLoader] = useState(false);\n\n\tuseEffect(() => {\n\t\tsetTimeout(() => {\n\t\t\tsetLoader(false);\n\t\t}, 2250);\n\t}, [loader]);\n\n\treturn (\n\t\t<span className=\"mt-6 block\">\n\t\t\t{!loader && (\n\t\t\t\t<button onClick={() => setLoader(true)}>reset preloader</button>\n\t\t\t)}\n\n\t\t\t<AnimatePresence mode=\"wait\">{loader && children}</AnimatePresence>\n\n\t\t\t{!loader && <div>your content goes here</div>}\n\t\t</span>\n\t);\n}\nexport default Page;\n",
      "type": "registry:block",
      "target": "~/example.tsx"
    },
    {
      "path": "components/usages/preloaderusage.tsx",
      "content": "\"use client\";\n\nimport React, { useEffect, useState } from \"react\";\n\nimport { AnimatePresence } from \"motion/react\";\n\nfunction Page({ children }) {\n\tconst [loader, setLoader] = useState(false);\n\n\tuseEffect(() => {\n\t\tsetTimeout(() => {\n\t\t\tsetLoader(false);\n\t\t}, 2250);\n\t}, [loader]);\n\n\treturn (\n\t\t<span className=\"mt-6 block\">\n\t\t\t{!loader && (\n\t\t\t\t<button onClick={() => setLoader(true)}>reset preloader</button>\n\t\t\t)}\n\n\t\t\t<AnimatePresence mode=\"wait\">{loader && children}</AnimatePresence>\n\n\t\t\t{!loader && <div>your content goes here</div>}\n\t\t</span>\n\t);\n}\nexport default Page;\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/open-source/preloader.tsx",
      "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport { motion } from \"motion/react\";\n\nimport { MouseImageTrail } from \"./mouse-image-trail\";\n\n// Credit:\n// https://www.sparkui.site/components/apple-preloader\n\nconst opacity = {\n\tinitial: {\n\t\topacity: 0,\n\t},\n\tenter: {\n\t\topacity: 0.75,\n\t\ttransition: { duration: 1, delay: 0.2 },\n\t},\n};\n\nconst slideUp = {\n\tinitial: {\n\t\ttop: 0,\n\t},\n\texit: {\n\t\ttop: \"-100vh\",\n\t\ttransition: { duration: 0.8, ease: [0.76, 0, 0.24, 1], delay: 0.2 },\n\t},\n};\n\nconst words = [\"Move\", \"yo\", \"mouse\", \"...\", \"see\", \"what\", \"we\", \"got\"];\n\nexport default function Preloader() {\n\tconst [index, setIndex] = useState(0);\n\tconst [dimension, setDimension] = useState({ width: 0, height: 0 });\n\n\tuseEffect(() => {\n\t\tsetDimension({ width: window.innerWidth, height: window.innerHeight });\n\t}, []);\n\n\tuseEffect(() => {\n\t\tif (index === words.length - 1) return;\n\t\tsetTimeout(\n\t\t\t() => {\n\t\t\t\tsetIndex(index + 1);\n\t\t\t},\n\t\t\tindex === 0 ? 1000 : 150\n\t\t);\n\t}, [index]);\n\n\tconst initialPath = `M0 0 L${dimension.width} 0 L${dimension.width} ${\n\t\tdimension.height\n\t} Q${dimension.width / 2} ${dimension.height + 300} 0 ${\n\t\tdimension.height\n\t}  L0 0`;\n\tconst targetPath = `M0 0 L${dimension.width} 0 L${dimension.width} ${\n\t\tdimension.height\n\t} Q${dimension.width / 2} ${dimension.height} 0 ${dimension.height}  L0 0`;\n\n\tconst curve = {\n\t\tinitial: {\n\t\t\td: initialPath,\n\t\t\ttransition: { duration: 0.7, ease: [0.76, 0, 0.24, 1] },\n\t\t},\n\t\texit: {\n\t\t\td: targetPath,\n\t\t\ttransition: { duration: 0.7, ease: [0.76, 0, 0.24, 1], delay: 0.3 },\n\t\t},\n\t};\n\n\treturn (\n\t\t<motion.div\n\t\t\tvariants={slideUp}\n\t\t\tinitial=\"initial\"\n\t\t\texit=\"exit\"\n\t\t\tclassName=\"h-screen w-screen z-501 fixed top-0 left-0 bg-black\"\n\t\t>\n\t\t\t<MouseImageTrail\n\t\t\t\timages={[\n\t\t\t\t\t\"/itjustworks.jpg\",\n\t\t\t\t\t\"/itjustworks.jpg\",\n\t\t\t\t\t\"/itjustworks.jpg\",\n\t\t\t\t\t\"/itjustworks.jpg\",\n\t\t\t\t\t\"/itjustworks.jpg\",\n\t\t\t\t\t\"/itjustworks.jpg\",\n\t\t\t\t\t\"/itjustworks.jpg\",\n\t\t\t\t\t\"/itjustworks.jpg\",\n\t\t\t\t]}\n\t\t\t\trenderImageBuffer={150}\n\t\t\t\trotationRange={25}\n\t\t\t>\n\t\t\t\t<div className=\"h-screen w-screen flex items-center justify-center \">\n\t\t\t\t\t{dimension.width > 0 && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<motion.p\n\t\t\t\t\t\t\t\tvariants={opacity}\n\t\t\t\t\t\t\t\tinitial=\"initial\"\n\t\t\t\t\t\t\t\tanimate=\"enter\"\n\t\t\t\t\t\t\t\tclassName=\"flex bg-clip-text bg-linear-to-br to-[rgb(255,255,255,0.5)] from-[rgb(255,255,255,0.58)] font-medium text-[42px] items-center absolute z-1\"\n\t\t\t\t\t\t\t\tstyle={{ color: \"transparent\" }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{words[index]}\n\t\t\t\t\t\t\t</motion.p>\n\t\t\t\t\t\t\t<svg className=\"absolute top-0 w-full h-[calc(100% + 200px)]\">\n\t\t\t\t\t\t\t\t<motion.path\n\t\t\t\t\t\t\t\t\tvariants={curve}\n\t\t\t\t\t\t\t\t\tinitial=\"initial\"\n\t\t\t\t\t\t\t\t\texit=\"exit\"\n\t\t\t\t\t\t\t\t\tfill=\"#000\"\n\t\t\t\t\t\t\t\t></motion.path>\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</MouseImageTrail>\n\t\t</motion.div>\n\t);\n}\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/open-source/mouse-image-trail.tsx",
      "content": "import React, { MouseEventHandler, ReactNode, useRef } from \"react\";\r\n\r\nimport { useAnimate } from \"motion/react\";\r\n\r\n// www.hover.dev/components/other#mouse-image-trail\r\n\r\nexport const MouseImageTrail = ({\r\n\tchildren,\r\n\t// List of image sources\r\n\timages,\r\n\t// Will render a new image every X pixels between mouse moves\r\n\trenderImageBuffer,\r\n\t// images will be rotated at a random number between zero and rotationRange,\r\n\t// alternating between a positive and negative rotation\r\n\trotationRange,\r\n}: {\r\n\tchildren: ReactNode;\r\n\timages: string[];\r\n\trenderImageBuffer: number;\r\n\trotationRange: number;\r\n}) => {\r\n\tconst [scope, animate] = useAnimate();\r\n\r\n\tconst lastRenderPosition = useRef({ x: 0, y: 0 });\r\n\tconst imageRenderCount = useRef(0);\r\n\r\n\tconst handleMouseMove: MouseEventHandler<HTMLDivElement> = (e) => {\r\n\t\tconst { clientX, clientY } = e;\r\n\r\n\t\tconst distance = calculateDistance(\r\n\t\t\tclientX,\r\n\t\t\tclientY,\r\n\t\t\tlastRenderPosition.current.x,\r\n\t\t\tlastRenderPosition.current.y\r\n\t\t);\r\n\r\n\t\tif (distance >= renderImageBuffer) {\r\n\t\t\tlastRenderPosition.current.x = clientX;\r\n\t\t\tlastRenderPosition.current.y = clientY;\r\n\r\n\t\t\trenderNextImage();\r\n\t\t}\r\n\t};\r\n\r\n\tconst calculateDistance = (\r\n\t\tx1: number,\r\n\t\ty1: number,\r\n\t\tx2: number,\r\n\t\ty2: number\r\n\t) => {\r\n\t\tconst deltaX = x2 - x1;\r\n\t\tconst deltaY = y2 - y1;\r\n\r\n\t\t// Using the Pythagorean theorem to calculate the distance\r\n\t\tconst distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\r\n\r\n\t\treturn distance;\r\n\t};\r\n\r\n\tconst renderNextImage = () => {\r\n\t\tconst imageIndex = imageRenderCount.current % images?.length;\r\n\t\tconst selector = `[data-mouse-move-index=\"${imageIndex}\"]`;\r\n\r\n\t\tconst el = document.querySelector(selector) as HTMLElement;\r\n\r\n\t\tel.style.top = `${lastRenderPosition.current.y}px`;\r\n\t\tel.style.left = `${lastRenderPosition.current.x}px`;\r\n\t\tel.style.zIndex = imageRenderCount.current.toString();\r\n\r\n\t\tconst rotation = Math.random() * rotationRange;\r\n\r\n\t\tanimate(\r\n\t\t\tselector,\r\n\t\t\t{\r\n\t\t\t\topacity: [0, 1],\r\n\t\t\t\ttransform: [\r\n\t\t\t\t\t`translate(-50%, -25%) scale(0.5) ${\r\n\t\t\t\t\t\timageIndex % 2\r\n\t\t\t\t\t\t\t? `rotate(${rotation}deg)`\r\n\t\t\t\t\t\t\t: `rotate(-${rotation}deg)`\r\n\t\t\t\t\t}`,\r\n\t\t\t\t\t`translate(-50%, -50%) scale(1) ${\r\n\t\t\t\t\t\timageIndex % 2\r\n\t\t\t\t\t\t\t? `rotate(-${rotation}deg)`\r\n\t\t\t\t\t\t\t: `rotate(${rotation}deg)`\r\n\t\t\t\t\t}`,\r\n\t\t\t\t],\r\n\t\t\t},\r\n\t\t\t{ type: \"spring\", damping: 15, stiffness: 200 }\r\n\t\t);\r\n\r\n\t\tanimate(\r\n\t\t\tselector,\r\n\t\t\t{\r\n\t\t\t\topacity: [1, 0],\r\n\t\t\t},\r\n\t\t\t{ ease: \"linear\", duration: 0.5, delay: 5 }\r\n\t\t);\r\n\r\n\t\timageRenderCount.current = imageRenderCount.current + 1;\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tref={scope}\r\n\t\t\tclassName=\"relative overflow-hidden h-screen z-502\"\r\n\t\t\tonMouseMove={handleMouseMove}\r\n\t\t>\r\n\t\t\t{children}\r\n\r\n\t\t\t{images?.map((img, index) => (\r\n\t\t\t\t<img\r\n\t\t\t\t\tclassName=\"pointer-events-none absolute left-0 top-0 h-48 w-auto rounded-xl border-2 border-black bg-background object-cover opacity-0\"\r\n\t\t\t\t\tsrc={img}\r\n\t\t\t\t\talt={`Mouse move image ${index}`}\r\n\t\t\t\t\tkey={index + \"mouse-image-trail\"}\r\n\t\t\t\t\tdata-mouse-move-index={index}\r\n\t\t\t\t/>\r\n\t\t\t))}\r\n\t\t</div>\r\n\t);\r\n};\r\n",
      "type": "registry:ui"
    }
  ]
}