chore: 更新构建ID和相关文件引用

This commit is contained in:
张翔
2026-02-23 21:19:44 +08:00
parent 25586a5a6c
commit e862a68ef0
145 changed files with 773 additions and 295 deletions
+3 -78
View File
@@ -4,6 +4,7 @@ import { useEffect, useRef, useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { RippleButton, SealButton } from '@/components/ui/ripple-button';
import { FadeUp, StaggerContainer, StaggerItem, CountUp, FloatingElement, SplitText, GradientText, MagneticButton, BlurReveal, CounterWithEffect } from '@/lib/animations';
import { InkDecoration, InkBackground } from '@/components/ui/ink-decoration';
import { COMPANY_INFO, STATS } from '@/lib/constants';
import { ArrowRight, Shield, Zap, Award } from 'lucide-react';
@@ -65,84 +66,8 @@ export function HeroSection() {
ref={sectionRef}
className="relative min-h-screen flex items-center pt-16 overflow-hidden bg-gradient-to-b from-[#FAFAFA] to-white"
>
<div className="absolute inset-0 pointer-events-none overflow-hidden">
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 1.2, ease: [0.16, 1, 0.3, 1] }}
className="absolute top-0 left-1/2 -translate-x-1/2 w-[800px] h-[600px] bg-[radial-gradient(ellipse_at_center,rgba(28,28,28,0.03)_0%,transparent_60%)]"
/>
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 1.2, delay: 0.2, ease: [0.16, 1, 0.3, 1] }}
className="absolute bottom-0 left-1/2 -translate-x-1/2 w-[600px] h-[400px] bg-[radial-gradient(ellipse_at_center,rgba(196,30,58,0.04)_0%,transparent_50%)]"
/>
<FloatingElement amplitude={20} duration={6} className="absolute top-[15%] left-[5%]">
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.5, duration: 0.8 }}
className="w-4 h-4 bg-[#C41E3A]/30 rounded-full blur-[1px]"
/>
</FloatingElement>
<FloatingElement amplitude={25} duration={7} delay={0.3} className="absolute top-[25%] right-[8%]">
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.7, duration: 0.8 }}
className="w-6 h-6 bg-[#1C1C1C]/20 rounded-full blur-[1px]"
/>
</FloatingElement>
<FloatingElement amplitude={18} duration={5} delay={0.6} className="absolute bottom-[30%] left-[10%]">
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.9, duration: 0.8 }}
className="w-3 h-3 bg-[#C41E3A]/25 rounded-full"
/>
</FloatingElement>
<FloatingElement amplitude={22} duration={6.5} delay={0.2} className="absolute bottom-[20%] right-[12%]">
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 1.1, duration: 0.8 }}
className="w-5 h-5 bg-[#1C1C1C]/15 rounded-full blur-[1px]"
/>
</FloatingElement>
<FloatingElement amplitude={15} duration={5.5} delay={0.8} className="absolute top-[40%] left-[15%]">
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 1.3, duration: 0.8 }}
className="w-2 h-2 bg-[#C41E3A]/40 rounded-full"
/>
</FloatingElement>
<FloatingElement amplitude={30} duration={8} delay={0.4} className="absolute top-[60%] right-[5%]">
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 1.5, duration: 0.8 }}
className="w-8 h-8 border-2 border-[#C41E3A]/20 rounded-full"
/>
</FloatingElement>
<FloatingElement amplitude={12} duration={4.5} delay={1} className="absolute top-[35%] right-[20%]">
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 1.7, duration: 0.8 }}
className="w-2 h-2 bg-[#1C1C1C]/30 rounded-full"
/>
</FloatingElement>
</div>
<InkBackground />
<InkDecoration variant="balanced" />
<div className="container-wide py-24 md:py-32 lg:py-40 relative z-10">
<div className="max-w-4xl mx-auto text-center">
+553
View File
@@ -0,0 +1,553 @@
'use client';
import { motion } from 'framer-motion';
import { useMemo, useState, useEffect } from 'react';
interface InkDropProps {
size?: number;
opacity?: number;
color?: string;
blur?: number;
delay?: number;
duration?: number;
className?: string;
}
export function InkDrop({
size = 20,
opacity = 0.15,
color = '#1C1C1C',
blur = 0,
delay = 0,
duration = 8,
className = ''
}: InkDropProps) {
return (
<motion.div
className={`absolute rounded-full ${className}`}
style={{
width: size,
height: size,
backgroundColor: color,
opacity,
filter: blur > 0 ? `blur(${blur}px)` : 'none',
}}
initial={{ scale: 0, opacity: 0 }}
animate={{
scale: [0.8, 1.2, 1],
opacity: [0, opacity, opacity],
}}
transition={{
duration: 1.5,
delay,
ease: [0.16, 1, 0.3, 1],
}}
/>
);
}
interface InkSplashProps {
size?: number;
color?: string;
opacity?: number;
delay?: number;
className?: string;
}
export function InkSplash({
size = 60,
color = '#C41E3A',
opacity = 0.2,
delay = 0,
className = ''
}: InkSplashProps) {
return (
<motion.svg
viewBox="0 0 100 100"
width={size}
height={size}
className={`absolute ${className}`}
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity, scale: 1 }}
transition={{ duration: 1.2, delay, ease: [0.16, 1, 0.3, 1] }}
>
<motion.path
d="M50 10 Q30 25 35 50 Q30 75 50 90 Q70 75 65 50 Q70 25 50 10"
fill={color}
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 1 }}
transition={{ duration: 2, delay: delay + 0.3, ease: [0.16, 1, 0.3, 1] }}
/>
</motion.svg>
);
}
interface SealStampProps {
size?: number;
color?: string;
opacity?: number;
delay?: number;
className?: string;
}
export function SealStamp({
size = 40,
color = '#C41E3A',
opacity = 0.15,
delay = 0,
className = ''
}: SealStampProps) {
return (
<motion.div
className={`absolute ${className}`}
style={{
width: size,
height: size,
border: `2px solid ${color}`,
borderRadius: '4px',
opacity: 0,
transform: 'rotate(-8deg)',
}}
initial={{ opacity: 0, scale: 1.5, rotate: -20 }}
animate={{ opacity, scale: 1, rotate: -8 }}
transition={{
type: 'spring',
stiffness: 200,
damping: 15,
delay,
}}
>
<motion.div
className="absolute inset-1 border border-current"
style={{ borderColor: color, opacity: 0.5 }}
initial={{ scale: 0.8 }}
animate={{ scale: 1 }}
transition={{ duration: 0.5, delay: delay + 0.3 }}
/>
</motion.div>
);
}
interface InkStainProps {
size?: number;
color?: string;
opacity?: number;
blur?: number;
delay?: number;
className?: string;
}
export function InkStain({
size = 100,
color = '#1C1C1C',
opacity = 0.05,
blur = 20,
delay = 0,
className = ''
}: InkStainProps) {
return (
<motion.div
className={`absolute ${className}`}
style={{
width: size,
height: size * 0.8,
backgroundColor: color,
borderRadius: '50% 40% 60% 45%',
opacity: 0,
filter: `blur(${blur}px)`,
}}
initial={{ opacity: 0, scale: 0.5 }}
animate={{ opacity, scale: 1 }}
transition={{ duration: 2, delay, ease: [0.16, 1, 0.3, 1] }}
/>
);
}
interface InkLineProps {
width?: number;
height?: number;
color?: string;
opacity?: number;
delay?: number;
className?: string;
}
export function InkLine({
width = 200,
height = 2,
color = '#1C1C1C',
opacity = 0.1,
delay = 0,
className = ''
}: InkLineProps) {
return (
<motion.div
className={`absolute ${className}`}
style={{
width,
height,
backgroundColor: color,
opacity: 0,
borderRadius: height / 2,
}}
initial={{ opacity: 0, scaleX: 0 }}
animate={{ opacity, scaleX: 1 }}
transition={{ duration: 1.5, delay, ease: [0.16, 1, 0.3, 1] }}
/>
);
}
interface BrushStrokeProps {
width?: number;
height?: number;
color?: string;
opacity?: number;
delay?: number;
className?: string;
}
export function BrushStroke({
width = 150,
height = 30,
color = '#C41E3A',
opacity = 0.12,
delay = 0,
className = ''
}: BrushStrokeProps) {
return (
<motion.svg
viewBox="0 0 150 30"
width={width}
height={height}
className={`absolute ${className}`}
initial={{ opacity: 0 }}
animate={{ opacity }}
transition={{ duration: 1, delay }}
>
<motion.path
d="M0 15 Q20 5 40 15 Q60 25 80 15 Q100 5 120 15 Q135 20 150 15"
fill="none"
stroke={color}
strokeWidth="3"
strokeLinecap="round"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 2, delay: delay + 0.5, ease: [0.16, 1, 0.3, 1] }}
/>
</motion.svg>
);
}
interface FloatingInkProps {
count?: number;
className?: string;
}
export function FloatingInk({ count = 15, className = '' }: FloatingInkProps) {
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, []);
const elements = useMemo(() => {
if (!isMounted) return [];
const items = [];
for (let i = 0; i < count; i++) {
const type = i % 5;
const baseDelay = i * 0.15;
items.push({
id: i,
type,
delay: baseDelay,
props: {
left: `${10 + Math.random() * 80}%`,
top: `${10 + Math.random() * 80}%`,
},
animX: Math.random() * 10 - 5,
animDuration: 6 + Math.random() * 4,
size: type === 0 ? 8 + Math.random() * 16 :
type === 1 ? 4 + Math.random() * 8 :
type === 2 ? 20 + Math.random() * 30 :
type === 3 ? 60 + Math.random() * 80 : 80 + Math.random() * 100,
opacity: type === 0 ? 0.08 + Math.random() * 0.1 :
type === 1 ? 0.1 + Math.random() * 0.15 :
type === 2 ? 0.08 + Math.random() * 0.08 :
type === 3 ? 0.03 + Math.random() * 0.04 : 0.06 + Math.random() * 0.08,
blur: type === 0 ? Math.random() * 2 : 0,
height: type === 4 ? 15 + Math.random() * 20 : undefined,
});
}
return items;
}, [count, isMounted]);
return (
<div className={`absolute inset-0 pointer-events-none overflow-hidden ${className}`}>
{elements.map((el) => (
<motion.div
key={el.id}
className="absolute"
style={el.props}
animate={{
y: [0, -20, 0],
x: [0, el.animX, 0],
}}
transition={{
duration: el.animDuration,
delay: el.delay,
repeat: Infinity,
ease: 'easeInOut',
}}
>
{el.type === 0 && (
<InkDrop
size={el.size}
opacity={el.opacity}
blur={el.blur}
delay={el.delay}
/>
)}
{el.type === 1 && (
<InkDrop
size={el.size}
opacity={el.opacity}
color="#C41E3A"
delay={el.delay}
/>
)}
{el.type === 2 && (
<SealStamp
size={el.size}
opacity={el.opacity}
delay={el.delay}
/>
)}
{el.type === 3 && (
<InkStain
size={el.size}
opacity={el.opacity}
delay={el.delay}
/>
)}
{el.type === 4 && (
<BrushStroke
width={el.size}
height={el.height}
opacity={el.opacity}
delay={el.delay}
/>
)}
</motion.div>
))}
</div>
);
}
interface InkDecorationProps {
variant?: 'minimal' | 'balanced' | 'rich';
className?: string;
}
export function InkDecoration({ variant = 'balanced', className = '' }: InkDecorationProps) {
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, []);
const config = {
minimal: { drops: 3, splashes: 1, seals: 1, stains: 1, strokes: 1 },
balanced: { drops: 5, splashes: 2, seals: 2, stains: 2, strokes: 2 },
rich: { drops: 8, splashes: 3, seals: 3, stains: 3, strokes: 3 },
};
const { drops, splashes, seals, stains, strokes } = config[variant];
const dropPositions = useMemo(() => {
if (!isMounted) return [];
return Array.from({ length: drops }, (_, i) => ({
left: `${15 + (i * 70 / drops)}%`,
top: `${20 + Math.random() * 60}%`,
size: 6 + Math.random() * 14,
opacity: 0.06 + Math.random() * 0.1,
blur: Math.random() * 3,
isRed: i % 3 === 0,
}));
}, [drops, isMounted]);
const splashPositions = useMemo(() => {
if (!isMounted) return [];
return Array.from({ length: splashes }, (_, i) => ({
left: `${20 + (i * 60 / splashes)}%`,
top: `${15 + Math.random() * 70}%`,
size: 40 + Math.random() * 40,
}));
}, [splashes, isMounted]);
const sealPositions = useMemo(() => {
if (!isMounted) return [];
return Array.from({ length: seals }, (_, i) => ({
left: `${25 + (i * 50 / seals)}%`,
top: `${25 + Math.random() * 50}%`,
size: 25 + Math.random() * 25,
}));
}, [seals, isMounted]);
const stainPositions = useMemo(() => {
if (!isMounted) return [];
return Array.from({ length: stains }, (_, i) => ({
left: `${10 + (i * 80 / stains)}%`,
top: `${30 + Math.random() * 40}%`,
size: 80 + Math.random() * 60,
}));
}, [stains, isMounted]);
const strokePositions = useMemo(() => {
if (!isMounted) return [];
return Array.from({ length: strokes }, (_, i) => ({
left: `${15 + (i * 70 / strokes)}%`,
top: `${40 + Math.random() * 30}%`,
width: 100 + Math.random() * 100,
}));
}, [strokes, isMounted]);
return (
<div className={`absolute inset-0 pointer-events-none overflow-hidden ${className}`}>
{dropPositions.map((pos, i) => (
<motion.div
key={`drop-${i}`}
className="absolute"
style={{ left: pos.left, top: pos.top }}
animate={{
y: [0, -15, 0],
scale: [1, 1.1, 1],
}}
transition={{
duration: 5 + Math.random() * 3,
delay: i * 0.2,
repeat: Infinity,
ease: 'easeInOut',
}}
>
<InkDrop
size={pos.size}
opacity={pos.opacity}
blur={pos.blur}
color={pos.isRed ? '#C41E3A' : '#1C1C1C'}
delay={i * 0.1}
/>
</motion.div>
))}
{splashPositions.map((pos, i) => (
<motion.div
key={`splash-${i}`}
className="absolute"
style={{ left: pos.left, top: pos.top }}
animate={{
y: [0, -10, 0],
rotate: [0, 5, -5, 0],
}}
transition={{
duration: 7 + Math.random() * 3,
delay: i * 0.3,
repeat: Infinity,
ease: 'easeInOut',
}}
>
<InkSplash size={pos.size} opacity={0.12} delay={i * 0.15} />
</motion.div>
))}
{sealPositions.map((pos, i) => (
<motion.div
key={`seal-${i}`}
className="absolute"
style={{ left: pos.left, top: pos.top }}
animate={{
y: [0, -8, 0],
rotate: [-8, -5, -10, -8],
}}
transition={{
duration: 6 + Math.random() * 2,
delay: i * 0.25,
repeat: Infinity,
ease: 'easeInOut',
}}
>
<SealStamp size={pos.size} opacity={0.1} delay={i * 0.2} />
</motion.div>
))}
{stainPositions.map((pos, i) => (
<motion.div
key={`stain-${i}`}
className="absolute"
style={{ left: pos.left, top: pos.top }}
animate={{
scale: [1, 1.05, 1],
opacity: [0.04, 0.06, 0.04],
}}
transition={{
duration: 8 + Math.random() * 4,
delay: i * 0.35,
repeat: Infinity,
ease: 'easeInOut',
}}
>
<InkStain size={pos.size} opacity={0.05} delay={i * 0.1} />
</motion.div>
))}
{strokePositions.map((pos, i) => (
<motion.div
key={`stroke-${i}`}
className="absolute"
style={{ left: pos.left, top: pos.top }}
animate={{
x: [0, 10, 0],
opacity: [0.08, 0.12, 0.08],
}}
transition={{
duration: 6 + Math.random() * 3,
delay: i * 0.3,
repeat: Infinity,
ease: 'easeInOut',
}}
>
<BrushStroke width={pos.width} opacity={0.1} delay={i * 0.15} />
</motion.div>
))}
</div>
);
}
export function InkBackground() {
return (
<div className="absolute inset-0 pointer-events-none overflow-hidden">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 2 }}
className="absolute top-0 left-1/4 w-[500px] h-[500px] bg-[radial-gradient(ellipse_at_center,rgba(28,28,28,0.02)_0%,transparent_70%)]"
/>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 2, delay: 0.3 }}
className="absolute bottom-0 right-1/4 w-[400px] h-[400px] bg-[radial-gradient(ellipse_at_center,rgba(196,30,58,0.03)_0%,transparent_60%)]"
/>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 2, delay: 0.6 }}
className="absolute top-1/3 right-0 w-[300px] h-[300px] bg-[radial-gradient(ellipse_at_center,rgba(28,28,28,0.015)_0%,transparent_50%)]"
/>
</div>
);
}