动画类型
- 微交互
- 过渡动画
- 数据动画
- 加载动画
animate 是为界面添加有目的的动画的技能。它的核心是:让动画服务于用户体验,而不是为了炫技。
作为设计师/开发者,你可能遇到过:
animate 就是解决这些的。
用户会被动画吸引:
✅ 正确:- 重要变化用动画- 引导用户视线- 突出关键信息
❌ 错误:- 到处都用动画- 干扰用户操作需要反馈:
✅ 正确:- 点击有反应- 加载有提示- 成功有庆祝
❌ 错误:- 点击没反应- 静默操作- 不知道发生了什么元素关系可视化:
✅ 正确:- 新增元素入场- 删除元素离场- 移动元素轨迹
❌ 错误:- 突然出现/消失- 跳变按钮交互:
点击:- 按压效果- 颜色变化- 波纹效果
反馈:- 成功动画- 失败动画- 加载动画输入交互:
焦点:- 边框变化- 标签浮动- 阴影变化
验证:- 正确打勾- 错误抖动页面切换:
入场:- 从右滑入- 淡入
离场:- 向左滑出- 淡出模态框:
打开:- 背景变暗- 弹窗缩放- 内容淡入
关闭:- 弹窗缩小- 背景恢复- 离场数字变化:
滚动数字:- 从 0 滚动到目标值- 配合计数动画
图表:- 柱状图生长- 曲线绘制骨架屏:
显示:- 灰色块闪烁- 模拟内容加载
好处:- 感知更快- 不单调进度条:
显示:- 百分比进度- 进度动画
状态:- 进行中- 完成- 错误✅ 推荐:transform: translateX()transform: translateY()transform: scale()transform: rotate()opacity
❌ 不推荐:left, top, right, bottomwidth, heightmargin, 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);}动画类型
时间
属性
原则
查看源文件: GitHub原始文件