feat: 添加预览效果页面并优化交互效果
refactor: 优化代码健壮性和类型安全 style: 更新字体样式和全局CSS fix: 修复IntersectionObserver潜在空引用问题 chore: 更新依赖和ESLint配置 build: 更新构建ID和路由配置
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
'use client';
|
||||
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
interface GradientOrbsProps {
|
||||
className?: string;
|
||||
count?: number;
|
||||
}
|
||||
|
||||
interface Orb {
|
||||
id: number;
|
||||
size: number;
|
||||
x: number;
|
||||
y: number;
|
||||
color: string;
|
||||
duration: number;
|
||||
delay: number;
|
||||
}
|
||||
|
||||
const colorPalette = [
|
||||
'rgba(196, 30, 58, 0.15)',
|
||||
'rgba(255, 232, 236, 0.2)',
|
||||
'rgba(255, 240, 243, 0.18)',
|
||||
'rgba(245, 245, 245, 0.15)',
|
||||
'rgba(255, 214, 221, 0.2)',
|
||||
'rgba(224, 74, 104, 0.12)',
|
||||
];
|
||||
|
||||
export function GradientOrbs({ className = '', count = 5 }: GradientOrbsProps) {
|
||||
const prefersReducedMotion = useReducedMotion();
|
||||
const [orbs, setOrbs] = useState<Orb[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const generatedOrbs: Orb[] = Array.from({ length: count }, (_, i) => ({
|
||||
id: i,
|
||||
size: Math.random() * 400 + 200,
|
||||
x: Math.random() * 100,
|
||||
y: Math.random() * 100,
|
||||
color: colorPalette[i % colorPalette.length] ?? 'rgba(196, 30, 58, 0.15)',
|
||||
duration: Math.random() * 20 + 15,
|
||||
delay: Math.random() * 5,
|
||||
}));
|
||||
setOrbs(generatedOrbs);
|
||||
}, [count]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`absolute inset-0 overflow-hidden ${className}`}
|
||||
aria-hidden="true"
|
||||
>
|
||||
{orbs.map((orb) => (
|
||||
<motion.div
|
||||
key={orb.id}
|
||||
className="absolute rounded-full"
|
||||
style={{
|
||||
width: orb.size,
|
||||
height: orb.size,
|
||||
left: `${orb.x}%`,
|
||||
top: `${orb.y}%`,
|
||||
background: `radial-gradient(circle, ${orb.color} 0%, transparent 70%)`,
|
||||
willChange: prefersReducedMotion ? 'auto' : 'transform',
|
||||
filter: 'blur(60px)',
|
||||
}}
|
||||
initial={{
|
||||
x: '-50%',
|
||||
y: '-50%',
|
||||
scale: 1,
|
||||
}}
|
||||
animate={
|
||||
prefersReducedMotion
|
||||
? {}
|
||||
: {
|
||||
x: ['-50%', '-40%', '-60%', '-50%'],
|
||||
y: ['-50%', '-60%', '-40%', '-50%'],
|
||||
scale: [1, 1.2, 0.9, 1],
|
||||
}
|
||||
}
|
||||
transition={{
|
||||
duration: orb.duration,
|
||||
repeat: Infinity,
|
||||
ease: 'easeInOut',
|
||||
delay: orb.delay,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-transparent to-white/20 pointer-events-none" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default GradientOrbs;
|
||||
Reference in New Issue
Block a user