{
  "name": "3d-marquee",
  "type": "registry:ui",
  "files": [
    {
      "path": "components/ui/3d-marquee.tsx",
      "content": "\"use client\";\n\nimport { motion } from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\nexport const ThreeDMarquee = ({\n  images,\n  className,\n}: {\n  images: string[];\n  className?: string;\n}) => {\n  // Split the images array into 4 equal parts\n  const chunkSize = Math.ceil(images.length / 4);\n  const chunks = Array.from({ length: 4 }, (_, colIndex) => {\n    const start = colIndex * chunkSize;\n    return images.slice(start, start + chunkSize);\n  });\n  return (\n    <div\n      className={cn(\n        \"mx-auto block h-[600px] overflow-hidden rounded-2xl max-sm:h-100\",\n        className,\n      )}\n    >\n      <div className=\"flex size-full items-center justify-center\">\n        <div className=\"size-[1720px] shrink-0 scale-50 sm:scale-75 lg:scale-100\">\n          <div\n            style={{\n              transform: \"rotateX(55deg) rotateY(0deg) rotateZ(-45deg)\",\n            }}\n            className=\"relative top-96 right-[50%] grid size-full origin-top-left grid-cols-4 gap-8 transform-3d\"\n          >\n            {chunks.map((subarray, colIndex) => (\n              <motion.div\n                animate={{ y: colIndex % 2 === 0 ? 100 : -100 }}\n                transition={{\n                  duration: colIndex % 2 === 0 ? 10 : 15,\n                  repeat: Infinity,\n                  repeatType: \"reverse\",\n                }}\n                key={colIndex + \"marquee\"}\n                className=\"flex flex-col items-start gap-8\"\n              >\n                <GridLineVertical className=\"-left-4\" offset=\"80px\" />\n                {subarray.map((image, imageIndex) => (\n                  <div className=\"relative\" key={imageIndex + image}>\n                    <GridLineHorizontal className=\"-top-4\" offset=\"20px\" />\n                    <motion.img\n                      whileHover={{\n                        y: -10,\n                      }}\n                      transition={{\n                        duration: 0.3,\n                        ease: \"easeInOut\",\n                      }}\n                      key={imageIndex + image}\n                      src={image}\n                      alt={`Image ${imageIndex + 1}`}\n                      className=\"aspect-[970/700] rounded-lg object-cover ring ring-gray-950/5 hover:shadow-2xl\"\n                      width={970}\n                      height={700}\n                    />\n                  </div>\n                ))}\n              </motion.div>\n            ))}\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n};\n\nconst GridLineHorizontal = ({\n  className,\n  offset,\n}: {\n  className?: string;\n  offset?: string;\n}) => {\n  return (\n    <div\n      style={\n        {\n          \"--background\": \"#ffffff\",\n          \"--color\": \"rgba(0, 0, 0, 0.2)\",\n          \"--height\": \"1px\",\n          \"--width\": \"5px\",\n          \"--fade-stop\": \"90%\",\n          \"--offset\": offset || \"200px\", //-100px if you want to keep the line inside\n          \"--color-dark\": \"rgba(255, 255, 255, 0.2)\",\n          maskComposite: \"exclude\",\n        } as React.CSSProperties\n      }\n      className={cn(\n        \"absolute left-[calc(var(--offset)/2*-1)] h-[var(--height)] w-[calc(100%+var(--offset))]\",\n        \"bg-[linear-gradient(to_right,var(--color),var(--color)_50%,transparent_0,transparent)]\",\n        \"[background-size:var(--width)_var(--height)]\",\n        \"[mask:linear-gradient(to_left,var(--background)_var(--fade-stop),transparent),_linear-gradient(to_right,var(--background)_var(--fade-stop),transparent),_linear-gradient(black,black)]\",\n        \"[mask-composite:exclude]\",\n        \"z-30\",\n        \"dark:bg-[linear-gradient(to_right,var(--color-dark),var(--color-dark)_50%,transparent_0,transparent)]\",\n        className,\n      )}\n    ></div>\n  );\n};\n\nconst GridLineVertical = ({\n  className,\n  offset,\n}: {\n  className?: string;\n  offset?: string;\n}) => {\n  return (\n    <div\n      style={\n        {\n          \"--background\": \"#ffffff\",\n          \"--color\": \"rgba(0, 0, 0, 0.2)\",\n          \"--height\": \"5px\",\n          \"--width\": \"1px\",\n          \"--fade-stop\": \"90%\",\n          \"--offset\": offset || \"150px\", //-100px if you want to keep the line inside\n          \"--color-dark\": \"rgba(255, 255, 255, 0.2)\",\n          maskComposite: \"exclude\",\n        } as React.CSSProperties\n      }\n      className={cn(\n        \"absolute top-[calc(var(--offset)/2*-1)] h-[calc(100%+var(--offset))] w-[var(--width)]\",\n        \"bg-[linear-gradient(to_bottom,var(--color),var(--color)_50%,transparent_0,transparent)]\",\n        \"[background-size:var(--width)_var(--height)]\",\n        \"[mask:linear-gradient(to_top,var(--background)_var(--fade-stop),transparent),_linear-gradient(to_bottom,var(--background)_var(--fade-stop),transparent),_linear-gradient(black,black)]\",\n        \"[mask-composite:exclude]\",\n        \"z-30\",\n        \"dark:bg-[linear-gradient(to_bottom,var(--color-dark),var(--color-dark)_50%,transparent_0,transparent)]\",\n        className,\n      )}\n    ></div>\n  );\n};\n",
      "type": "registry:ui",
      "target": "components/ui/3d-marquee.tsx"
    }
  ],
  "author": "Manu Arora <hi@manuarora.in>",
  "title": "3d Marquee"
}