Files
sfera/src/components/admin/ui-kit/animations-demo.tsx

555 lines
24 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { useState } from 'react'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Avatar, AvatarFallback } from '@/components/ui/avatar'
import { Progress } from '@/components/ui/progress'
import {
Play,
Pause,
RotateCcw,
Zap,
Sparkles,
Loader,
RefreshCw,
Heart,
Star,
ArrowRight,
ChevronDown,
Bell,
Settings,
CheckCircle,
AlertTriangle,
Package,
Truck,
ShoppingCart
} from 'lucide-react'
export function AnimationsDemo() {
const [isAnimating, setIsAnimating] = useState(false)
const [hoveredCard, setHoveredCard] = useState<number | null>(null)
const [progress, setProgress] = useState(0)
const [isLoading, setIsLoading] = useState(false)
const [showNotification, setShowNotification] = useState(false)
const startProgress = () => {
setProgress(0)
const interval = setInterval(() => {
setProgress((prev) => {
if (prev >= 100) {
clearInterval(interval)
return 100
}
return prev + 10
})
}, 200)
}
const showLoadingDemo = () => {
setIsLoading(true)
setTimeout(() => setIsLoading(false), 3000)
}
const triggerNotification = () => {
setShowNotification(true)
setTimeout(() => setShowNotification(false), 3000)
}
return (
<div className="space-y-6">
{/* CSS Анимации */}
<Card className="glass-card border-white/10">
<CardHeader>
<CardTitle className="text-white">CSS Анимации</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{/* Spin Animations */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Вращение и загрузка</h4>
<div className="grid grid-cols-4 gap-4">
<div className="glass-card p-4 rounded-lg border border-white/10 text-center">
<div className="w-8 h-8 border-2 border-white/20 border-t-white rounded-full animate-spin mx-auto mb-2"></div>
<p className="text-white/70 text-xs">animate-spin</p>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10 text-center">
<RefreshCw className="w-8 h-8 text-white/70 animate-spin mx-auto mb-2" />
<p className="text-white/70 text-xs">icon spin</p>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10 text-center">
<Loader className="w-8 h-8 text-blue-400 animate-spin mx-auto mb-2" />
<p className="text-white/70 text-xs">loader</p>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10 text-center">
<div className="flex space-x-1 mx-auto w-fit mb-2">
<div className="w-2 h-2 bg-white rounded-full animate-bounce"></div>
<div className="w-2 h-2 bg-white rounded-full animate-bounce" style={{ animationDelay: '0.1s' }}></div>
<div className="w-2 h-2 bg-white rounded-full animate-bounce" style={{ animationDelay: '0.2s' }}></div>
</div>
<p className="text-white/70 text-xs">dots bounce</p>
</div>
</div>
</div>
{/* Pulse Animations */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Пульсация</h4>
<div className="grid grid-cols-4 gap-4">
<div className="glass-card p-4 rounded-lg border border-white/10 text-center">
<div className="w-8 h-8 bg-green-400 rounded-full animate-pulse mx-auto mb-2"></div>
<p className="text-white/70 text-xs">pulse circle</p>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10 text-center">
<Bell className="w-8 h-8 text-yellow-400 animate-pulse mx-auto mb-2" />
<p className="text-white/70 text-xs">notification</p>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10 text-center">
<Heart className="w-8 h-8 text-red-400 animate-pulse mx-auto mb-2 fill-current" />
<p className="text-white/70 text-xs">heartbeat</p>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10 text-center">
<div className="relative mx-auto w-8 h-8 mb-2">
<div className="absolute inset-0 bg-blue-400 rounded-full animate-ping"></div>
<div className="relative w-8 h-8 bg-blue-400 rounded-full"></div>
</div>
<p className="text-white/70 text-xs">ping</p>
</div>
</div>
</div>
{/* Bounce Animations */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Подпрыгивание</h4>
<div className="grid grid-cols-3 gap-4">
<div className="glass-card p-4 rounded-lg border border-white/10 text-center">
<ArrowRight className="w-8 h-8 text-white/70 animate-bounce mx-auto mb-2" />
<p className="text-white/70 text-xs">bounce arrow</p>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10 text-center">
<ChevronDown className="w-8 h-8 text-white/70 animate-bounce mx-auto mb-2" />
<p className="text-white/70 text-xs">bounce down</p>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10 text-center">
<Button
variant="glass"
size="sm"
className="animate-bounce"
>
Кнопка
</Button>
<p className="text-white/70 text-xs mt-2">bounce button</p>
</div>
</div>
</div>
</CardContent>
</Card>
{/* Hover эффекты */}
<Card className="glass-card border-white/10">
<CardHeader>
<CardTitle className="text-white">Hover эффекты</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{/* Scale Hover */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Масштабирование при наведении</h4>
<div className="grid grid-cols-4 gap-4">
<div className="glass-card p-4 rounded-lg border border-white/10 text-center hover:scale-105 transition-transform cursor-pointer">
<Package className="w-8 h-8 text-blue-400 mx-auto mb-2" />
<p className="text-white/70 text-xs">scale-105</p>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10 text-center hover:scale-110 transition-transform cursor-pointer">
<Truck className="w-8 h-8 text-green-400 mx-auto mb-2" />
<p className="text-white/70 text-xs">scale-110</p>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10 text-center hover:scale-95 transition-transform cursor-pointer">
<ShoppingCart className="w-8 h-8 text-purple-400 mx-auto mb-2" />
<p className="text-white/70 text-xs">scale-95</p>
</div>
<div className="glass-card p-4 rounded-lg border border-white/10 text-center hover:-translate-y-1 transition-transform cursor-pointer">
<Star className="w-8 h-8 text-yellow-400 mx-auto mb-2" />
<p className="text-white/70 text-xs">translate-y</p>
</div>
</div>
</div>
{/* Color Hover */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Изменение цвета</h4>
<div className="grid grid-cols-3 gap-4">
<Button
variant="outline"
className="hover:bg-blue-500 hover:border-blue-500 transition-colors"
>
Hover Blue
</Button>
<Button
variant="outline"
className="hover:bg-green-500 hover:border-green-500 transition-colors"
>
Hover Green
</Button>
<Button
variant="outline"
className="hover:bg-purple-500 hover:border-purple-500 transition-colors"
>
Hover Purple
</Button>
</div>
</div>
{/* Shadow Hover */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Тени при наведении</h4>
<div className="grid grid-cols-3 gap-4">
{[1, 2, 3].map((card) => (
<div
key={card}
className="glass-card p-4 rounded-lg border border-white/10 cursor-pointer transition-all duration-300 hover:shadow-xl hover:shadow-purple-500/20"
onMouseEnter={() => setHoveredCard(card)}
onMouseLeave={() => setHoveredCard(null)}
>
<div className="text-center">
<div className={`w-12 h-12 rounded-full mx-auto mb-3 flex items-center justify-center transition-all ${
hoveredCard === card ? 'bg-purple-500/30 scale-110' : 'bg-white/10'
}`}>
<Sparkles className={`w-6 h-6 transition-colors ${
hoveredCard === card ? 'text-purple-300' : 'text-white/60'
}`} />
</div>
<p className="text-white font-medium">Карточка {card}</p>
<p className="text-white/60 text-xs">Наведите для эффекта</p>
</div>
</div>
))}
</div>
</div>
</CardContent>
</Card>
{/* Transition эффекты */}
<Card className="glass-card border-white/10">
<CardHeader>
<CardTitle className="text-white">Переходы (Transitions)</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{/* Duration Examples */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Продолжительность переходов</h4>
<div className="grid grid-cols-4 gap-4">
<Button
variant="outline"
className="hover:bg-white/20 transition-all duration-75"
>
75ms
</Button>
<Button
variant="outline"
className="hover:bg-white/20 transition-all duration-150"
>
150ms
</Button>
<Button
variant="outline"
className="hover:bg-white/20 transition-all duration-300"
>
300ms
</Button>
<Button
variant="outline"
className="hover:bg-white/20 transition-all duration-500"
>
500ms
</Button>
</div>
</div>
{/* Easing Examples */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Типы анимации</h4>
<div className="grid grid-cols-3 gap-4">
<Button
variant="outline"
className="hover:scale-110 transition-transform duration-300 ease-linear"
>
Linear
</Button>
<Button
variant="outline"
className="hover:scale-110 transition-transform duration-300 ease-in-out"
>
Ease In Out
</Button>
<Button
variant="outline"
className="hover:scale-110 transition-transform duration-300 ease-out"
>
Ease Out
</Button>
</div>
</div>
</CardContent>
</Card>
{/* Интерактивные анимации */}
<Card className="glass-card border-white/10">
<CardHeader>
<CardTitle className="text-white">Интерактивные анимации</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{/* Loading Progress */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Прогресс загрузки</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="flex items-center justify-between mb-4">
<span className="text-white text-sm">Прогресс: {progress}%</span>
<Button
variant="glass"
size="sm"
onClick={startProgress}
disabled={progress > 0 && progress < 100}
>
<Play className="h-4 w-4 mr-2" />
Запустить
</Button>
</div>
<Progress value={progress} className="mb-2" />
<div className="text-xs text-white/60">
{progress === 0 && "Нажмите 'Запустить' для начала"}
{progress > 0 && progress < 100 && "Загрузка..."}
{progress === 100 && "Загрузка завершена!"}
</div>
</div>
</div>
{/* Loading States */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Состояния загрузки</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="flex items-center justify-between mb-4">
<span className="text-white text-sm">Демо загрузки (3 сек)</span>
<Button
variant="glass"
size="sm"
onClick={showLoadingDemo}
disabled={isLoading}
>
{isLoading ? (
<>
<Loader className="h-4 w-4 mr-2 animate-spin" />
Загрузка...
</>
) : (
<>
<Zap className="h-4 w-4 mr-2" />
Загрузить
</>
)}
</Button>
</div>
{isLoading && (
<div className="space-y-3">
<div className="flex items-center space-x-3">
<div className="w-4 h-4 border-2 border-white/20 border-t-white rounded-full animate-spin"></div>
<span className="text-white/70 text-sm">Подключение к серверу...</span>
</div>
<div className="flex items-center space-x-3">
<div className="w-4 h-4 border-2 border-white/20 border-t-blue-400 rounded-full animate-spin"></div>
<span className="text-white/70 text-sm">Загрузка данных...</span>
</div>
<div className="flex items-center space-x-3">
<div className="w-4 h-4 border-2 border-white/20 border-t-green-400 rounded-full animate-spin"></div>
<span className="text-white/70 text-sm">Обработка результата...</span>
</div>
</div>
)}
</div>
</div>
{/* Notification Animation */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Анимация уведомлений</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="flex items-center justify-between mb-4">
<span className="text-white text-sm">Всплывающее уведомление</span>
<Button
variant="glass"
size="sm"
onClick={triggerNotification}
>
<Bell className="h-4 w-4 mr-2" />
Показать
</Button>
</div>
{showNotification && (
<div className="animate-in slide-in-from-right-5 duration-300">
<div className="glass-card p-3 rounded-lg border border-green-500/30 bg-green-500/10">
<div className="flex items-center space-x-3">
<CheckCircle className="h-5 w-5 text-green-400" />
<div>
<div className="text-white font-medium text-sm">Успешно!</div>
<div className="text-green-300/70 text-xs">Операция выполнена успешно</div>
</div>
</div>
</div>
</div>
)}
</div>
</div>
{/* Animation Toggle */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Переключение анимации</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="flex items-center justify-between mb-4">
<span className="text-white text-sm">Управление анимацией</span>
<Button
variant="glass"
size="sm"
onClick={() => setIsAnimating(!isAnimating)}
>
{isAnimating ? (
<>
<Pause className="h-4 w-4 mr-2" />
Остановить
</>
) : (
<>
<Play className="h-4 w-4 mr-2" />
Запустить
</>
)}
</Button>
</div>
<div className="grid grid-cols-4 gap-4">
<div className={`glass-card p-3 rounded-lg border border-white/10 text-center ${isAnimating ? 'animate-pulse' : ''}`}>
<div className="w-8 h-8 bg-blue-400 rounded-full mx-auto mb-2"></div>
<p className="text-white/70 text-xs">Pulse</p>
</div>
<div className={`glass-card p-3 rounded-lg border border-white/10 text-center ${isAnimating ? 'animate-bounce' : ''}`}>
<div className="w-8 h-8 bg-green-400 rounded-full mx-auto mb-2"></div>
<p className="text-white/70 text-xs">Bounce</p>
</div>
<div className={`glass-card p-3 rounded-lg border border-white/10 text-center ${isAnimating ? 'animate-spin' : ''}`}>
<div className="w-8 h-8 bg-purple-400 rounded-full mx-auto mb-2"></div>
<p className="text-white/70 text-xs">Spin</p>
</div>
<div className={`glass-card p-3 rounded-lg border border-white/10 text-center transition-all duration-1000 ${isAnimating ? 'scale-110 rotate-12' : 'scale-100 rotate-0'}`}>
<div className="w-8 h-8 bg-yellow-400 rounded-full mx-auto mb-2"></div>
<p className="text-white/70 text-xs">Transform</p>
</div>
</div>
</div>
</div>
</CardContent>
</Card>
{/* Сложные анимации */}
<Card className="glass-card border-white/10">
<CardHeader>
<CardTitle className="text-white">Сложные анимации</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{/* Staggered Animation */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Поэтапная анимация</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="grid grid-cols-5 gap-2">
{[1, 2, 3, 4, 5].map((item) => (
<div
key={item}
className="h-16 bg-gradient-to-r from-purple-500/20 to-pink-500/20 rounded animate-pulse border border-white/10"
style={{
animationDelay: `${item * 0.2}s`,
animationDuration: '2s'
}}
>
<div className="h-full flex items-center justify-center text-white/70 text-sm">
{item}
</div>
</div>
))}
</div>
</div>
</div>
{/* Chain Animation */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Цепочка анимаций</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="relative h-20">
<div className="absolute inset-0 flex items-center">
<div className="w-4 h-4 bg-blue-400 rounded-full animate-bounce"></div>
<div className="flex-1 h-0.5 bg-white/20 mx-2"></div>
<div className="w-4 h-4 bg-green-400 rounded-full animate-pulse"></div>
<div className="flex-1 h-0.5 bg-white/20 mx-2"></div>
<div className="w-4 h-4 bg-purple-400 rounded-full animate-spin"></div>
<div className="flex-1 h-0.5 bg-white/20 mx-2"></div>
<div className="w-4 h-4 bg-yellow-400 rounded-full animate-ping"></div>
</div>
</div>
</div>
</div>
{/* Card Flip Animation */}
<div>
<h4 className="text-white/90 text-sm font-medium mb-3">Переворот карточки</h4>
<div className="glass-card p-4 rounded-lg border border-white/10">
<div className="grid grid-cols-3 gap-4">
{[1, 2, 3].map((card) => (
<div
key={card}
className="relative h-32 [perspective:1000px] cursor-pointer group"
>
<div className="relative w-full h-full transition-transform duration-700 [transform-style:preserve-3d] group-hover:[transform:rotateY(180deg)]">
{/* Front */}
<div className="absolute inset-0 glass-card rounded-lg border border-white/10 [backface-visibility:hidden] flex items-center justify-center">
<div className="text-center">
<div className="w-8 h-8 bg-blue-400 rounded-full mx-auto mb-2"></div>
<p className="text-white text-sm">Карточка {card}</p>
</div>
</div>
{/* Back */}
<div className="absolute inset-0 glass-card rounded-lg border border-white/10 [backface-visibility:hidden] [transform:rotateY(180deg)] flex items-center justify-center">
<div className="text-center">
<Settings className="w-8 h-8 text-purple-400 mx-auto mb-2" />
<p className="text-white text-sm">Настройки</p>
</div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
</CardContent>
</Card>
</div>
)
}