当前位置: 首页 > 文档资料 > HTML5 在线教程 >

11.5 CSS 动画(animations)

优质
小牛编辑
171浏览
2023-12-01

我们前面提到过,转换(transitions) 实际上就是一种特殊的CSS动画:

  • 只有两个状态: 起始状态和终止状态
  • 动画不会出现循环
  • 中间状态只能由时变函数(transition-timing-function)来控制

实际动画需求要复杂得多,比如我们可能会需要:

  • 自动播放的动画(不会有交互状态)
  • 控制中间状态
  • 创建循环动画
  • 在同一个HTML元素上应用不同的动画
  • 在动画过程中控制不同的元素属性
  • 给不同的属性应用不同的时变函数

这个时候就需要使用CSS3动画(animation)特性,而且提供了更多的功能。

CSS3动画就像一部迷你电影,里面有演员(HTML元素)、剧本(keyframes)以及动作片段(CSS规则)。

animation 属性

transition 属性一样,animation 是一组动画属性的速写

  • name: 动画名称
  • duration: 动画持续时间
  • timing-function: 时变函数,用来计算中间状态
  • delay: 延时,在一定时候后启动动画
  • iteration-count: 动画重复的次数
  • direction: 动画的运行方向,可以是反过来的
  • fill-mode: 动画填充模式,用来确定动画开始之前和结束之后的样式

例1:提示信息自动淡出动画

代码很简单,就是把keyframes(下面会讲解)的最后一帧设置为透明,持续时间3s。为了演示,我们把animation的循环模式设置为infinite。实际使用时需要修改为forwards,即停留在最后的状态。

例2:按钮弹跳动画

我们给一个按钮添加弹跳(bouncing)动画:

@keyframes bouncing{
  0%  { bottom: 0; box-shadow: 0 0 5px rgba(0,0,0,0.5);}
  100%{ bottom: 50px; box-shadow: 0 50px 50px rgba(0,0,0,0.1);}
}

.loading-button{ animation: bouncing 0.5s cubic-bezier(0.1,0.25,0.1,1) 0s infinite alternate both;}
Loading

首先我们选定“演员”为一个加载按钮(html元素),然后设定其表演剧本(keyframes)为弹跳,然后添加一些动作指令(CSS规则)来创建一个CSS3动画:

  • name: bouncing (动画名称必须和keyframes名称一致)
  • duration: 0.5s (持续0.5秒)
  • timing-function: cubic-bezier(0.1,0.25,0.1,1)
  • delay: 0s (没有延迟)
  • iteration-count: infinite (无限循环)
  • direction: alternate (交替往返)
  • fill-mode: both(填充模式同时应用backwards和forwards规则,后面会详细说明)

@keyframes

在“电影开拍”之前,我们得创建“剧本”(@keyframes,即关键帧),用来规定动画中间的每一个表演步骤。@keyframes通过percentages(百分比格式的时间坐标)来定义:

  • 0% 动画的第一帧(可选)。
  • 50% 动画的中间时间节点。
  • 100% 动画的最后一帧。

我们也可以分别使用关键词 fromto 来代替 0%100%

你可以定义任意多的keyframes,比如 33%, 4% 乃至 29.86%

每个 keyframe 都是一个 CSS规则,定义这个时间节点下元素的某个或某些属性。

@keyframes 具体语法定义如下:

@keyframes animationname {keyframes-selector {css-styles;}}

  • animationname: 必需。定义动画的名称。
  • keyframes-selector: 必需。百分比格式的时间坐标。合法的值:0-100% | from(与 0% 相同)| to(与 100% 相同)。
  • css-styles: 必需。一个或多个合法的 CSS规则(样式定义)。
@keyframes around {
  0%  { left: 0; top: 0;}
  25% { left: 240px; top: 0;}
  50% { left: 240px; top: 240px;}
  75% { left: 0; top: 240px;}
  100%{ left: 0; top: 0;}
}
p{ animation: around 4s linear infinite;}

上面的例子把起点 0% 和终点 100% 设置成一样的状态,并且是 infinite 播放,这样可以确保动画的两次播放之间的无缝衔接。

另外如果若干时间节点具有相同的样式,可以合并在一起简写,比如:

@keyframes around {
  0%, 100%  { left: 0; top: 0;}
}

如果在@keyframes中0%和100%时间点所设置的属性有默认值,那么有些情况下可以忽略不写。

动画名称(animation-name)

动画名称(animation-name)会至少出现两次:

  • 一次是“编写剧本” @keframes 时。
  • 一次是“演员入戏”时,即设置HTML元素的 animation-name 属性值为“剧本”的名称(或者在 animation 速写中)。
@keyframes scenario{
  /* ... */
}

.selector{ animation-name: scenario;}

和CSS class名称一样,animation 的名称只能包含:

  • 字母 (a-z)
  • 数字 (0-9)
  • 下划线 underscore (_)
  • 中划线 dash (-)

不能以数字或者两个中划线开始。

动画持续时间(animation-duration)

transition durations 一样,animation durations 可以设置为 1s毫秒 200ms

.selector{ animation-duration: 0.5s;}

默认值为 0s,即不会有动画出现。

动画时变函数(animation-timing-function)

transition timing functions 一样,animation timing functions 可以使用一些预定义的关键词比如 linear, ease-out, 或者使用cubic bezier函数来自定义。

.selector{ animation-timing-function: ease-in-out;}

缺省值是 ease

我们可以通过设置线性时变函数以及自定义的@keyframes来模拟复杂的贝塞尔曲线。Bounce.js 就是这样一个在线高级动画生成工具,支持导出CSS样式代码。

animation-delay

transition delays 一样,animation delays 可以设置为 1s毫秒 200ms

默认值为 0s,即不会有延迟。

这个属性在触发多个时间交替的动画序列时很有用。

.a,.b,.c{ animation: bouncing 1s;}
.b{ animation-delay: 0.25s;}
.c{ animation-delay: 0.5s;}

动画循环次数(animation-iteration-count)

默认情况下,动画只运行一次(即默认值为 1),你可以设置3种类型的数值:

  • 整数23
  • 小数0.5,意味着只运行动画的一半
  • the 关键词 infinite 无限重复
.selector{ animation-duration: infinite;}

动画方向(animation-direction)

animation-direction 定义浏览器对@keyframes的读取顺序。

  • normal: 正常方向,从 0% 开始,到 100% 结束,然后再从 0% 开始。
  • reverse: 相反方向,从 100% 开始,到 0% 结束,然后再从 100% 开始。
  • alternate: 交替方向,从 0% 开始,到 100% ,再到 0%
  • alternate-reverse: 反向交替方向,从 100% 开始,到 0%,再到 100%

通过下面的循环动画,对比小方块的运动轨迹,可以比较直观的感受这几个方向取值之间的差别:

Normal: 0% --> 100%

Reverse: 100% --> 0%

Alternate: 0% <--> 100%

Alternate reverse: 100% <--> 0%

动画填充模式(animation-fill-mode)

animation-fill-mode 用来确定动画开始之前和结束之后的状态。这样才是一个完整的动画过程。

通过 keyframes 我们定义了动画不同阶段下的CSS规则,这有可能会和已经定义的样式冲突。

填充模式属性允许我们告诉浏览器是否动画样式在动画之外也生效。

让我们想象这样一个按钮

  • 默认是红色
  • 在动画开始时被设置为绿色
  • 在动画结束时被设置为蓝色
animation-fill-mode动画开始前动画开始时动画结束时动画结束后
noneDefaultStartEndDefault
forwardsDefaultStartEndEnd
backwardsStartStartEndDefault
bothStartStartEndEnd

1. 动画之前 2. 动画期间 3. 动画之后

None: 动画样式不会影响默认样式

缺省为红色 从蓝变绿 变回缺省红色

Forwards: 动画结束时的样式被保持到动画结束后

缺省为红色 从蓝变绿 保持绿色

Backwards: 动画开始时的样式会被预置到动画开始前(即默认样式会被覆盖)

总是蓝色 从蓝变绿 变回缺省红色

Both: 动画开始时的样式会被预置到动画开始前,动画结束时的样式被保持到动画结束后

总是蓝色 从蓝变绿 保持绿色

我们可以简单的理解为:forwards就是动画样式作用区间向时间轴正方向(->)延伸,backwards则向负方向(<-)延伸,而both就是双向()延伸。从而影响到相邻区间的默认样式。