{
  "name": "background-gradient-animation",
  "type": "registry:ui",
  "files": [
    {
      "path": "components/ui/background-gradient-animation.tsx",
      "content": "\"use client\";\nimport { cn } from \"@/lib/utils\";\nimport { useEffect, useRef, useState } from \"react\";\n\nexport const BackgroundGradientAnimation = ({\n  gradientBackgroundStart = \"rgb(108, 0, 162)\",\n  gradientBackgroundEnd = \"rgb(0, 17, 82)\",\n  firstColor = \"18, 113, 255\",\n  secondColor = \"221, 74, 255\",\n  thirdColor = \"100, 220, 255\",\n  fourthColor = \"200, 50, 50\",\n  fifthColor = \"180, 180, 50\",\n  pointerColor = \"140, 100, 255\",\n  size = \"80%\",\n  blendingValue = \"hard-light\",\n  children,\n  className,\n  interactive = true,\n  containerClassName,\n}: {\n  gradientBackgroundStart?: string;\n  gradientBackgroundEnd?: string;\n  firstColor?: string;\n  secondColor?: string;\n  thirdColor?: string;\n  fourthColor?: string;\n  fifthColor?: string;\n  pointerColor?: string;\n  size?: string;\n  blendingValue?: string;\n  children?: React.ReactNode;\n  className?: string;\n  interactive?: boolean;\n  containerClassName?: string;\n}) => {\n  const interactiveRef = useRef<HTMLDivElement>(null);\n\n  const [curX, setCurX] = useState(0);\n  const [curY, setCurY] = useState(0);\n  const [tgX, setTgX] = useState(0);\n  const [tgY, setTgY] = useState(0);\n  useEffect(() => {\n    document.body.style.setProperty(\n      \"--gradient-background-start\",\n      gradientBackgroundStart\n    );\n    document.body.style.setProperty(\n      \"--gradient-background-end\",\n      gradientBackgroundEnd\n    );\n    document.body.style.setProperty(\"--first-color\", firstColor);\n    document.body.style.setProperty(\"--second-color\", secondColor);\n    document.body.style.setProperty(\"--third-color\", thirdColor);\n    document.body.style.setProperty(\"--fourth-color\", fourthColor);\n    document.body.style.setProperty(\"--fifth-color\", fifthColor);\n    document.body.style.setProperty(\"--pointer-color\", pointerColor);\n    document.body.style.setProperty(\"--size\", size);\n    document.body.style.setProperty(\"--blending-value\", blendingValue);\n  }, []);\n\n  useEffect(() => {\n    function move() {\n      if (!interactiveRef.current) {\n        return;\n      }\n      setCurX(curX + (tgX - curX) / 20);\n      setCurY(curY + (tgY - curY) / 20);\n      interactiveRef.current.style.transform = `translate(${Math.round(\n        curX\n      )}px, ${Math.round(curY)}px)`;\n    }\n\n    move();\n  }, [tgX, tgY]);\n\n  const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {\n    if (interactiveRef.current) {\n      const rect = interactiveRef.current.getBoundingClientRect();\n      setTgX(event.clientX - rect.left);\n      setTgY(event.clientY - rect.top);\n    }\n  };\n\n  const [isSafari, setIsSafari] = useState(false);\n  useEffect(() => {\n    setIsSafari(/^((?!chrome|android).)*safari/i.test(navigator.userAgent));\n  }, []);\n\n  return (\n    <div\n      className={cn(\n        \"h-screen w-screen relative overflow-hidden top-0 left-0 bg-[linear-gradient(40deg,var(--gradient-background-start),var(--gradient-background-end))]\",\n        containerClassName\n      )}\n    >\n      <svg className=\"hidden\">\n        <defs>\n          <filter id=\"blurMe\">\n            <feGaussianBlur\n              in=\"SourceGraphic\"\n              stdDeviation=\"10\"\n              result=\"blur\"\n            />\n            <feColorMatrix\n              in=\"blur\"\n              mode=\"matrix\"\n              values=\"1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -8\"\n              result=\"goo\"\n            />\n            <feBlend in=\"SourceGraphic\" in2=\"goo\" />\n          </filter>\n        </defs>\n      </svg>\n      <div className={cn(\"\", className)}>{children}</div>\n      <div\n        className={cn(\n          \"gradients-container h-full w-full blur-lg\",\n          isSafari ? \"blur-2xl\" : \"[filter:url(#blurMe)_blur(40px)]\"\n        )}\n      >\n        <div\n          className={cn(\n            `absolute [background:radial-gradient(circle_at_center,_var(--first-color)_0,_var(--first-color)_50%)_no-repeat]`,\n            `[mix-blend-mode:var(--blending-value)] w-[var(--size)] h-[var(--size)] top-[calc(50%-var(--size)/2)] left-[calc(50%-var(--size)/2)]`,\n            `[transform-origin:center_center]`,\n            `animate-first`,\n            `opacity-100`\n          )}\n        ></div>\n        <div\n          className={cn(\n            `absolute [background:radial-gradient(circle_at_center,_rgba(var(--second-color),_0.8)_0,_rgba(var(--second-color),_0)_50%)_no-repeat]`,\n            `[mix-blend-mode:var(--blending-value)] w-[var(--size)] h-[var(--size)] top-[calc(50%-var(--size)/2)] left-[calc(50%-var(--size)/2)]`,\n            `[transform-origin:calc(50%-400px)]`,\n            `animate-second`,\n            `opacity-100`\n          )}\n        ></div>\n        <div\n          className={cn(\n            `absolute [background:radial-gradient(circle_at_center,_rgba(var(--third-color),_0.8)_0,_rgba(var(--third-color),_0)_50%)_no-repeat]`,\n            `[mix-blend-mode:var(--blending-value)] w-[var(--size)] h-[var(--size)] top-[calc(50%-var(--size)/2)] left-[calc(50%-var(--size)/2)]`,\n            `[transform-origin:calc(50%+400px)]`,\n            `animate-third`,\n            `opacity-100`\n          )}\n        ></div>\n        <div\n          className={cn(\n            `absolute [background:radial-gradient(circle_at_center,_rgba(var(--fourth-color),_0.8)_0,_rgba(var(--fourth-color),_0)_50%)_no-repeat]`,\n            `[mix-blend-mode:var(--blending-value)] w-[var(--size)] h-[var(--size)] top-[calc(50%-var(--size)/2)] left-[calc(50%-var(--size)/2)]`,\n            `[transform-origin:calc(50%-200px)]`,\n            `animate-fourth`,\n            `opacity-70`\n          )}\n        ></div>\n        <div\n          className={cn(\n            `absolute [background:radial-gradient(circle_at_center,_rgba(var(--fifth-color),_0.8)_0,_rgba(var(--fifth-color),_0)_50%)_no-repeat]`,\n            `[mix-blend-mode:var(--blending-value)] w-[var(--size)] h-[var(--size)] top-[calc(50%-var(--size)/2)] left-[calc(50%-var(--size)/2)]`,\n            `[transform-origin:calc(50%-800px)_calc(50%+800px)]`,\n            `animate-fifth`,\n            `opacity-100`\n          )}\n        ></div>\n\n        {interactive && (\n          <div\n            ref={interactiveRef}\n            onMouseMove={handleMouseMove}\n            className={cn(\n              `absolute [background:radial-gradient(circle_at_center,_rgba(var(--pointer-color),_0.8)_0,_rgba(var(--pointer-color),_0)_50%)_no-repeat]`,\n              `[mix-blend-mode:var(--blending-value)] w-full h-full -top-1/2 -left-1/2`,\n              `opacity-70`\n            )}\n          ></div>\n        )}\n      </div>\n    </div>\n  );\n};\n",
      "type": "registry:ui",
      "target": "components/ui/background-gradient-animation.tsx"
    }
  ],
  "author": "Manu Arora <hi@manuarora.in>",
  "title": "Background Gradient Animation"
}