"use client";
import { ul } from "@/lib/utils";
import { useEffect, useState } from "react";
export const BackgroundGradientAnimation = ({
gradientBackgroundStart = "rgb(0, 0, 0)", // Dark background
gradientBackgroundEnd = "rgb(10, 10, 10)", // Slightly lighter dark background
firstColor = "0, 255, 255", // Electric cyan
secondColor = "0, 200, 255", // Electric blue
thirdColor = "255, 0, 255", // Electric magenta
fourthColor = "200, 0, 255", // Deep electric purple
fifthColor = "150, 0, 255", // Dark electric purple
pointerColor = "0, 255, 255", // Electric cyan for pointer
size = "80%",
blendingValue = "overlay",
children,
className,
interactive = true,
containerClassName,
}: {
gradientBackgroundStart?: string;
gradientBackgroundEnd?: string;
firstColor?: string;
secondColor?: string;
thirdColor?: string;
fourthColor?: string;
fifthColor?: string;
pointerColor?: string;
size?: string;
blendingValue?: string;
children?: React.ReactNode;
className?: string;
interactive?: boolean;
containerClassName?: string;
}) => {
const [curX, setCurX] = useState(0);
const [curY, setCurY] = useState(0);
const [tgX, setTgX] = useState(0);
const [tgY, setTgY] = useState(0);
useEffect(() => {
document.body.style.setProperty(
"--gradient-background-start",
gradientBackgroundStart
);
document.body.style.setProperty(
"--gradient-background-end",
gradientBackgroundEnd
);
document.body.style.setProperty("--first-color", firstColor);
document.body.style.setProperty("--second-color", secondColor);
document.body.style.setProperty("--third-color", thirdColor);
document.body.style.setProperty("--fourth-color", fourthColor);
document.body.style.setProperty("--fifth-color", fifthColor);
document.body.style.setProperty("--pointer-color", pointerColor);
document.body.style.setProperty("--size", size);
document.body.style.setProperty("--blending-value", blendingValue);
}, [gradientBackgroundStart, gradientBackgroundEnd, firstColor, secondColor, thirdColor, fourthColor, fifthColor, pointerColor, size, blendingValue]);
useEffect(() => {
function move() {
setCurX((prevX) => prevX + (tgX - prevX) / 20);
setCurY((prevY) => prevY + (tgY - prevY) / 20);
}
move();
}, [tgX, tgY]);
const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {
const rect = event.currentTarget.getBoundingClientRect();
setTgX(event.clientX - rect.left);
setTgY(event.clientY - rect.top);
};
const [isSafari, setIsSafari] = useState(false);
useEffect(() => {
setIsSafari(/^((?!chrome|android).)*safari/i.test(navigator.userAgent));
}, []);
return (
<div
className={ul(
"h-screen w-screen relative overflow-hidden top-0 left-0 bg-[linear-gradient(135deg,var(--gradient-background-start),var(--gradient-background-end))]",
containerClassName
)}
onMouseMove={handleMouseMove}
>
<svg className="hidden">
<defs>
<filter id="blurMe">
<feGaussianBlur
in="SourceGraphic"
stdDeviation="10"
result="blur"
/>
<feColorMatrix
in="blur"
mode="matrix"
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 20 -10"
result="goo"
/>
<feBlend in="SourceGraphic" in2="goo" />
</filter>
</defs>
</svg>
<div className={ul("", className)}>{children}</div>
<div
className={ul(
"gradients-container h-full w-full blur-lg",
isSafari ? "blur-2xl" : "[filter:url(#blurMe)_blur(40px)]"
)}
>
<div
className={ul(
`absolute [background:radial-gradient(circle_at_top_left,_rgba(var(--first-color),_0.4)_0,_rgba(var(--first-color),_0)_50%)_no-repeat]`,
`[mix-blend-mode:var(--blending-value)] w-[var(--size)] h-[var(--size)] top-0 left-0`,
`[transform-origin:top_left]`,
`animate-first`,
`opacity-100`
)}
></div>
<div
className={ul(
`absolute [background:radial-gradient(circle_at_top_left,_rgba(var(--second-color),_0.4)_0,_rgba(var(--second-color),_0)_50%)_no-repeat]`,
`[mix-blend-mode:var(--blending-value)] w-[var(--size)] h-[var(--size)] top-0 left-0`,
`[transform-origin:top_left]`,
`animate-second`,
`opacity-100`
)}
></div>
<div
className={ul(
`absolute [background:radial-gradient(circle_at_top_left,_rgba(var(--third-color),_0.4)_0,_rgba(var(--third-color),_0)_50%)_no-repeat]`,
`[mix-blend-mode:var(--blending-value)] w-[var(--size)] h-[var(--size)] top-0 left-0`,
`[transform-origin:top_left]`,
`animate-third`,
`opacity-100`
)}
></div>
<div
className={ul(
`absolute [background:radial-gradient(circle_at_top_left,_rgba(var(--fourth-color),_0.4)_0,_rgba(var(--fourth-color),_0)_50%)_no-repeat]`,
`[mix-blend-mode:var(--blending-value)] w-[var(--size)] h-[var(--size)] top-0 left-0`,
`[transform-origin:top_left]`,
`animate-fourth`,
`opacity-70`
)}
></div>
<div
className={ul(
`absolute [background:radial-gradient(circle_at_top_left,_rgba(var(--fifth-color),_0.4)_0,_rgba(var(--fifth-color),_0)_50%)_no-repeat]`,
`[mix-blend-mode:var(--blending-value)] w-[var(--size)] h-[var(--size)] top-0 left-0`,
`[transform-origin:top_left]`,
`animate-fifth`,
`opacity-100`
)}
></div>
{interactive && (
<div
className={ul(
`absolute [background:radial-gradient(circle_at_top_left,_rgba(var(--pointer-color),_0.4)_0,_rgba(var(--pointer-color),_0)_50%)_no-repeat]`,
`[mix-blend-mode:var(--blending-value)] w-full h-full -top-1/2 -left-1/2`,
`opacity-70`
)}
></div>
)}
</div>
</div>
);
};