动画在网页里解决什么
网页动画不是为了炫技,而是帮用户理解界面的状态变化:元素从哪来、到哪去、谁和谁有关系。合理的转场让交互更连贯、操作结果可预期;滥用的动画则分散注意力、拖慢体验。好的动画克制、有目的、跟手。
动画的价值在于建立空间与因果关系,而不是让页面热闹起来。
- CSS 过渡状态变化时平滑补间,最常用。
- 关键帧多阶段动画,定义起止与中间帧。
- 缓动easing 曲线决定动效的手感。
- Canvas/WAAPI数据可视化与精细编排的动画。
CSS 过渡与关键帧
最简单的动画是 transition:元素属性变化时,浏览器自动在新旧值之间补间。按钮 hover 变色、卡片缩放,几行 CSS 就搞定。需要多阶段、循环、自动播放的动画用 @keyframes 定义关键帧,再用 animation 挂到元素上。
/* 过渡:hover 时平滑放大 */
.card { transition: transform 0.3s ease; }
.card:hover { transform: scale(1.05); }
/* 关键帧:让元素淡入上移 */
@keyframes rise {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.item { animation: rise 0.5s ease both; }
优先只动 transform 和 opacity——这两个属性不触发重排,由合成器直接处理,动画最流畅。
缓动函数:动画的灵魂
同样一段位移,匀速(linear)显得机械生硬,先快后慢(ease-out)自然舒服。缓动函数(cubic-bezier)控制速度曲线:入场用 ease-out(快出)、退场用 ease-in(快收)、弹性用 spring 曲线。选对缓动,同样的动画观感天差地别——这也是"动效设计"的主要打磨点。
实操上有几条经验法则:位移类动画用 ease-out(入场)和 ease-in(退场);带回弹的元素用带轻微过冲的 cubic-bezier,让它稍稍越过目标再收回,显得有弹性;需要连续跟随手指的手势动画,则用 spring 物理曲线,让元素黏在手指上、松手后自然衰减。切忌给所有动画套同一个 linear,那样整个界面会像在机械地爬行。
Canvas:可编程的动画画布
DOM 动画适合单个元素的状态变化;当要做几百上千个粒子、图表实时滚动、游戏画面这类每一帧都重画的内容,就用 Canvas。通过 requestAnimationFrame 每帧清屏、重算、重绘,配合鼠标事件做交互。代价是要自己管理每帧逻辑、没有 DOM 的便利,但灵活性最高。
写 Canvas 动画的核心是把状态和绘制分开:每帧先更新物体的位置、速度、旋转角这些数字,再把整个画布清掉、按新状态重画一遍。配合 requestAnimationFrame 把回调交给浏览器的重绘节奏,才能稳定在每秒六十帧。要控制内存,粒子用完要及时从数组里移除,否则长时间运行后帧率会被无谓的计算拖垮。
Web Animations API:JS 驱动动画
有时候需要用 JS 精确控制动画:动态时长、根据手势调整进度、播放完回调。Web Animations API(element.animate)让你在 JS 里定义关键帧与缓动,同时拥有 CSS 动画的性能(走合成器)和 JS 的控制力。它还支持暂停、反向、查询当前进度,是手势驱动动画的首选。
// 用 WAAPI 让一个元素沿路径滑入
el.animate(
[ { transform: 'translateX(-100%)' }, { transform: 'translateX(0)' } ],
{ duration: 400, easing: 'cubic-bezier(.2,.8,.2,1)' }
);
相比直接操作 CSS,WAAPI 还能把动画的时间轴绑定到页面滚动位置,元素就会随滚动逐帧变化,做滚动驱动的章节揭示、视差位移时非常顺手。它同样只动合成器能处理的属性,性能和 CSS 动画持平,却把播放控制权完整地交给了脚本。
性能与设计原则
原则:动画时长别太长(200-500ms 最合适)、只动 transform/opacity、给用户留减少动效的选项(prefers-reduced-motion)。别在同一页面堆太多动画,滚动时的视差和入场要克制。动画是调味料,不是主菜。
小结
把动画落到实战:
- 状态切换用 CSS transition,最省心。
- 多阶段自动播用 @keyframes。
- 花心思调缓动曲线,手感差异全在这。
- 大量粒子与实时画布用 Canvas。
- 手势与精细编排用 Web Animations API。