first commit

This commit is contained in:
jeremygan2021
2025-09-14 17:20:28 +08:00
commit a9ee899cc5
13 changed files with 19904 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
node_modules

17402
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

35
package.json Normal file
View File

@@ -0,0 +1,35 @@
{
"name": "ai-company-website",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"framer-motion": "^10.16.4",
"react-scripts": "5.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

35
public/index.html Normal file
View File

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="AI公司官网 - 创新科技,引领未来" />
<title>Radiant AI - 创新科技,引领未来</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
overflow-x: hidden;
scroll-behavior: smooth;
}
#root {
width: 100vw;
min-height: 100vh;
}
</style>
</head>
<body>
<noscript>您需要启用JavaScript来运行此应用程序。</noscript>
<div id="root"></div>
</body>
</html>

1468
src/App.css Normal file

File diff suppressed because it is too large Load Diff

171
src/App.js Normal file
View File

@@ -0,0 +1,171 @@
import React, { useEffect, useRef, useState } from 'react';
import { motion, useScroll, useTransform, AnimatePresence } from 'framer-motion';
import Navigation from './components/Navigation';
import HeroSection from './components/HeroSection';
import ProductSection from './components/ProductSection';
import TeamSection from './components/TeamSection';
import CaseSection from './components/CaseSection';
import ContactSection from './components/ContactSection';
import './App.css';
const App = () => {
const containerRef = useRef(null);
const [currentSection, setCurrentSection] = useState(0);
const [isScrolling, setIsScrolling] = useState(false);
const isScrollingRef = useRef(false);
const currentSectionRef = useRef(0);
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ["start start", "end start"]
});
const sections = [
{ id: 'hero', component: HeroSection, title: '发现新视界', subtitle: 'Discover New Horizons' },
{ id: 'product', component: ProductSection, title: 'AI产品', subtitle: 'Innovative Solutions' },
{ id: 'team', component: TeamSection, title: '专业团队', subtitle: 'Expert Team' },
{ id: 'cases', component: CaseSection, title: '成功案例', subtitle: 'Success Stories' },
{ id: 'contact', component: ContactSection, title: '联系我们', subtitle: 'Get In Touch' }
];
// 同步 ref 值
useEffect(() => {
isScrollingRef.current = isScrolling;
currentSectionRef.current = currentSection;
}, [isScrolling, currentSection]);
useEffect(() => {
let timeout;
const handleWheel = (e) => {
e.preventDefault();
// 如果正在滚动中,忽略新的滚动事件
if (isScrollingRef.current) {
return;
}
// 设置滚动状态
isScrollingRef.current = true;
setIsScrolling(true);
// 计算新的section索引
let newSection = currentSectionRef.current;
if (e.deltaY > 0 && currentSectionRef.current < sections.length - 1) {
newSection = currentSectionRef.current + 1;
} else if (e.deltaY < 0 && currentSectionRef.current > 0) {
newSection = currentSectionRef.current - 1;
}
// 如果section有变化更新状态
if (newSection !== currentSectionRef.current) {
setCurrentSection(newSection);
}
// 清除之前的超时
if (timeout) {
clearTimeout(timeout);
}
// 设置超时来重置滚动状态
timeout = setTimeout(() => {
isScrollingRef.current = false;
setIsScrolling(false);
}, 1200); // 增加到1.2秒,与动画时间匹配
};
const container = containerRef.current;
if (container) {
container.addEventListener('wheel', handleWheel, { passive: false });
}
return () => {
if (container) {
container.removeEventListener('wheel', handleWheel);
}
if (timeout) {
clearTimeout(timeout);
}
};
}, [sections.length]);
const backgroundOpacity = useTransform(scrollYProgress, [0, 1], [1, 0.3]);
const scale = useTransform(scrollYProgress, [0, 1], [1, 1.2]);
return (
<div className="app" ref={containerRef}>
<Navigation
currentSection={currentSection}
sections={sections}
onSectionChange={setCurrentSection}
/>
<motion.div
className="background-gradient"
style={{ opacity: backgroundOpacity, scale }}
/>
<div className="sections-container">
<AnimatePresence mode="wait">
{sections.map((section, index) => {
const Component = section.component;
const isActive = index === currentSection;
return isActive ? (
<motion.div
key={section.id}
className="section"
initial={{ opacity: 0, scale: 0.8, rotateX: 15 }}
animate={{
opacity: 1,
scale: 1,
rotateX: 0,
transition: {
duration: 1.2,
ease: [0.25, 0.1, 0.25, 1],
staggerChildren: 0.1
}
}}
exit={{
opacity: 0,
scale: 1.1,
rotateX: -15,
transition: { duration: 0.8 }
}}
>
<motion.div
className="section-title"
initial={{ y: 100, opacity: 0 }}
animate={{
y: 0,
opacity: 1,
transition: { delay: 0.3, duration: 0.8 }
}}
>
<h1>{section.title}</h1>
<span className="subtitle">{section.subtitle}</span>
</motion.div>
<Component sectionIndex={index} isActive={isActive} />
</motion.div>
) : null;
})}
</AnimatePresence>
</div>
<div className="section-indicators">
{sections.map((_, index) => (
<motion.div
key={index}
className={`indicator ${index === currentSection ? 'active' : ''}`}
onClick={() => setCurrentSection(index)}
whileHover={{ scale: 1.2 }}
whileTap={{ scale: 0.9 }}
/>
))}
</div>
</div>
);
};
export default App;

View File

@@ -0,0 +1,140 @@
import React, { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
const CaseSection = ({ isActive }) => {
const [selectedCase, setSelectedCase] = useState(0);
const cases = [
{
id: 1,
title: '智能金融风控系统',
client: '某大型银行',
category: '金融科技',
description: '基于机器学习的实时风险评估系统将欺诈检测准确率提升至99.8%',
results: ['风险识别提升85%', '处理速度提高300%', '年节省成本2000万'],
image: '🏦',
technologies: ['深度学习', '实时计算', '大数据分析']
},
{
id: 2,
title: '智能医疗诊断助手',
client: '顶级三甲医院',
category: '医疗健康',
description: 'AI辅助医生进行疾病诊断显著提高诊断效率和准确性',
results: ['诊断准确率提升20%', '诊疗时间缩短40%', '患者满意度95%'],
image: '🏥',
technologies: ['计算机视觉', '自然语言处理', '知识图谱']
},
{
id: 3,
title: '智能制造优化平台',
client: '制造业龙头企业',
category: '工业4.0',
description: '通过AI优化生产流程实现智能化生产管理和质量控制',
results: ['生产效率提升45%', '次品率降低90%', 'ROI达到280%'],
image: '🏭',
technologies: ['预测性维护', 'IoT集成', '优化算法']
}
];
return (
<div className="case-section">
<motion.div
className="case-header"
initial={{ opacity: 0, y: 50 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 0.2 }}
>
<h2>成功案例</h2>
<p>见证AI技术如何转化为实际商业价值</p>
</motion.div>
<div className="case-container">
<motion.div
className="case-navigation"
initial={{ opacity: 0, x: -50 }}
animate={isActive ? { opacity: 1, x: 0 } : {}}
transition={{ duration: 0.8, delay: 0.4 }}
>
{cases.map((caseItem, index) => (
<motion.div
key={caseItem.id}
className={`case-nav-item ${index === selectedCase ? 'active' : ''}`}
onClick={() => setSelectedCase(index)}
whileHover={{ scale: 1.02, x: 10 }}
whileTap={{ scale: 0.98 }}
>
<div className="nav-icon">{caseItem.image}</div>
<div className="nav-content">
<h4>{caseItem.title}</h4>
<span className="nav-category">{caseItem.category}</span>
</div>
</motion.div>
))}
</motion.div>
<motion.div
className="case-details"
initial={{ opacity: 0, x: 50 }}
animate={isActive ? { opacity: 1, x: 0 } : {}}
transition={{ duration: 0.8, delay: 0.6 }}
>
<AnimatePresence mode="wait">
<motion.div
key={selectedCase}
className="case-content"
initial={{ opacity: 0, y: 30, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, y: -30, scale: 1.05 }}
transition={{ duration: 0.5 }}
>
<div className="case-meta">
<span className="case-category">{cases[selectedCase].category}</span>
<span className="case-client">{cases[selectedCase].client}</span>
</div>
<h3 className="case-title">{cases[selectedCase].title}</h3>
<p className="case-description">{cases[selectedCase].description}</p>
<div className="case-technologies">
<h4>核心技术</h4>
<div className="tech-tags">
{cases[selectedCase].technologies.map((tech, idx) => (
<span key={idx} className="tech-tag">{tech}</span>
))}
</div>
</div>
<div className="case-results">
<h4>项目成果</h4>
<div className="results-grid">
{cases[selectedCase].results.map((result, idx) => (
<motion.div
key={idx}
className="result-item"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: idx * 0.1 }}
>
{result}
</motion.div>
))}
</div>
</div>
<motion.button
className="case-cta"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
查看详细案例
</motion.button>
</motion.div>
</AnimatePresence>
</motion.div>
</div>
</div>
);
};
export default CaseSection;

View File

@@ -0,0 +1,168 @@
import React from 'react';
import { motion } from 'framer-motion';
const ContactSection = ({ isActive }) => {
const contactMethods = [
{
icon: '📧',
title: '邮件联系',
content: 'contact@radiant-ai.com',
description: '7x24小时响应您的咨询'
},
{
icon: '📞',
title: '电话咨询',
content: '+86 400-888-9999',
description: '专业顾问为您答疑解惑'
},
{
icon: '📍',
title: '公司地址',
content: '北京市朝阳区',
description: '欢迎莅临参观交流'
}
];
const formVariants = {
hidden: { opacity: 0, x: 50 },
visible: {
opacity: 1,
x: 0,
transition: {
duration: 0.8,
staggerChildren: 0.1
}
}
};
const fieldVariants = {
hidden: { opacity: 0, y: 30 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.6 }
}
};
return (
<div className="contact-section">
<motion.div
className="contact-header"
initial={{ opacity: 0, y: 50 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 0.2 }}
>
<h2>联系我们</h2>
<p>让我们一起探索AI的无限可能</p>
</motion.div>
<div className="contact-container">
<motion.div
className="contact-info"
initial={{ opacity: 0, x: -50 }}
animate={isActive ? { opacity: 1, x: 0 } : {}}
transition={{ duration: 0.8, delay: 0.4 }}
>
<div className="contact-methods">
{contactMethods.map((method, index) => (
<motion.div
key={index}
className="contact-method"
whileHover={{ scale: 1.05, y: -5 }}
transition={{ duration: 0.3 }}
>
<div className="method-icon">{method.icon}</div>
<div className="method-content">
<h4>{method.title}</h4>
<div className="method-value">{method.content}</div>
<p className="method-description">{method.description}</p>
</div>
</motion.div>
))}
</div>
<motion.div
className="contact-social"
initial={{ opacity: 0, y: 30 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 0.8 }}
>
<h4>关注我们</h4>
<div className="social-links">
{['微信', '微博', 'LinkedIn', 'GitHub'].map((platform, idx) => (
<motion.div
key={idx}
className="social-link"
whileHover={{ scale: 1.2, rotate: 5 }}
whileTap={{ scale: 0.9 }}
>
{platform}
</motion.div>
))}
</div>
</motion.div>
</motion.div>
<motion.div
className="contact-form"
variants={formVariants}
initial="hidden"
animate={isActive ? "visible" : "hidden"}
>
<motion.form variants={formVariants}>
<motion.div className="form-group" variants={fieldVariants}>
<label>姓名</label>
<input type="text" placeholder="请输入您的姓名" />
</motion.div>
<motion.div className="form-group" variants={fieldVariants}>
<label>公司</label>
<input type="text" placeholder="请输入公司名称" />
</motion.div>
<motion.div className="form-group" variants={fieldVariants}>
<label>邮箱</label>
<input type="email" placeholder="请输入邮箱地址" />
</motion.div>
<motion.div className="form-group" variants={fieldVariants}>
<label>需求类型</label>
<select>
<option>产品咨询</option>
<option>技术合作</option>
<option>商务合作</option>
<option>其他</option>
</select>
</motion.div>
<motion.div className="form-group" variants={fieldVariants}>
<label>详细需求</label>
<textarea placeholder="请详细描述您的需求和期望..."></textarea>
</motion.div>
<motion.button
type="submit"
className="form-submit"
variants={fieldVariants}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
提交咨询
</motion.button>
</motion.form>
</motion.div>
</div>
<motion.div
className="contact-footer"
initial={{ opacity: 0 }}
animate={isActive ? { opacity: 1 } : {}}
transition={{ duration: 1, delay: 1.2 }}
>
<p>© 2024 Radiant AI. 创新科技引领未来</p>
</motion.div>
</div>
);
};
export default ContactSection;

View File

@@ -0,0 +1,124 @@
import React from 'react';
import { motion } from 'framer-motion';
const HeroSection = ({ isActive }) => {
return (
<div className="hero-section-minimal">
{/* 左侧主要内容 */}
<motion.div
className="hero-left"
initial={{ opacity: 0, x: -60 }}
animate={isActive ? { opacity: 1, x: 0 } : {}}
transition={{ duration: 1.2, delay: 0.3 }}
>
<motion.h1
className="hero-main-title"
initial={{ opacity: 0, y: 40 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 0.6 }}
>
推动变革
</motion.h1>
<motion.h2
className="hero-subtitle"
initial={{ opacity: 0, y: 40 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 0.8 }}
>
<span className="highlight-text">通过</span>
<br />
人工智能技术
</motion.h2>
<motion.div
className="hero-quote"
initial={{ opacity: 0, x: -20 }}
animate={isActive ? { opacity: 1, x: 0 } : {}}
transition={{ duration: 0.8, delay: 1.2 }}
>
<div className="quote-line"></div>
<p>
通过利用战略洞察和行业网络
<br />
Radiant 作为增长催化剂为我们的
<br />
投资组合公司和投资者创造卓越价值
</p>
</motion.div>
</motion.div>
{/* 右侧几何形状 */}
<motion.div
className="hero-right"
initial={{ opacity: 0, scale: 0.8 }}
animate={isActive ? { opacity: 1, scale: 1 } : {}}
transition={{ duration: 1.5, delay: 0.5 }}
>
<div className="geometric-container">
<motion.div
className="cube-main"
initial={{ rotateY: 0, rotateX: 0 }}
animate={isActive ? {
rotateY: [0, 15, 0],
rotateX: [0, -10, 0]
} : {}}
transition={{
duration: 8,
repeat: Infinity,
ease: "easeInOut"
}}
>
<div className="cube-face front"></div>
<div className="cube-face back"></div>
<div className="cube-face right"></div>
<div className="cube-face left"></div>
<div className="cube-face top"></div>
<div className="cube-face bottom"></div>
</motion.div>
<motion.div
className="cube-small"
initial={{ rotateY: 0 }}
animate={isActive ? { rotateY: 360 } : {}}
transition={{
duration: 12,
repeat: Infinity,
ease: "linear"
}}
>
<div className="cube-face front"></div>
<div className="cube-face back"></div>
<div className="cube-face right"></div>
<div className="cube-face left"></div>
<div className="cube-face top"></div>
<div className="cube-face bottom"></div>
</motion.div>
</div>
</motion.div>
{/* 底部进度指示器 */}
<motion.div
className="hero-progress"
initial={{ opacity: 0, y: 20 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 1.5 }}
>
<div className="progress-bar">
<motion.div
className="progress-fill"
initial={{ width: "0%" }}
animate={isActive ? { width: "23%" } : {}}
transition={{ duration: 2, delay: 2 }}
></motion.div>
</div>
<div className="progress-info">
<span className="progress-time">00:04</span>
<span className="progress-total">00:18</span>
</div>
</motion.div>
</div>
);
};
export default HeroSection;

View File

@@ -0,0 +1,148 @@
import React, { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
const Navigation = ({ currentSection, sections, onSectionChange }) => {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const menuItems = [
{ name: '发现', engName: 'Discover', sectionIndex: 0 },
{ name: '产品', engName: 'Products', sectionIndex: 1 },
{ name: '团队', engName: 'Team', sectionIndex: 2 },
{ name: '案例', engName: 'Cases', sectionIndex: 3 },
{ name: '联系', engName: 'Contact', sectionIndex: 4 }
];
const handleItemClick = (sectionIndex) => {
onSectionChange(sectionIndex);
setIsMobileMenuOpen(false);
};
const toggleMobileMenu = () => {
setIsMobileMenuOpen(!isMobileMenuOpen);
};
return (
<>
<motion.nav
className="navigation-glass"
initial={{ y: -50, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.2 }}
>
{/* Logo */}
<motion.div
className="logo-glass"
whileHover={{
scale: 1.02,
y: -1
}}
whileTap={{ scale: 0.98 }}
onClick={() => handleItemClick(0)}
>
<motion.div
className="logo-icon-glass"
whileHover={{
rotate: [0, -5, 5, 0],
scale: 1.1
}}
transition={{ duration: 0.5 }}
>
Q
</motion.div>
<motion.span
className="logo-text"
>
Quant Speed
</motion.span>
</motion.div>
{/* 桌面端菜单 */}
<div className="nav-menu-glass">
{menuItems.map((item, index) => (
<motion.div
key={index}
className={`nav-item-glass ${currentSection === item.sectionIndex ? 'active' : ''}`}
whileHover={{
scale: 1.05,
y: -2
}}
whileTap={{ scale: 0.95 }}
transition={{ duration: 0.2 }}
onClick={() => handleItemClick(item.sectionIndex)}
>
<span className="nav-item-main">{item.name}</span>
<span className="nav-item-sub">{item.engName}</span>
{currentSection === item.sectionIndex && (
<motion.div
className="nav-item-indicator"
layoutId="activeIndicator"
initial={false}
transition={{ type: "spring", stiffness: 300, damping: 30 }}
/>
)}
</motion.div>
))}
</div>
{/* 移动端汉堡菜单按钮 */}
<motion.div
className={`hamburger-glass ${isMobileMenuOpen ? 'active' : ''}`}
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
onClick={toggleMobileMenu}
>
<motion.div
className="hamburger-line"
animate={isMobileMenuOpen ? { rotate: 45, y: 6 } : { rotate: 0, y: 0 }}
/>
<motion.div
className="hamburger-line"
animate={isMobileMenuOpen ? { opacity: 0 } : { opacity: 1 }}
/>
<motion.div
className="hamburger-line"
animate={isMobileMenuOpen ? { rotate: -45, y: -6 } : { rotate: 0, y: 0 }}
/>
</motion.div>
</motion.nav>
{/* 移动端菜单 */}
<AnimatePresence>
{isMobileMenuOpen && (
<motion.div
className="mobile-menu-glass"
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.3 }}
>
<motion.div
className="mobile-menu-content"
initial={{ scale: 0.95 }}
animate={{ scale: 1 }}
exit={{ scale: 0.95 }}
>
{menuItems.map((item, index) => (
<motion.div
key={index}
className={`mobile-nav-item ${currentSection === item.sectionIndex ? 'active' : ''}`}
whileHover={{ x: 10 }}
whileTap={{ scale: 0.95 }}
onClick={() => handleItemClick(item.sectionIndex)}
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: index * 0.1 }}
>
<span className="mobile-nav-main">{item.name}</span>
<span className="mobile-nav-sub">{item.engName}</span>
</motion.div>
))}
</motion.div>
</motion.div>
)}
</AnimatePresence>
</>
);
};
export default Navigation;

View File

@@ -0,0 +1,101 @@
import React from 'react';
import { motion } from 'framer-motion';
const ProductSection = ({ isActive }) => {
return (
<div className="product-section-minimal">
<motion.div
className="product-content"
initial={{ opacity: 0, y: 60 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 1.2, delay: 0.3 }}
>
<motion.h1
className="product-main-title"
initial={{ opacity: 0, y: 40 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 0.6 }}
>
我们的战略
<br />
<span className="highlight-text">针对</span>
<br />
远见项目
</motion.h1>
<motion.div
className="product-quote"
initial={{ opacity: 0, x: -20 }}
animate={isActive ? { opacity: 1, x: 0 } : {}}
transition={{ duration: 0.8, delay: 1 }}
>
<div className="quote-line"></div>
<p>
Radiant的战略投资框架旨在
<br />
赋能创业者我们专注于与创始人
<br />
建立持久关系推动有意义的变革
</p>
</motion.div>
</motion.div>
<motion.div
className="product-visual"
initial={{ opacity: 0, scale: 0.9 }}
animate={isActive ? { opacity: 1, scale: 1 } : {}}
transition={{ duration: 1.5, delay: 0.5 }}
>
<div className="visual-container">
<motion.div
className="visual-element-1"
animate={isActive ? {
rotateY: [0, 360],
scale: [1, 1.1, 1]
} : {}}
transition={{
duration: 20,
repeat: Infinity,
ease: "linear"
}}
/>
<motion.div
className="visual-element-2"
animate={isActive ? {
rotateX: [0, 360],
y: [0, -20, 0]
} : {}}
transition={{
duration: 15,
repeat: Infinity,
ease: "easeInOut"
}}
/>
</div>
</motion.div>
{/* 进度指示器 */}
<motion.div
className="product-progress"
initial={{ opacity: 0, y: 20 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 1.5 }}
>
<div className="progress-bar">
<motion.div
className="progress-fill"
initial={{ width: "0%" }}
animate={isActive ? { width: "44%" } : {}}
transition={{ duration: 2, delay: 2 }}
></motion.div>
</div>
<div className="progress-info">
<span className="progress-time">00:08</span>
<span className="progress-total">00:18</span>
</div>
</motion.div>
</div>
);
};
export default ProductSection;

View File

@@ -0,0 +1,101 @@
import React from 'react';
import { motion } from 'framer-motion';
const TeamSection = ({ isActive }) => {
return (
<div className="team-section-minimal">
<motion.div
className="team-content"
initial={{ opacity: 0, y: 60 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 1.2, delay: 0.3 }}
>
<motion.h1
className="team-main-title"
initial={{ opacity: 0, y: 40 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 0.6 }}
>
团队专业
<br />
<span className="highlight-text">知识</span>
<br />
与经验
</motion.h1>
<motion.div
className="team-quote"
initial={{ opacity: 0, x: -20 }}
animate={isActive ? { opacity: 1, x: 0 } : {}}
transition={{ duration: 0.8, delay: 1 }}
>
<div className="quote-line"></div>
<p>
我们的团队汇聚了行业顶尖人才
<br />
拥有深厚的技术背景和丰富的
<br />
创新经验致力于推动AI技术发展
</p>
</motion.div>
</motion.div>
<motion.div
className="team-visual"
initial={{ opacity: 0, scale: 0.9 }}
animate={isActive ? { opacity: 1, scale: 1 } : {}}
transition={{ duration: 1.5, delay: 0.5 }}
>
<div className="team-visual-container">
<motion.div
className="team-visual-element-1"
animate={isActive ? {
rotateZ: [0, 180, 360],
scale: [1, 1.2, 1]
} : {}}
transition={{
duration: 18,
repeat: Infinity,
ease: "easeInOut"
}}
/>
<motion.div
className="team-visual-element-2"
animate={isActive ? {
rotateY: [0, 180, 360],
x: [0, 20, 0]
} : {}}
transition={{
duration: 12,
repeat: Infinity,
ease: "linear"
}}
/>
</div>
</motion.div>
{/* 进度指示器 */}
<motion.div
className="team-progress"
initial={{ opacity: 0, y: 20 }}
animate={isActive ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, delay: 1.5 }}
>
<div className="progress-bar">
<motion.div
className="progress-fill"
initial={{ width: "0%" }}
animate={isActive ? { width: "67%" } : {}}
transition={{ duration: 2, delay: 2 }}
></motion.div>
</div>
<div className="progress-info">
<span className="progress-time">00:12</span>
<span className="progress-total">00:18</span>
</div>
</motion.div>
</div>
);
};
export default TeamSection;

10
src/index.js Normal file
View File

@@ -0,0 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);