跳转到内容

动效

动效只做三件事:告诉你按到了、告诉你东西从哪来到哪去、告诉你什么在变。三档时长、一组语义缓动、一条按压时间线、三类浮层进出场——全部是令牌与共享关键帧,皮肤只引用,不自己发明。

时长与缓动

令牌取值说明
--xh-duration-fast120ms微反馈:换面、按下、退场
--xh-duration-normal200ms入场、释放、位移
--xh-duration-slow320ms大面积滑入:Drawer、Sheet
令牌取值说明
--xh-ease-standardcubic-bezier(0.2, 0, 0, 1)连续变化:颜色、按下
--xh-ease-outcubic-bezier(0, 0, 0.2, 1)入场
--xh-ease-out-strongcubic-bezier(0.23, 1, 0.32, 1)强入场、释放回弹
--xh-ease-out-fluidcubic-bezier(0.32, 0.72, 0, 1)大面积滑入
--xh-ease-incubic-bezier(0.4, 0, 1, 1)退场
--xh-ease-in-outcubic-bezier(0.4, 0, 0.2, 1)扫过:进度、指示条移动
--xh-ease-out-backcubic-bezier(0.34, 1.56, 0.64, 1)落定:拖动结束的轻微过冲

组件不直接取这两组原语,取语义层的 --xh-motion-*duration-enter / exit / micro / slide / press / releaseease-enter / enter-strong / exit / slide / sweep / press / release / settle / continuous、位移 distance-sm / md(4 / 8px)、缩放 scale-enter 0.96 / exit 0.98 / press 0.97 / drag 1.12、错开起播 stagger-step。CSS 串与 JS 侧 @xihan-ui/motion 的采样函数同一份来源,门禁 check-motion-source 比对。

按压触感

定尺的独立动作控件(按钮、把手、方框、星、日历格、色块、排序钮)投影 Action Control 配方,按下与释放走同一条时间线:

阶段时长结果缓动
按下120ms(--xh-motion-duration-pressscale 1 → 0.97,底进入 active--xh-motion-ease-press
释放200ms(--xh-motion-duration-releasescale 0.97 → 1,底回到 hover / rest--xh-motion-ease-release
  • transform origin 固定居中;指针 :active、键盘 Space / Enter 与 Headless 投影的 data-pressed 三者一致。
  • 行级条目与 disclosure trigger(菜单项、树节点、表格行、手风琴标题)只换面,不缩放整个条目;不允许零反馈。
  • 不用点击波纹;不允许组件自设 0.94 / 0.96 / 0.98 等缩放。
  • 业务事件不等动画结束:按下首帧先于异步 loading 可见;pending 后锁定重复操作,不持续缩放。
  • hover + pressed 时 pressed 优先;focus-visible + pressed 保留焦点环、按压只改内部表面;selected / danger + pressed 保留各自身份,在其上派生 active 面。

Disclosure

  • Surface 级展开(Accordion、Collapsible、Reasoning、ToolCall)内容走 grid-template-rows: 0fr → 1fr:入场 --xh-motion-duration-enter + --xh-motion-ease-enter-strong,退场 --xh-motion-duration-exit + --xh-motion-ease-exit;指示器旋转与内容同档。
  • 密集树形展开(Tree、TreeSelect、JsonViewer、SideNav 内联子层)不动高度,只旋转指示器 --xh-motion-duration-micro

浮层进出场

按锚定关系三分,关键帧集中在 family/motion.css,皮肤不得重定义:

关系关键帧组件
锚定列表 / 菜单xh-overlay-slide-in / outMenu、Select、Combobox、Cascader、ContextMenu、Menubar、Mention、TreeSelect、Date / Time picker、Tooltip
锚定面板xh-overlay-pop-in / xh-pop-outPopover、HoverCard、Popconfirm、Tour、Command
无锚定弹出xh-pop-in / outNavigationMenu、SideNav popout、FloatingPanel、FloatButton 列表、Pagination 弹层

遮罩与全屏面 xh-fade-in / out;Dialog / Notification = 位移 md + scale-enter;Drawer 入场 --xh-motion-duration-slide + --xh-motion-ease-slide、退场 --xh-motion-duration-exit + --xh-motion-ease-exit。退场由 Presence 等动画真正结束再卸载节点。

弹簧与 JS 动画

指针跟手的东西(拖动、滑杆、轮播惯性)不用固定时长,用 @xihan-ui/motion 的弹簧:由刚度、阻尼与质量算终点,中途换目标不跳帧。animate() 默认取 durations.normal@xihan-ui/animations 的配方默认取 durations.slow。见 动效原语动画层

减弱动效

data-motion="reduce"(偏好 system 时跟 prefers-reduced-motion)取消位移与缩放,保留即时换面:按下仍然换底、浮层仍然出现,只是不再滑动与缩放。JS 侧经 resolveMotionPreference 读同一个值——退场租约、贴底滚动、数字动画、加载弧线、背景层全部走这一条通道,产品自己的"减弱动效"设置用 setMotionOverride 一处设置、处处生效。

相关

Released under The MIT License