四、动画系统:CSS 优先 + Framer Motion 补充
HeroUI 的动画策略非常清晰:
4.1 动画分工
4.2 CSS 动画示例
所有交互状态变化都使用 CSS transition,无 JavaScript 开销:
/* HeroUI 内部的 CSS 动画实现(简化示例) */
.button {
transition: all 0.2s ease;
}
.button:hover {
transform: scale(1.02);
background-color: var(--primary-hover);
}
.button:active {
transform: scale(0.98);
}
4.3 Framer Motion 深度集成
对于 Modal 等组件的入场/出场动画:
// HeroUI Modal 内部使用 AnimatePresence
import { AnimatePresence, motion } from "framer-motion";
<AnimatePresence>
{isOpen && (
<motion.div
initial={
{ opacity: 0, scale: 0.95 }}
animate={
{ opacity: 1, scale: 1 }}
exit={
{ opacity: 0, scale: 0.95 }}
transition={
{ type: "spring", damping: 25, stiffness: 300 }}
>
{/* Modal 内容 */}
</motion.div>
)}
</AnimatePresence>
4.4 无障碍动画支持
HeroUI 自动检测用户的 prefers-reduced-motion 系统设置:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
当你需要禁用动画时:
<HeroUIProvider disableAnimation>
{children}
</HeroUIProvider>
4.5 自定义动画变体
如果你需要更精细的动画控制(比如想要一个从右侧滑入的 Modal),可以通过自定义 CSS 覆盖:
/* 自定义 Modal 入场动画 */
.my-modal {
animation: slideInRight 0.3s ease-out;
}
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(100%);
}
to {
opacity: 1;
transform: translateX(0);
}
}