动画系统

了解 Lumi UI 的动画系统。

Lumi UI 提供了一套流畅的动画系统,我们沿用了Base UI 的动画系统,使用 CSS 过渡(Transitions) 而非传统的 CSS 动画(Keyframes),从而创造出更灵敏、更接近原生体验的效果,同时保持代码的简洁与可维护性。

核心理念

跨组件的一致性

通过将动画逻辑集中到共享的@utility中,你的整个应用能够保持统一的动效语言。这确保了每一个弹出框、模态框和下拉菜单在动效感受上都物理一致。

利用 CSS 过渡实现原生感

与大多数使用 CSS 动画(一旦开始就必须播放完成)的库不同,Lumi UI 使用了能追踪元素状态的 CSS 过渡。这意味着动画可以在播放中途平滑地反转方向,从而避免用户在快速交互时感受到“生硬跳变”。

简洁、极简的代码

用单一的utility替代冗长的动画类:

传统方式:

<PopoverPrimitive.Popup 
  className="data-[state=open]:animate-in data-[state=closed]:animate-out 
    data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 
    data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 ..." />

Lumi UI 方式:

<BasePopover.Popup className="animate-popup ..." />

可用的动画类

类名用途
animate-popup用于弹出框、下拉菜单、选择器等。
animate-dialog用于模态框和对话框。
animate-backdrop用于背景遮罩层。

详情见下文组件兼容性部分。

安装与设置

如果你已通过 CLI 安装了 init 命令,可以跳过本节。如果是手动安装,请将以下 CSS 添加到你的项目中。

@utility animate-popup {
  @apply origin-[var(--transform-origin)] transition-[opacity,scale,translate] duration-200;
 
  &[data-starting-style],
  &[data-ending-style] {
    opacity: 0;
    scale: 0.95;
  }
}
 
@utility animate-dialog {
  @apply transition-all duration-150;
 
  &[data-starting-style],
  &[data-ending-style] {
    opacity: 0;
    scale: 0.9;
  }
}
 
@utility animate-backdrop {
  @apply transition-all duration-100;
 
  &[data-starting-style],
  &[data-ending-style] {
    opacity: 0;
  }
}

组件级覆盖

如果有独特的动画需求,你可以直接覆盖这些工具类。

如何不使用默认动画

移除 animate-popupanimate-dialoganimate-backdrop 工具类,并使用标准的 Tailwind 类来获得完全的控制权:

<PopoverContent
  className="data-[ending-style]:scale-90 data-[ending-style]:opacity-0 
  data-[starting-style]:scale-90 data-[starting-style]:opacity-0 
  origin-[var(--transform-origin)] transition-[transform,scale,opacity]"
/>
<DialogContent
  className="transition-all duration-150 data-[ending-style]:scale-90 
  data-[ending-style]:opacity-0 data-[starting-style]:scale-90 
  data-[starting-style]:opacity-0"
/>
<DialogBackdrop className="transition-all duration-100 
data-[ending-style]:opacity-0 data-[starting-style]:opacity-0" />

组件兼容性

使用 animate-popup 的组件:


使用 animate-dialoganimate-backdrop 的组件:对话框 | 警示对话框