fix: first commit

This commit is contained in:
Guwan 2025-08-05 00:18:38 +08:00
parent 27ede6c1db
commit 54217e7adf
1 changed files with 634 additions and 0 deletions

View File

@ -0,0 +1,634 @@
import React, { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import Confetti from 'react-confetti';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, BarChart, Bar, PieChart, Pie, Cell } from 'recharts';
// ========== 炫酷组件库演示 ==========
// 1. Framer Motion 动画演示
const FramerMotionDemo: React.FC = () => {
const [isVisible, setIsVisible] = useState(true);
const [selectedCard, setSelectedCard] = useState<number | null>(null);
const cards = [
{ id: 1, title: '卡片 1', color: '#FF6B6B', icon: '🚀' },
{ id: 2, title: '卡片 2', color: '#4ECDC4', icon: '🎨' },
{ id: 3, title: '卡片 3', color: '#45B7D1', icon: '⚡' },
{ id: 4, title: '卡片 4', color: '#96CEB4', icon: '🌟' }
];
return (
<div style={{
padding: '20px',
border: '2px solid #6c5ce7',
borderRadius: '12px',
margin: '15px',
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
color: 'white'
}}>
<h3>🎬 Framer Motion </h3>
<div style={{ marginBottom: '20px' }}>
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
onClick={() => setIsVisible(!isVisible)}
style={{
padding: '12px 24px',
backgroundColor: '#ff7675',
color: 'white',
border: 'none',
borderRadius: '25px',
cursor: 'pointer',
fontSize: '16px',
marginRight: '10px'
}}
>
{isVisible ? '隐藏动画元素' : '显示动画元素'}
</motion.button>
</div>
<AnimatePresence>
{isVisible && (
<motion.div
initial={{ opacity: 0, y: 50 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -50 }}
transition={{ duration: 0.5 }}
style={{
padding: '20px',
backgroundColor: 'rgba(255, 255, 255, 0.1)',
borderRadius: '10px',
marginBottom: '20px'
}}
>
<h4> /退</h4>
<p>退</p>
</motion.div>
)}
</AnimatePresence>
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))',
gap: '15px',
marginTop: '20px'
}}>
{cards.map((card) => (
<motion.div
key={card.id}
layoutId={`card-${card.id}`}
onClick={() => setSelectedCard(selectedCard === card.id ? null : card.id)}
whileHover={{
scale: 1.05,
rotate: selectedCard === card.id ? 0 : 5,
transition: { duration: 0.2 }
}}
whileTap={{ scale: 0.95 }}
animate={{
backgroundColor: selectedCard === card.id ? '#2d3436' : card.color,
scale: selectedCard === card.id ? 1.1 : 1
}}
style={{
padding: '20px',
borderRadius: '15px',
cursor: 'pointer',
textAlign: 'center',
backgroundColor: card.color
}}
>
<motion.div
animate={{
rotate: selectedCard === card.id ? 360 : 0,
scale: selectedCard === card.id ? 1.2 : 1
}}
transition={{ duration: 0.5 }}
style={{ fontSize: '32px', marginBottom: '10px' }}
>
{card.icon}
</motion.div>
<h4 style={{ margin: 0, color: 'white' }}>{card.title}</h4>
{selectedCard === card.id && (
<motion.p
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
style={{ marginTop: '10px', fontSize: '14px' }}
>
</motion.p>
)}
</motion.div>
))}
</div>
<motion.div
animate={{ rotate: 360 }}
transition={{ duration: 2, repeat: Infinity, ease: "linear" }}
style={{
width: '60px',
height: '60px',
backgroundColor: '#fdcb6e',
borderRadius: '50%',
margin: '20px auto',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '24px'
}}
>
🌀
</motion.div>
</div>
);
};
// 2. React Confetti 彩纸效果演示
const ConfettiDemo: React.FC = () => {
const [showConfetti, setShowConfetti] = useState(false);
const [confettiConfig, setConfettiConfig] = useState({
numberOfPieces: 200,
gravity: 0.1
});
useEffect(() => {
if (showConfetti) {
const timer = setTimeout(() => setShowConfetti(false), 5000);
return () => clearTimeout(timer);
}
}, [showConfetti]);
return (
<div style={{
padding: '20px',
border: '2px solid #00b894',
borderRadius: '12px',
margin: '15px',
background: 'linear-gradient(135deg, #00b894 0%, #00cec9 100%)',
color: 'white',
position: 'relative'
}}>
{showConfetti && (
<Confetti
width={window.innerWidth}
height={window.innerHeight}
numberOfPieces={confettiConfig.numberOfPieces}
gravity={confettiConfig.gravity}
style={{ position: 'fixed', top: 0, left: 0, zIndex: 1000 }}
/>
)}
<h3>🎉 React Confetti </h3>
<p></p>
<div style={{ marginBottom: '20px' }}>
<label style={{ display: 'block', marginBottom: '10px' }}>
: {confettiConfig.numberOfPieces}
<input
type="range"
min="50"
max="500"
value={confettiConfig.numberOfPieces}
onChange={(e) => setConfettiConfig(prev => ({
...prev,
numberOfPieces: Number(e.target.value)
}))}
style={{ marginLeft: '10px', width: '200px' }}
/>
</label>
<label style={{ display: 'block', marginBottom: '15px' }}>
: {confettiConfig.gravity}
<input
type="range"
min="0.05"
max="0.3"
step="0.01"
value={confettiConfig.gravity}
onChange={(e) => setConfettiConfig(prev => ({
...prev,
gravity: Number(e.target.value)
}))}
style={{ marginLeft: '10px', width: '200px' }}
/>
</label>
</div>
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
onClick={() => setShowConfetti(true)}
disabled={showConfetti}
style={{
padding: '15px 30px',
backgroundColor: showConfetti ? '#95a5a6' : '#e74c3c',
color: 'white',
border: 'none',
borderRadius: '25px',
cursor: showConfetti ? 'not-allowed' : 'pointer',
fontSize: '18px',
fontWeight: 'bold'
}}
>
{showConfetti ? '彩纸飞舞中...' : '🎊 释放彩纸!'}
</motion.button>
</div>
);
};
// 3. Recharts 图表演示
const ChartsDemo: React.FC = () => {
const [chartType, setChartType] = useState<'line' | 'bar' | 'pie'>('line');
const lineData = [
{ name: '1月', 用户: 400, 销售: 240, 访问: 300 },
{ name: '2月', 用户: 300, 销售: 139, 访问: 200 },
{ name: '3月', 用户: 200, 销售: 980, 访问: 400 },
{ name: '4月', 用户: 278, 销售: 390, 访问: 350 },
{ name: '5月', 用户: 189, 销售: 480, 访问: 200 },
{ name: '6月', 用户: 239, 销售: 380, 访问: 500 },
];
const pieData = [
{ name: 'React', value: 35, color: '#61dafb' },
{ name: 'Vue', value: 25, color: '#4fc08d' },
{ name: 'Angular', value: 20, color: '#dd1b16' },
{ name: 'Svelte', value: 10, color: '#ff3e00' },
{ name: '其他', value: 10, color: '#9ca3af' }
];
const renderChart = () => {
switch (chartType) {
case 'line':
return (
<ResponsiveContainer width="100%" height={300}>
<LineChart data={lineData}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Line type="monotone" dataKey="用户" stroke="#8884d8" strokeWidth={2} />
<Line type="monotone" dataKey="销售" stroke="#82ca9d" strokeWidth={2} />
<Line type="monotone" dataKey="访问" stroke="#ffc658" strokeWidth={2} />
</LineChart>
</ResponsiveContainer>
);
case 'bar':
return (
<ResponsiveContainer width="100%" height={300}>
<BarChart data={lineData}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Bar dataKey="用户" fill="#8884d8" />
<Bar dataKey="销售" fill="#82ca9d" />
<Bar dataKey="访问" fill="#ffc658" />
</BarChart>
</ResponsiveContainer>
);
case 'pie':
return (
<ResponsiveContainer width="100%" height={300}>
<PieChart>
<Pie
data={pieData}
cx="50%"
cy="50%"
labelLine={false}
label={({ name, percent }) => `${name} ${((percent || 0) * 100).toFixed(0)}%`}
outerRadius={80}
fill="#8884d8"
dataKey="value"
>
{pieData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.color} />
))}
</Pie>
<Tooltip />
</PieChart>
</ResponsiveContainer>
);
default:
return null;
}
};
return (
<div style={{
padding: '20px',
border: '2px solid #e17055',
borderRadius: '12px',
margin: '15px',
backgroundColor: '#f8f9fa'
}}>
<h3 style={{ color: '#2d3436' }}>📊 Recharts </h3>
<div style={{ marginBottom: '20px' }}>
{(['line', 'bar', 'pie'] as const).map((type) => (
<motion.button
key={type}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
onClick={() => setChartType(type)}
style={{
padding: '8px 16px',
marginRight: '10px',
backgroundColor: chartType === type ? '#e17055' : '#ddd',
color: chartType === type ? 'white' : '#333',
border: 'none',
borderRadius: '20px',
cursor: 'pointer'
}}
>
{type === 'line' ? '📈 折线图' : type === 'bar' ? '📊 柱状图' : '🥧 饼图'}
</motion.button>
))}
</div>
<motion.div
key={chartType}
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3 }}
>
{renderChart()}
</motion.div>
</div>
);
};
// 4. 炫酷加载动画演示
const LoadingAnimationsDemo: React.FC = () => {
const [isLoading, setIsLoading] = useState(false);
const startLoading = () => {
setIsLoading(true);
setTimeout(() => setIsLoading(false), 3000);
};
return (
<div style={{
padding: '20px',
border: '2px solid #a29bfe',
borderRadius: '12px',
margin: '15px',
background: 'linear-gradient(135deg, #a29bfe 0%, #6c5ce7 100%)',
color: 'white'
}}>
<h3> </h3>
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
onClick={startLoading}
disabled={isLoading}
style={{
padding: '12px 24px',
backgroundColor: isLoading ? '#95a5a6' : '#fd79a8',
color: 'white',
border: 'none',
borderRadius: '25px',
cursor: isLoading ? 'not-allowed' : 'pointer',
fontSize: '16px',
marginBottom: '20px'
}}
>
{isLoading ? '加载中...' : '开始加载'}
</motion.button>
<AnimatePresence>
{isLoading && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
style={{ textAlign: 'center' }}
>
{/* 旋转圆环 */}
<motion.div
animate={{ rotate: 360 }}
transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
style={{
width: '60px',
height: '60px',
border: '4px solid rgba(255,255,255,0.3)',
borderTop: '4px solid white',
borderRadius: '50%',
margin: '20px auto'
}}
/>
{/* 脉冲圆点 */}
<div style={{ display: 'flex', justifyContent: 'center', gap: '10px', marginBottom: '20px' }}>
{[0, 1, 2].map((i) => (
<motion.div
key={i}
animate={{
scale: [1, 1.5, 1],
opacity: [0.5, 1, 0.5]
}}
transition={{
duration: 1,
repeat: Infinity,
delay: i * 0.2
}}
style={{
width: '15px',
height: '15px',
backgroundColor: 'white',
borderRadius: '50%'
}}
/>
))}
</div>
{/* 波浪进度条 */}
<div style={{
width: '200px',
height: '6px',
backgroundColor: 'rgba(255,255,255,0.3)',
borderRadius: '3px',
margin: '0 auto',
overflow: 'hidden'
}}>
<motion.div
animate={{ x: [-200, 200] }}
transition={{ duration: 1.5, repeat: Infinity, ease: "easeInOut" }}
style={{
width: '100px',
height: '100%',
background: 'linear-gradient(90deg, transparent, white, transparent)',
borderRadius: '3px'
}}
/>
</div>
</motion.div>
)}
</AnimatePresence>
</div>
);
};
// 5. 交互式卡片网格
const InteractiveCardsDemo: React.FC = () => {
const [hoveredCard, setHoveredCard] = useState<number | null>(null);
const features = [
{ id: 1, title: '高性能', icon: '⚡', description: '极致的性能优化' },
{ id: 2, title: '易使用', icon: '🎯', description: '简单直观的API' },
{ id: 3, title: '可定制', icon: '🎨', description: '灵活的主题配置' },
{ id: 4, title: '响应式', icon: '📱', description: '完美适配各种设备' },
{ id: 5, title: '现代化', icon: '🚀', description: '最新技术栈支持' },
{ id: 6, title: '文档完善', icon: '📚', description: '详细的使用指南' }
];
return (
<div style={{
padding: '20px',
border: '2px solid #00cec9',
borderRadius: '12px',
margin: '15px',
backgroundColor: '#f8f9fa'
}}>
<h3 style={{ color: '#2d3436', textAlign: 'center' }}>🎴 </h3>
<motion.div
layout
style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
gap: '20px',
marginTop: '20px'
}}
>
{features.map((feature) => (
<motion.div
key={feature.id}
layout
onHoverStart={() => setHoveredCard(feature.id)}
onHoverEnd={() => setHoveredCard(null)}
whileHover={{
scale: 1.05,
rotateY: 5,
z: 50
}}
whileTap={{ scale: 0.95 }}
style={{
padding: '20px',
backgroundColor: hoveredCard === feature.id ? '#00cec9' : 'white',
color: hoveredCard === feature.id ? 'white' : '#2d3436',
borderRadius: '15px',
boxShadow: hoveredCard === feature.id
? '0 10px 30px rgba(0, 206, 201, 0.3)'
: '0 5px 15px rgba(0,0,0,0.1)',
cursor: 'pointer',
textAlign: 'center',
transition: 'all 0.3s ease'
}}
>
<motion.div
animate={{
scale: hoveredCard === feature.id ? 1.2 : 1,
rotate: hoveredCard === feature.id ? 360 : 0
}}
transition={{ duration: 0.3 }}
style={{ fontSize: '32px', marginBottom: '10px' }}
>
{feature.icon}
</motion.div>
<h4 style={{ margin: '10px 0' }}>{feature.title}</h4>
<AnimatePresence>
{hoveredCard === feature.id && (
<motion.p
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
exit={{ opacity: 0, height: 0 }}
style={{ margin: 0, fontSize: '14px' }}
>
{feature.description}
</motion.p>
)}
</AnimatePresence>
</motion.div>
))}
</motion.div>
</div>
);
};
// 主组件
const CoolLibrariesDemo: React.FC = () => {
return (
<div style={{ padding: '20px' }}>
<motion.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<h2 style={{ textAlign: 'center', color: '#2d3436', marginBottom: '10px' }}>
React组件库演示
</h2>
<p style={{ textAlign: 'center', color: '#636e72', marginBottom: '30px' }}>
React UI库和动画库
</p>
</motion.div>
<FramerMotionDemo />
<ConfettiDemo />
<ChartsDemo />
<LoadingAnimationsDemo />
<InteractiveCardsDemo />
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.5 }}
style={{
marginTop: '30px',
padding: '25px',
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
borderRadius: '15px',
color: 'white',
textAlign: 'center'
}}
>
<h3>🎯 </h3>
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))',
gap: '20px',
marginTop: '20px'
}}>
<div>
<h4>🎬 </h4>
<ul style={{ textAlign: 'left', lineHeight: '1.8' }}>
<li><strong>Framer Motion</strong>: React动画库</li>
<li><strong>React Spring</strong>: </li>
<li><strong>React Transition Group</strong>: </li>
</ul>
</div>
<div>
<h4>🎨 UI组件库</h4>
<ul style={{ textAlign: 'left', lineHeight: '1.8' }}>
<li><strong>Ant Design</strong>: UI设计语言</li>
<li><strong>Material-UI</strong>: Google Material Design</li>
<li><strong>Chakra UI</strong>: </li>
</ul>
</div>
<div>
<h4>📊 </h4>
<ul style={{ textAlign: 'left', lineHeight: '1.8' }}>
<li><strong>Recharts</strong>: D3的图表库</li>
<li><strong>Victory</strong>: </li>
<li><strong>React-vis</strong>: Uber开源图表库</li>
</ul>
</div>
</div>
</motion.div>
</div>
);
};
export default CoolLibrariesDemo;