fix: rewrite 5 broken background components from Aceternity sources

- Aurora: remove invert filter (broken on dark bg), use dark gradient directly
- Beams: use animated linearGradient positions instead of pathLength animation
- Beams Collision: add collision detection, explosion particles, AnimatePresence
- Gemini Effect: rewrite as SVG motion.path with animated pathLength (was canvas)
- Noise: change mixBlendMode from overlay to screen (overlay invisible on dark bg)
This commit is contained in:
Fringg
2026-02-25 07:31:16 +03:00
parent 1a702a68b9
commit de97a030d2
5 changed files with 320 additions and 216 deletions

View File

@@ -1,4 +1,4 @@
import { useEffect, useRef } from 'react';
import React from 'react';
import { motion } from 'framer-motion';
interface Props {
@@ -16,61 +16,94 @@ const paths = [
'M-331 -245C-331 -245 -263 160 201 287C665 414 733 819 733 819',
'M-324 -253C-324 -253 -256 152 208 279C672 406 740 811 740 811',
'M-317 -261C-317 -261 -249 144 215 271C679 398 747 803 747 803',
'M-310 -269C-310 -269 -242 136 222 263C686 390 754 795 754 795',
'M-303 -277C-303 -277 -235 128 229 255C693 382 761 787 761 787',
'M-296 -285C-296 -285 -228 120 236 247C700 374 768 779 768 779',
'M-289 -293C-289 -293 -221 112 243 239C707 366 775 771 775 771',
'M-282 -301C-282 -301 -214 104 250 231C714 358 782 763 782 763',
'M-275 -309C-275 -309 -207 96 257 223C721 350 789 755 789 755',
'M-268 -317C-268 -317 -200 88 264 215C728 342 796 747 796 747',
'M-261 -325C-261 -325 -193 80 271 207C735 334 803 739 803 739',
'M-254 -333C-254 -333 -186 72 278 199C742 326 810 731 810 731',
'M-247 -341C-247 -341 -179 64 285 191C749 318 817 723 817 723',
];
export default function BackgroundBeams({ settings: _settings }: Props) {
const svgRef = useRef<SVGSVGElement>(null);
useEffect(() => {
const handleVisibility = () => {
if (svgRef.current) {
svgRef.current.style.display = document.hidden ? 'none' : '';
}
};
document.addEventListener('visibilitychange', handleVisibility);
return () => document.removeEventListener('visibilitychange', handleVisibility);
}, []);
// Static background paths (subset for the radial gradient overlay)
const bgPath =
'M-380 -189C-380 -189 -312 216 152 343C616 470 684 875 684 875M-373 -197C-373 -197 -305 208 159 335C623 462 691 867 691 867M-366 -205C-366 -205 -298 200 166 327C630 454 698 859 698 859M-359 -213C-359 -213 -291 192 173 319C637 446 705 851 705 851M-352 -221C-352 -221 -284 184 180 311C644 438 712 843 712 843M-345 -229C-345 -229 -277 176 187 303C651 430 719 835 719 835M-338 -237C-338 -237 -270 168 194 295C658 422 726 827 726 827M-331 -245C-331 -245 -263 160 201 287C665 414 733 819 733 819M-324 -253C-324 -253 -256 152 208 279C672 406 740 811 740 811M-317 -261C-317 -261 -249 144 215 271C679 398 747 803 747 803';
export default React.memo(function BackgroundBeams({ settings: _settings }: Props) {
return (
<div className="absolute inset-0 overflow-hidden">
<svg
ref={svgRef}
className="pointer-events-none absolute inset-0 h-full w-full"
width="100%"
height="100%"
viewBox="0 0 696 316"
fill="none"
preserveAspectRatio="xMidYMid slice"
xmlns="http://www.w3.org/2000/svg"
>
{paths.map((path, i) => (
{/* Static background paths */}
<path d={bgPath} stroke="url(#paint0_radial)" strokeOpacity="0.05" strokeWidth="0.5" />
{/* Animated beam paths with moving gradients */}
{paths.map((path, index) => (
<motion.path
key={i}
key={`path-${index}`}
d={path}
stroke={`url(#beam-gradient-${i})`}
stroke={`url(#linearGradient-${index})`}
strokeOpacity="0.4"
strokeWidth="0.5"
strokeOpacity="0.1"
initial={{ pathLength: 0, opacity: 0 }}
animate={{
pathLength: 1,
opacity: [0, 0.3, 0.6, 0.3, 0],
}}
transition={{
duration: 4 + i * 0.5,
ease: 'easeInOut',
repeat: Infinity,
delay: i * 0.3,
}}
/>
))}
<defs>
{paths.map((_, i) => (
<linearGradient key={i} id={`beam-gradient-${i}`} gradientUnits="userSpaceOnUse">
{/* Animated linear gradients that move along the paths */}
{paths.map((_, index) => (
<motion.linearGradient
id={`linearGradient-${index}`}
key={`gradient-${index}`}
initial={{
x1: '0%',
x2: '0%',
y1: '0%',
y2: '0%',
}}
animate={{
x1: ['0%', '100%'],
x2: ['0%', '95%'],
y1: ['0%', '100%'],
y2: ['0%', `${93 + Math.random() * 8}%`],
}}
transition={{
duration: Math.random() * 10 + 10,
ease: 'easeInOut',
repeat: Infinity,
delay: Math.random() * 10,
}}
>
<stop stopColor="#18CCFC" stopOpacity="0" />
<stop stopColor="#18CCFC" />
<stop offset="0.325" stopColor="#6344F5" />
<stop offset="1" stopColor="#AE48FF" stopOpacity="0" />
</linearGradient>
<stop offset="32.5%" stopColor="#6344F5" />
<stop offset="100%" stopColor="#AE48FF" stopOpacity="0" />
</motion.linearGradient>
))}
{/* Radial gradient for static background */}
<radialGradient
id="paint0_radial"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(352 34) rotate(90) scale(555 1560.62)"
>
<stop offset="0.0666667" stopColor="#d4d4d4" />
<stop offset="0.243243" stopColor="#d4d4d4" />
<stop offset="0.43594" stopColor="white" stopOpacity="0" />
</radialGradient>
</defs>
</svg>
</div>
);
}
});