跳转到内容

动画设计 (animate)

animate 是为界面添加有目的的动画的技能。它的核心是:让动画服务于用户体验,而不是为了炫技。

作为设计师/开发者,你可能遇到过:

  • “动画太慢/太快”
  • “动画看起来很假”
  • “不知道什么时候用动画”

animate 就是解决这些的。

用户会被动画吸引:
✅ 正确:
- 重要变化用动画
- 引导用户视线
- 突出关键信息
❌ 错误:
- 到处都用动画
- 干扰用户
操作需要反馈:
✅ 正确:
- 点击有反应
- 加载有提示
- 成功有庆祝
❌ 错误:
- 点击没反应
- 静默操作
- 不知道发生了什么
元素关系可视化:
✅ 正确:
- 新增元素入场
- 删除元素离场
- 移动元素轨迹
❌ 错误:
- 突然出现/消失
- 跳变

按钮交互

点击:
- 按压效果
- 颜色变化
- 波纹效果
反馈:
- 成功动画
- 失败动画
- 加载动画

输入交互

焦点:
- 边框变化
- 标签浮动
- 阴影变化
验证:
- 正确打勾
- 错误抖动

页面切换

入场:
- 从右滑入
- 淡入
离场:
- 向左滑出
- 淡出

模态框

打开:
- 背景变暗
- 弹窗缩放
- 内容淡入
关闭:
- 弹窗缩小
- 背景恢复
- 离场

数字变化

滚动数字:
- 从 0 滚动到目标值
- 配合计数动画
图表:
- 柱状图生长
- 曲线绘制

骨架屏

显示:
- 灰色块闪烁
- 模拟内容加载
好处:
- 感知更快
- 不单调

进度条

显示:
- 百分比进度
- 进度动画
状态:
- 进行中
- 完成
- 错误
✅ 推荐:
transform: translateX()
transform: translateY()
transform: scale()
transform: rotate()
opacity
❌ 不推荐:
left, top, right, bottom
width, height
margin, padding
/* 自然感 */
ease-in-out
/* 进入 */
ease-out
/* 退出 */
ease-in
/* 弹性 */
cubic-bezier(0.68, -0.55, 0.265, 1.55)
/* 弹跳 */
cubic-bezier(0.34, 1.56, 0.64, 1)
/* 微交互 */
150-200ms
/* 页面过渡 */
200-300ms
/* 复杂动画 */
300-500ms
/* 禁止 */
< 100ms(太快看不清)
> 1000ms(太慢等不及)
每个动画要有意义:
✅ 正确:
- 告诉用户发生了什么
- 引导注意力
- 提供反馈
❌ 错误:
- 为了酷而酷
- 干扰用户
动画要自然:
✅ 正确:
- 缓动函数自然
- 时间适中
- 流畅不卡顿
❌ 错误:
- 线性(机械感)
- 太快/太慢
- 卡顿掉帧
动画风格统一:
✅ 正确:
- 同类元素用同类动画
- 动画时间一致
- 缓动函数一致
❌ 错误:
- 随机
- 不一致
性能是底线:
✅ 正确:
- GPU 加速
- 简单动画
- 优雅降级
❌ 错误:
- 复杂动画
- 布局抖动
- 低端设备卡顿
/* 点击效果 */
.btn {
transition: transform 0.15s ease;
}
.btn:active {
transform: scale(0.95);
}
/* 成功效果 */
.btn.success {
animation: success-pulse 0.3s ease;
}
@keyframes success-pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.list-item {
opacity: 0;
transform: translateY(20px);
animation: fade-in 0.3s ease forwards;
}
@keyframes fade-in {
to {
opacity: 1;
transform: translateY(0);
}
}
/* 交错动画 */
.list-item:nth-child(1) { animation-delay: 0ms; }
.list-item:nth-child(2) { animation-delay: 50ms; }
.list-item:nth-child(3) { animation-delay: 100ms; }
/* 背景 */
.modal-overlay {
opacity: 0;
transition: opacity 0.2s ease;
}
.modal-overlay.active {
opacity: 1;
}
/* 弹窗 */
.modal {
opacity: 0;
transform: scale(0.9);
transition: all 0.2s ease;
}
.modal.active {
opacity: 1;
transform: scale(1);
}
function animateNumber(element, target) {
const duration = 1000;
const start = 0;
const startTime = performance.now();
function update(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
// 缓动函数
const easeOut = 1 - Math.pow(1 - progress, 3);
const current = Math.floor(start + (target - start) * easeOut);
element.textContent = current;
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
  • 这个动画有意义吗?
  • 对用户有帮助吗?
  • 会不会干扰用户?
  • 使用 transform/opacity?
  • 会引起布局抖动吗?
  • 低端设备能流畅运行吗?
  • 时间 150-500ms?
  • 缓动函数自然?
  • 不会太长?
  • 与其他动画风格一致?
  • 同类元素用同类动画?

动画类型

  • 微交互
  • 过渡动画
  • 数据动画
  • 加载动画

时间

  • 微交互:150-200ms
  • 过渡:200-300ms
  • 复杂:300-500ms

属性

  • transform
  • opacity
  • filter

原则

  • 目的性
  • 流畅性
  • 一致性
  • 性能
  • polish - 打磨
  • overdrive - 极限动画
  • optimize - 性能优化

查看源文件: GitHub原始文件