fix: first commit
This commit is contained in:
parent
27ede6c1db
commit
54217e7adf
|
@ -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;
|
Loading…
Reference in New Issue