动画系统

了解 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-fade-up向上进入的 Sheet/Drawer。
animate-fade-down向下进入的对话框/Sheet。
animate-slide-left从右侧进入的 Sheet。
animate-slide-right从左侧进入的 Sheet。
animate-fade-zoom对话框/命令菜单的缩放过渡。
animate-fade背景遮罩与纯淡入淡出的浮层。

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

安装与设置

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

@utility animate-popup {
  @apply origin-[var(--transform-origin)] transition-[opacity,scale,transform] duration-200;
 
  &[data-starting-style],
  &[data-ending-style] {
    opacity: 0;
    scale: 0.95;
  }
}
 
@utility animate-fade-up {
  @apply transition-all duration-200 ease-[cubic-bezier(0.25,1,0.5,1)];
 
  &[data-starting-style],
  &[data-ending-style] {
    opacity: 0;
    scale: 0.98;
    translate: 0 0.5rem;
  }
}
 
@utility animate-fade-down {
  @apply transition-all duration-200 ease-[cubic-bezier(0.25,1,0.5,1)];
 
  &[data-starting-style],
  &[data-ending-style] {
    opacity: 0;
    scale: 0.98;
    translate: 0 -0.5rem;
  }
}
 
@utility animate-fade-zoom {
  @apply transition-all duration-200 ease-[cubic-bezier(0.25,1,0.5,1)];
 
  &[data-starting-style],
  &[data-ending-style] {
    opacity: 0;
    scale: 0.94;
  }
}
 
@utility animate-fade {
  @apply transition-all duration-200;
 
  &[data-starting-style],
  &[data-ending-style] {
    opacity: 0;
  }
}

组件级覆盖

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

如何不使用默认动画

移除 animate-popupanimate-fade-upanimate-fade-zoomanimate-fade-downanimate-fade 工具类,并使用标准的 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-200 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-200 
data-[ending-style]:opacity-0 data-[starting-style]:opacity-0" />

组件兼容性

animate-popup

用于跟随锚点或需要"弹性"入场效果的浮层组件:

animate-fadeanimate-fade-zoom

用于居中对齐的浮层或静态背景遮罩:

方向动画

用于边缘对齐的 Sheet对话框 变体:

  • animate-fade-up:Sheet(bottom)、Dialog(bottom
  • animate-fade-down:Sheet(top)、Dialog(top
  • animate-slide-left:Sheet(right
  • animate-slide-right:Sheet(left