Files
mixvideo-v2/apps/desktop/src/components/PageTransition.tsx
imeepos c366261008 feat: UI美化和UX改进 v0.1.5
- 优化设计系统和主题配置
  - 增强Tailwind配置,添加更丰富的色彩系统
  - 新增多种动画效果和过渡动画
  - 改进字体系统和间距设置
  - 添加阴影变体和渐变效果

- 改进项目列表页面UI/UX
  - 重新设计页面头部,添加渐变背景和统计信息
  - 优化项目卡片布局和响应式设计
  - 增强加载和错误状态的视觉效果
  - 添加交错动画效果

- 优化项目卡片组件
  - 重新设计卡片布局,添加背景装饰
  - 改进统计信息展示,使用渐变背景和徽章
  - 增强悬停效果和交互反馈
  - 优化菜单和按钮设计

- 改进表单和模态框体验
  - 重新设计模态框头部和布局
  - 增强表单字段的视觉设计和验证反馈
  - 添加加载状态和成功状态指示
  - 改进按钮样式和交互效果

- 增强加载状态和反馈机制
  - 重新设计EmptyState组件,添加装饰效果
  - 增强LoadingSpinner,支持多种动画样式
  - 改进ErrorMessage组件,支持多种消息类型
  - 新增SkeletonLoader组件用于骨架屏加载

- 添加微交互和动画效果
  - 新增AnimatedButton组件,支持涟漪效果
  - 创建PageTransition组件用于页面过渡
  - 添加多种动画工具组件
  - 增强按钮和卡片的微交互效果

- 优化响应式设计和移动端体验
  - 改进容器布局和间距设置
  - 优化移动端的触摸体验
  - 确保所有组件在不同屏幕尺寸下的完美适配

遵循前端开发规范,提升界面美观性和用户体验
2025-07-14 00:23:58 +08:00

210 lines
4.2 KiB
TypeScript

import React, { useEffect, useState } from 'react';
interface PageTransitionProps {
children: React.ReactNode;
className?: string;
delay?: number;
}
/**
* 页面过渡动画组件
* 提供平滑的页面切换效果
*/
export const PageTransition: React.FC<PageTransitionProps> = ({
children,
className = '',
delay = 0
}) => {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const timer = setTimeout(() => {
setIsVisible(true);
}, delay);
return () => clearTimeout(timer);
}, [delay]);
return (
<div
className={`
transition-all duration-500 ease-out
${isVisible
? 'opacity-100 translate-y-0'
: 'opacity-0 translate-y-4'
}
${className}
`}
>
{children}
</div>
);
};
/**
* 交错动画容器
* 为子元素提供依次出现的动画效果
*/
export const StaggeredContainer: React.FC<{
children: React.ReactNode;
staggerDelay?: number;
className?: string;
}> = ({ children, staggerDelay = 100, className = '' }) => {
return (
<div className={className}>
{React.Children.map(children, (child, index) => (
<PageTransition delay={index * staggerDelay}>
{child}
</PageTransition>
))}
</div>
);
};
/**
* 滑入动画组件
*/
export const SlideIn: React.FC<{
children: React.ReactNode;
direction?: 'left' | 'right' | 'up' | 'down';
delay?: number;
className?: string;
}> = ({ children, direction = 'up', delay = 0, className = '' }) => {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const timer = setTimeout(() => {
setIsVisible(true);
}, delay);
return () => clearTimeout(timer);
}, [delay]);
const getTransformClasses = () => {
const transforms = {
left: isVisible ? 'translate-x-0' : '-translate-x-8',
right: isVisible ? 'translate-x-0' : 'translate-x-8',
up: isVisible ? 'translate-y-0' : 'translate-y-8',
down: isVisible ? 'translate-y-0' : '-translate-y-8'
};
return transforms[direction];
};
return (
<div
className={`
transition-all duration-500 ease-out
${isVisible ? 'opacity-100' : 'opacity-0'}
${getTransformClasses()}
${className}
`}
>
{children}
</div>
);
};
/**
* 缩放动画组件
*/
export const ScaleIn: React.FC<{
children: React.ReactNode;
delay?: number;
className?: string;
}> = ({ children, delay = 0, className = '' }) => {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const timer = setTimeout(() => {
setIsVisible(true);
}, delay);
return () => clearTimeout(timer);
}, [delay]);
return (
<div
className={`
transition-all duration-300 ease-out
${isVisible
? 'opacity-100 scale-100'
: 'opacity-0 scale-95'
}
${className}
`}
>
{children}
</div>
);
};
/**
* 悬停放大组件
*/
export const HoverScale: React.FC<{
children: React.ReactNode;
scale?: number;
className?: string;
}> = ({ children, scale = 1.05, className = '' }) => {
return (
<div
className={`
transition-transform duration-200 ease-out
hover:scale-[${scale}]
${className}
`}
>
{children}
</div>
);
};
/**
* 悬停倾斜组件
*/
export const HoverTilt: React.FC<{
children: React.ReactNode;
degree?: number;
className?: string;
}> = ({ children, degree = 2, className = '' }) => {
return (
<div
className={`
transition-transform duration-200 ease-out
hover:rotate-[${degree}deg]
${className}
`}
>
{children}
</div>
);
};
/**
* 脉冲动画组件
*/
export const Pulse: React.FC<{
children: React.ReactNode;
className?: string;
}> = ({ children, className = '' }) => {
return (
<div className={`animate-pulse ${className}`}>
{children}
</div>
);
};
/**
* 呼吸动画组件
*/
export const Breathe: React.FC<{
children: React.ReactNode;
className?: string;
}> = ({ children, className = '' }) => {
return (
<div className={`animate-breathe ${className}`}>
{children}
</div>
);
};