深挖基于 CSS 的变换与动画技术
深挖基于 CSS 的变换与动画技术
李俊才 的 CSDN 博客
邮箱 :[email protected]
CSDN 主页:https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343
本文地址:https://blog.csdn.net/qq_28550263/article/details/123649691
相关文章推荐:
- vue3 中使用动画技术:https://blog.csdn.net/qq_28550263/article/details/122892028
TODO: - 补充二维部分的案例;- ★扩展写作三维变换。
目 录
1. 概述
2. 二维变换
- 2.1 原点变换
- 2.2 平移变换
- 2.2.1 沿横轴平移:
translateX
() - 2.2.2 沿纵轴平移:
translateY
() - 2.2.3 双轴平移:
translate
()
- 2.2.1 沿横轴平移:
- 2.3 缩放与变形
- 2.3.1 缩放
- 2.3.1.1 沿 X 轴缩放:
scaleX
() - 2.3.1.2 沿 Y 轴缩放:
scaleY
() - 2.3.1.3 双轴同时缩放:
scale
()
- 2.3.1.1 沿 X 轴缩放:
- 2.3.2 变形
- 2.3.2.1 水平变形
skewX
() - 2.3.2.2 垂直变形
skewY
() - 2.3.2.3 双轴同时变形
skew
()
- 2.3.2.1 水平变形
- 2.3.1 缩放
- 2.4 旋转(二维)
rotate()
函数
- 2.5 多重变换
- 2.6 二维矩阵变换
- 2.6.1 什么是矩阵变换
- 2.6.2
matrix
() 函数
3. 基于过度的动画
- 3.1 什么是过度(transitions)
- 3.2 过度定义的相关属性
- 3.2.1 控制过度属性:transition-property属性
- 3.2.2 控制过度快慢:transition-duration属性
- 3.2.3 过渡计时函数属性:transition-timing-function属性
- 3.2.3.1
缓动过度
的概念 - 3.2.3.2 线性缓动函数
- 3.2.3.3 三次贝塞尔函数 和
弹性过度
- 1. 关于贝塞尔函数
- 2. CSS 中的
cubic-bezier()
函数
- 3.2.3.3 步进的概念 与CSS 中的
steps
() 函数- 1 步进的概念
- 2 CSS 中的
steps
() 函数语法
- 3.2.3.4 步进的概念 与CSS 中的
steps
函数- 1 步进的概念
- 2 CSS 中的步进函数语法
- 3.2.3.1
- 3.2.4 延时过度属性:transition-delay
4. CSS的关键帧动画
- 4.1 从 过度 到 关键帧
- 4.2 定义和使用关键帧序列动画
- 4.3 曲线动画
5. 进阶 - 三维变换
附录
- CSS可动画属性
1. 概述
本文详细介绍了 CSS 中的变换 和 关键帧动画。变换 会计算被变换元素上的没一点,然后得到其在本地坐标系中的一个坐标。从本质效果上看变换和关键帧动画都是动画,他们实现了两个或者多个样式状态之间切换的动态效果。
2. 二维变换
属性 | 描述 | 说明 |
---|---|---|
transform-origin |
指定原点的位置。默认值为元素的中心,可以被移动。很多变形需要用到这个属性,比如旋转,缩放和倾斜,他们都需要一个指定的点作为参数。 | |
transform |
指定作用在元素上的变形。取值为空格分隔的一系列变形的列表,他们会像被组合操作请求一样被分别执行。 |
2.1 原点变换
transform-origin
属性用于控制原点的位置,指定不同的值可以对原点进行变换。
你可以使用top
、bottom
、center
、right
、left
以及他们的组合来表示原点的位置,原点相对于盒子的位置如图示意:
例如:
transform-origin: center;
你也可以指定一个具体的值,如:
transform-origin: 10px 20px;
更多语法示范:
/* 单值语法 */transform-origin: 2px;transform-origin: bottom;/* x轴-偏移 | y轴-偏移*/transform-origin: 3cm 2px;/* x轴-偏移-keyword | y轴-偏移*/transform-origin: left 2px;/* x轴-偏移-keyword | y轴-偏移-keyword */transform-origin: right top;/* y轴-偏移-keyword | x轴-偏移-keyword */transform-origin: top right;/* x轴-偏移 | y-偏移| z轴-偏移 */transform-origin: 2px 30% 10px;/* x轴-偏移-keyword | y轴-offset | z-偏移 */transform-origin: left 5px -3px;/* x轴-偏移-keyword | y轴-offset-keyword | z-偏移 */transform-origin: right bottom 2cm;/* y轴-偏移-keyword | x轴-offset-偏移 | z-偏移 */transform-origin: bottom right 2cm;/* Global values */transform-origin: inherit;transform-origin: initial;transform-origin: unset;
2.2 平移变换
平移指将元素沿着某个方向上移动到一个新的位置。你可以仅沿着某一个轴平移,也可以同时沿着两个轴平移,不管怎么样平移它的移动轨迹都是一条直线段。应用平移变换由以下三个函数:
平移变换 | 描述 |
---|---|
translateX () |
沿着横轴方向移动 |
translateY () |
沿着纵轴方向移动 |
translate () |
二维平面中任意方向平移 |
2.2.1 沿横轴平移:translateX
()
语法
translateX(t)
参数 | 描述 |
---|---|
t |
代表了向量平移的横坐标长度 或 。百分比指的是盒子高度,盒子由属性 transform-box 定义。 |
例如
<body> <div class="translate-x">translateX(50%)</div></body><style> .translate-x { width: 150px; height:100px; background-color: #B1DCFF; color: #FF7B38;font-weight:bold; text-align: center; transition: all .3s linear;}.translate-x:hover { transform: translateX(50%);}</style>
其效果如下:
2.2.2 沿纵轴平移:translateY
()
语法
/* values */transform: translateY(200px);transform: translateY(50%);
例如
<body> <div class="translate-y">translateY(50%)</div></body><style> .translate-y { width: 150px; height:100px; background-color: #B1DCFF; color: #FF7B38;font-weight:bold; text-align: center; transition: all .3s linear;}.translate-y:hover { transform: translateY(50%);}</style></html>
其效果如下:
2.2.3 双轴平移:translate
()
语法
translate(50%,50%) .translate { width: 150px; height:100px; background-color: #B1DCFF; color: #FF7B38;font-weight:bold; text-align: center; transition: all .3s linear;}.translate:hover { transform: translate(50%,50%);}
例如
<body> <div class="translate">translate(50%,50%)</div></body><style> .translate { width: 150px; height:100px; background-color: #B1DCFF; color: #FF7B38;font-weight:bold; text-align: center; transition: all .3s linear;}.translate:hover { transform: translate(50%,50%);}</style>
其效果如下:
2.3 缩放与变形
2.3.1 缩放
缩放函数 | 描述 |
---|---|
scaleX() |
沿着 X 轴缩放 |
scaleY() |
沿着 Y 轴缩放 |
scale() |
用于同时在 X 和 Y 轴上缩放 |
2.3.1.1 沿 X 轴缩放:scaleX()
scaleX(sx) 也可使用 scale(sx, 1)
或 scale3d(sx, 1, 1)
来表示(虽然很没有必要如此自己作弄自己),它表示将一个元素沿着横轴进行缩放。
语法
scaleX(s)
其中参数 s
表示方法的比例。
例如:
<html><head> <meta charset="utf-8"> </head><body> <p></p> <p class="scale2"></p></body><style> p{ padding:0; border:0; margin:0; width: 50px; height: 50px; background-color: #cdcdcd;}.scale2{ transform: translateX(200%) scaleX(2); background-color: green;}</style></html>
其效果为:
2.3.1.2 沿 Y 轴缩放:scaleY()
scaleX(sx) 也可使用 scale(1, sy)
或 scale3d(1, sy, 1)
来表示,它表示将一个元素沿着纵轴进行缩放。
语法
scaleY(s)
例如
<html><head> <meta charset="utf-8"> </head><body> <p></p> <p class="scale2"></p></body><style> p{ padding:0; border:0; margin:0; width: 50px; height: 50px; background-color: #cdcdcd;}.scale2{ transform: translateX(200%) scaleY(2); background-color: #FF7B38;}</style></html>
其效果为:
2.3.1.3 双轴同时缩放:scale()
图: scale(2, 2)
该变换用于对元素同时在 X 和 Y 轴上缩放,它通过一个二维向量确定在一个方向缩放的多少。如果缩放向量的两个坐标是相等的,那么所讲是均等的,或者说是各向同的,同时元素的形状是被保持的。这种情况下进行的是位似变换。
当坐标值处于区间 [-1, 1] 之外时,该变换将在相应的坐标方向上放大该元素,当处在区间之中时,该变换将在相应的坐标方向上缩小该元素。当值为1时将不进行任何处理,当为负数时,将进行像素点反射之后再进行大小的修改。
语法
scale(sx)scale(sx, sy)
参数 | 描述 |
---|---|
sx | ,表示缩放向量的横坐标。 |
sy | ,表示缩放向量的纵坐标。如果未设置,则他的默认值被设置为 sx。 从而使得元素在保持原有形状下均等缩放 |
例如:
<html><head> <meta charset="utf-8"> </head><body> <p></p> <p class="scale2"></p></body><style> p{ padding:0; border:0; margin:0; width: 50px; height: 50px; background-color: #cdcdcd;}.scale2{ transform: translateX(200%) scale(2,2); /* scale(2,2) 简写为scale(2),等同于同时使用变换: scaleX(2) scaleY(2);*/ background-color: blue;}</style></html>
其效果为:
2.3.2 变形
形变函数 | 描述 |
---|---|
skewX() |
该转换将元素倾斜到二维平面上的 水平方向 |
skewY() |
将元素倾斜到二维平面上的 垂直方向 |
skew() |
维平面上的倾斜转换 |
2.3.2.1 水平变形 skewX()
语法
skewX(a)
参数 | 描述 |
---|---|
a |
是一个 ,表示用于沿横坐标扭曲元素的角度。 |
例如
<body> <div>无变形</div> <div class="skewed">skewX变形</div></body><style> div { width: 80px; height: 80px; background-color: skyblue;}.skewed { transform: translate(200%, -100%) skewX(35deg);; background-color: pink;}</style>
其效果如下:
2.3.2.2 垂直变形 skewY()
语法
skewY(a)
参数 | 描述 |
---|---|
a |
是一个 ,表示元素沿纵坐标扭曲的角度。 |
例如
<body> <div>无变形</div> <div class="skewed">skewY变形</div></body><style> div { width: 80px; height: 80px; background-color: skyblue;}.skewed { transform: translate(200%, -70%) skewY(35deg);; background-color: pink;}</style>
其效果如下:
2.3.2.3 双轴同时变形 skew()
语法
skew(ax)skew(ax, ay)
参数 | 描述 |
---|---|
ax |
是一个 ,表示用于沿横坐标扭曲元素的角度。 |
ay |
是一个 ,表示用于沿纵坐标扭曲元素的角度。如果未定义,则其默认值为0,导致纯水平倾斜。 |
例如
<body> <div>无变形</div> <div class="skewed">变形</div></body><style> div { width: 80px; height: 80px; background-color: skyblue;}.skewed { transform: translate(200%, -100%) skew(60deg); background-color: pink;}</style>
其效果如下:
2.4 旋转
transform-origin
属性还可以指定 rotate()
函数对元素进行旋转,这是一个二维的旋转函数。该函数对应的三维版本为rotate3d()
。
旋转函数 | 描述 | 说明 |
---|---|---|
rotate() |
二维旋转 | |
rotate3d() |
三维旋转 | 见 三维变换部分 |
rotateX() |
它可以让一个元素围绕 水平轴 旋转 | 见 三维变换部分 |
rotateY() |
它可以让一个元素围绕 垂直轴 旋转,而不会对其进行变形。 | 见 三维变换部分 |
rotate()
函数
rotate属性允许你单独设置transform的旋转属性。这种映射方式可以让我们更方便的设置我们想要的效果,并且避免了简写形式需要记忆属性顺序的不方便之处。
语法
/* Keyword values */scale: none;/* Angle value */rotate: 90deg;rotate: 0.25turn;rotate: 1.57rad;/* x, y, or z axis name plus angle */rotate: x 90deg;rotate: y 0.25turn;rotate: z 1.57rad;/* Vector plus angle value */rotate: 1 1 1 90deg;
例如:
<body> <div class="rotate">rotate(90deg)</div></body><style> .rotate { width: 150px; height:100px; background-color: #cdcdcd; color: #FF7B38;font-weight:bold; text-align: center; transition: all .3s linear;}.rotate:hover { transform: rotate(90deg); background-color: #B1DCFF;}</style>
其效果如下:
2.5 多重变换
提供给transform
属性以至于以空格分隔形式的列表值,可以同时应用 多重变换,多重变换 是基于单个变换的先后顺序应用而成,列表项中的单个变换的先后顺序也就是多重变换的应用顺序。
在平移变换的例子中,我们就同时使用了两个变换:
transform: translateX(200%) scale(2,2);
当然我们也能够应用更多的变换,只要符合这个格式即可。
2.6 二维矩阵变换
2.6.1 什么是矩阵变换
在线性代数学中我们所使用的二次型(quadratic form)就是典型的矩阵变换,它在几何上看实际上就是求一个变换矩阵 X 将一个看起来 歪 这的图形 “扳正”,这是十分特殊的一类矩阵变换。事实上我们在图形上,可以使用一个变换矩阵X 来完成一个图形的平移、旋转、形变等多个变换的组合,当应用于二维图形时,这就是 CSS 中的 二维矩阵变换,在后面的章节中,一样的原理还有 三维矩阵变换。
变换函数 | 描述 |
---|---|
matrix() |
二维矩阵变换 |
matrix3d() |
三维矩阵变换,见第5节 三维变换章节 |
2.6.2 matrix() 函数
语法
二维可以看作特殊的三维,因此 matrix(a, b, c, d, tx, ty)
可以看作是三维矩阵变换 matrix3d(a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, tx, ty, 0, 1)
的简写。其语法格式为:
matrix(a, b, c, d, tx, ty)
参数 | 描述 |
---|---|
a b c d | 描述线性变换的 。 |
tx ty | 描述如何应用这个变换的 。 |
这些值表示以下函数:
matrix( scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY() )
例如
<body> <div></div> <div class="changed"></div></body><style> div { width: 80px; height: 80px; background-color: skyblue;}.changed { transform: matrix(1, .5, -1, 1, 40, 40); background-color: pink;}</style>
其效果为:
3. 基于过度的动画
3.1 什么是过度(transitions)
CSS 过度(transitions)提供了一种 在更改CSS属性时控制动画速度 的方法。 实际上过度(transitions)是一种隐性动画
,我们需要给浏览器指定两个状态
,在两个状态之间使用过度可以让属性的变化成为一个持续一段时间的过程
,而不是立即完成的。
3.2 过度定义的相关属性
属性 | 描述 | 说明 |
---|---|---|
transition-property |
指定哪个或哪些 CSS 属性用于过渡 | 只有指定的属性才会在过渡中发生动画,其它属性仍如通常那样瞬间变化。 |
transition-duration |
指定过渡的时长 | 或者为所有属性指定一个值,或者指定多个值,为每个属性指定不同的时长。 |
transition-timing-function |
指定一个函数,定义属性值怎么变化 | 缓动函数 Timing functions 定义属性如何计算。多数 timing functions 由四点定义一个 bezier 曲线。也可以从 Easing Functions Cheat Sheet 选择缓动效果。 |
transition-delay |
指定延迟时间 | 延迟指的是属性开始变化时与过渡开始发生时之间的时长。 |
3.2.1 控制过度属性:transition-property属性
该属性用于指定应用过渡属性的名称,附录中包含了可被用于动画的属性。如果指定简写属性(比如 background),那么其完整版中所有可以动画的属性都会被应用过渡。
属性值
属性值 | 描述 |
---|---|
none |
没有过渡动画。 |
all |
所有可被动画的属性都表现出过渡动画。 |
IDENT |
属性名称。由小写字母 a 到 z,数字 0 到 9,下划线(_)和破折号(-)。第一个非破折号字符不能是数字。同时,不能以两个破折号开头。 |
例如:
/* Keyword values */transition-property: none;transition-property: all;transition-property: test_05;transition-property: -specific;transition-property: sliding-vertically;transition-property: test1;transition-property: test1, animation4;transition-property: all, height, all;transition-property: all, -moz-specific, sliding;/* Global values */transition-property: inherit;transition-property: initial;transition-property: unset;
3.2.2 控制过度快慢:transition-duration属性
transition-duration
属性以秒或毫秒为单位指定过渡动画所需的时间。默认值为 0s ,表示不出现过渡动画。
概述性的值为类型,例如:
/* 值 */transition-duration: 6s;transition-duration: 120ms;transition-duration: 1s, 15s;transition-duration: 10s, 30s, 230ms;/* 全局值 */transition-duration: inherit;transition-duration: initial;transition-duration: unset;
3.2.3 过渡计时函数属性:transition-timing-function
上文已经解释过,过度(transition) 其实是在两个状态之间产生一些列的中间值
。属性 transition-timing-function
用于指定所使用的 过度计时函数 ,这些函数用于描述这些 中间值 是如何计算得到的。
实质上,通过这个函数会建立一条 加速度曲线,因此在整个transition变化过程中,变化速度可以不断改变。这条加速度曲线被 所定义,之后作用到每个CSS属性的过渡
有以下过度计时函数:
过度计时函数 | 描述 | 备注 |
---|---|---|
linear |
线性缓动函数 | 见线性缓动函数部分 |
ease-in-out |
两头慢中间快 | 见三次贝塞尔缓动函数部分 |
ease |
开始稍慢中间加快,接近终值时又逐渐变慢 | 见三次贝塞尔缓动函数部分 |
ease-in |
开始快后来慢 | 见三次贝塞尔缓动函数部分 |
ease-out |
开始慢后来快 | 见三次贝塞尔缓动函数部分 |
cubic-bezire () |
自己来指定一个 三次贝塞尔缓动函数 。 这四个数字将曲线的点P1和P2指定为 ( x1 , y1 , x2 , y2 )。两个x值都必须在 [0, 1] 范围内,否则定义无效。 |
见三次贝塞尔缓动函数部分 |
step () |
包括 steps ([, ]?)、step-start 、step-end 三个函数 |
见步进函数部分 |
3.2.3.1 缓动过度
的概念
默认情况下,过度变化的速度并不是每一帧都相同,而是一开始的时候稍微慢一些,之后迅速加快,到接近最后的时候过度过程再次变慢。这个默认情况实际对应了transition-property
属性的值为ease
。
这种速度变化的过程称之为缓动,目的是让动画效果更加地自然流畅。
3.2.3.2 线性缓动函数
线性缓动函数是一个恒等函数,意味着它的输出进度值等于所有输入的输入进度值。线性缓动函数的语法就是linear
关键字,即:
transition-timing-function: linear;
也可以在transition
中指定transition-timing-function
值为linear
,例如:
transition: all .6s linear;
一个完整的例子如:
<html><head> <meta charset="utf-8"> </head><body> <div class="linear"></div></body><style> .linear{width:100px;height:100px;background:blue;transition: all .6s linear;}div:hover{width:200px;height:200px;}</style></html>
3.2.3.3 三次贝塞尔函数 和 弹性过度
1. 关于贝塞尔函数
贝塞尔函数是数学上的一类特殊函数的总称,是下列常微分方程(一般称为贝塞尔方程)的标准解函数 y ( x ) y(x) y(x):
x2 d 2yd x 2 + x d yd x + (x2 −α2 ) y = 0 x^2 \frac{d^2y}{dx^2} + x\frac{dy}{dx} + (x^2 - \alpha^2)y = 0 x2dx2d2y+xdxdy+(x2−α2)y=0
控制速度变化的数学函数在底层基于三次贝塞尔函数乘生成。通常这些函数都可以绘制成一条曲线,起点表示初始时间和初始值( P 0 P_0 P0)终点表示结束时间和结束值( P 1 P_1 P1)。
图: 三次贝塞尔函数 该图片来源于 MDN Docs
在上图中,三次贝塞尔曲线由四个点 P 0 P_0 P0、 P 1 P_1 P1、 P 2 P_2 P2 和 P 3 P_3 P3 定义。 P 0 P_0 P0 和 P 3 P_3 P3 是曲线的起点和终点,在 CSS 中这些点是固定的,因为坐标是比率(横坐标是时间的比率,纵坐标是输出范围的比率)。 P 0 P_0 P0是(0, 0)和表示初始时间或位置和初始状态, P 3 P_3 P3是(1, 1)和表示最后时间或位置和最终状态。
三次贝塞尔函数需要 4个参数 来计算随时间的变化,分别是两对 x x x坐标、两对 y y y坐标,他们扽别代表了控制曲线的两个 控制点。
由于这些曲线是连续的,它们通常用于平滑插值的开始和结束,因此有时称为缓动函数。
过度计时函数 | 描述 | 备注 |
---|---|---|
ease-in-out |
两头慢中间快 | 相当于 cubic-bezier(0.25, 0.1, 0.25, 1) |
ease |
开始稍慢中间加快,接近终值时又逐渐变慢 | 相当于cubic-bezier(0.42, 0, 1, 1) |
ease-in |
开始快后来慢 | 相当于 cubic-bezier(0, 0, 0.58, 1) |
ease-out |
开始慢后来快 | 相当于 cubic-bezier(0.42, 0, 0.58, 1) |
这四个关键自函数产生的缓动函数图形如下所示:
图: 各个三次贝塞尔缓动函数关键字值产生的缓动函数 来源: W3C编辑草案文档
2. CSS 中的cubic-bezier()
函数
三次贝塞尔函数需要 4个参数 来计算随时间的变化。 cubic-bezier()
函数符号定义三次贝塞尔曲线,它可以接受这些参数生成函数值作为缓动值。该函数的语法为:
cubic-bezier(x1, y1, x2, y2)
其中,x1, y1, x2, y2 的类型为,代表定义三次贝塞尔曲线的 P1 P_1 P1 和 P2 P_2 P2 点的横坐标和纵坐标的值。x1 和 x2 必须在 [0, 1] 范围内,否则该值无效。
3.2.3.4 步进的概念 与CSS 中的steps
函数
1 步进的概念
所谓步进指的是过度是分为若干个步骤的,可以指定过度中的每一个步骤的状态。CSS提供了步进函数steps()
,它非常适合用于创建 定格动画(stop-motion Animation)。
所谓 定格动画 是通过逐格地播放对象然后使之连续放映,从而产生仿佛活了一般的动画效果。
2 CSS 中的步进函数语法
CSS中一共有三个步进函数:
步进函数 | 描述 |
---|---|
steps ([, ]?) |
它由多个步骤和一个步骤位置定义,是将输入时间划分为指定数量的等长间隔的缓动函数。详见下文。 |
step-start |
计算得到 steps (1, start) |
step-end |
计算得到 steps (1, end) |
其中:
图: 步进缓动函数关键字值示例 来源: W3C编辑草案文档
由于 step-start函数 和 step-end函数 是 steps() 函数 的特殊情况,因此我们接下来仅仅介绍 函数 steps
([, ]?)。
🧾函数 steps
([, ]?)
steps()函数符号定义了一个阶梯函数,将输出值的域划分为等距阶梯。步进缓动函数是一种将输入时间划分为指定数量的等长间隔的缓动函数。它由多个步骤和一个步骤位置定义。它具有以下语法:
steps(number_of_steps, direction)
参数 | 描述 |
---|---|
number_of_steps |
是一个严格的正数 ,表示构成步进函数的等距踏板的数量。 |
direction |
是一个关键字,指示函数是左连续还是右连续 |
第一个参数指定函数中的间隔数。它必须是大于 0 的正整数,除非第二个参数是jump-none在这种情况下它必须是大于 1 的正整数。
第二个参数direction
参数默认为end
,可以为以下值:
值 | 描述 |
---|---|
jump-start |
表示左连续函数,因此第一步或跳跃发生在插值开始时; |
jump-end |
表示右连续函数,以便在插值结束时发生最后一步或跳转; |
jump-both |
表示左右连续函数,包括在0%和100%标记处的暂停,有效地在插值迭代期间增加了一个步长; |
jump-none |
两端都没有突变(跳跃)。相反,保持在0%标记和100%标记,每个标记持续1/n的时间; |
start |
等同于 jump-start |
end |
等同于 jump-end |
图: 示例步骤缓动函数 来源: W3C编辑草案文档
3.2.4 延时过度属性:transition-delay
transition-delay 用于指定延迟时间,即属性开始变化时与过渡开始发生时之间的时长。
例如:
/* ?值 */transition-delay: 3s;transition-delay: 2s, 4ms;/* 全局变量 */transition-delay: inherit;transition-delay: initial;transition-delay: unset;
4. CSS的关键帧动画
4.1 从 过度 到 关键帧
上文所介绍的 过度 实质上是基于两个状态的隐式动画。我们给浏览器的某个元素指定两个状态,然后浏览器通过计算将该元素从一个状态过度到另外一个状态。但是更多的情况下,动画可能并不仅仅只有两个状态,这时我们就需要使用关键帧(keyframes
)来实现可控制这些动画了。
4.2 定义和使用关键帧序列动画
keyframes 用于定义关键帧,其语法为:
@keyframes animationname { keyframes-selector {css-styles;}}
其中:
animationname
表示动画名,声明一个动画必须要有动画名之后才可以通过动画名来使用动画;- 如果多个关键帧使用同一个动画名,以最后一次定义的为准;
keyframes-selector
表示关键帧,用于描述中间状态的样式;keyframes-selector
可以为 百分数如10%
,也可以为from
(相当于0%
)to
(相当于100%
)、
例如:
@keyframes myanim{ 0% {top:0px;} 25% {top:0px; left:200px;} 75% {top:200px; left:200px;} 100% {top:200px; left:0px;}}
定义了一个名字为myanim
的关键帧动画。该动画定义后,就像 JavaScript 中定义函数后一样,可以在需要的地方多次调用。
属性 | 描述 | 备注 |
---|---|---|
animation-delay |
设置延时,即从元素加载完成之后到动画序列开始执行的这段时间。 | 实验中的功能 |
animation-direction |
设置动画在每次运行完后是反向运行还是重新回到开始位置重复运行。 | 实验中的功能 |
animation-duration |
设置动画一个周期的时长。 | 实验中的功能 |
animation-iteration-count |
设置动画重复次数, 可以指定infinite 无限次重复动画 |
实验中的功能 |
animation-name |
指定由@keyframes描述的关键帧名称。 | 使用简写属性animation可以很方便地同时设置所有的动画属性。 |
animation-play-state |
允许暂停和恢复动画。 | 实验中的功能 |
animation-timing-function |
设置动画速度, 即通过建立加速度曲线,设置动画在关键帧之间是如何变化。 | 若该关键帧没有定义缓动函数,则使用定义于整个动画的缓动函数。使用简写属性 animation 一次性设置所有动画属性通常很方便 |
animation-fill-mode |
指定动画执行前后如何为目标元素应用样式。 | 使用简写属性 animation 一次性设置所有动画属性通常很方便 |
4.3 曲线动画
两个点之间的动画往往都是沿着直线行走,那么如何沿着曲线行走呢?这里有两种思路。
第一种是学习 matlab 绘图种近似的思路,将曲线看作是多个点连成的多条线段的近似。这意味着着我们需要将动画分成更多的片段,也就是定义更多的关键帧。这样的曲线动画不仅麻烦,而且效果上也没有那么 “丝滑”。
例如:
<body> <div class="changed"></div></body><style> .changed { margin:200px; width: 160px; height: 160px; background-color: skyblue; animation: jump 2s ease-in-out infinite;}@keyframes jump{ from{ transform: rotate(0) translateX(-170px) rotate(0) scale(1); } to{ transform: rotate(175deg) translateX(-170px) rotate(-175deg) scale(.5); }}</style>
其效果如下:
5. 进阶 - 三维变换
5.1 透视的概念
5.2 创建三维部件
5.3 三维变换
附录
CSS可动画属性
一些CSS属性可以是动画的,也就是说,当它的值改变时,或者当 CSS动画或 CSS转换使用时,它可以以平滑的方式改变。
以下属性为可动画属性:
属性名 |
---|
-moz-outline-radius |
-moz-outline-radius-bottomleft |
-moz-outline-radius-bottomright |
-moz-outline-radius-topleft |
-moz-outline-radius-topright |
-ms-grid-columns (en-US) |
-ms-grid-rows (en-US) |
-webkit-line-clamp |
-webkit-text-fill-color (en-US) |
-webkit-text-stroke |
-webkit-text-stroke-color (en-US) |
accent-color (en-US) |
all |
backdrop-filter |
background |
background-color |
background-position |
background-size |
block-size |
border |
border-block-end |
border-block-end-color (en-US) |
border-block-end-width (en-US) |
border-block-start (en-US) |
border-block-start-color (en-US) |
border-block-start-width (en-US) |
border-bottom |
border-bottom-color |
border-bottom-left-radius |
border-bottom-right-radius |
border-bottom-width |
border-color |
border-end-end-radius (en-US) |
border-end-start-radius (en-US) |
border-image-outset |
border-image-slice |
border-image-width |
border-inline-end (en-US) |
border-inline-end-color (en-US) |
border-inline-end-width (en-US) |
border-inline-start (en-US) |
border-inline-start-color (en-US) |
border-inline-start-width (en-US) |
border-left |
border-left-color |
border-left-width |
border-radius |
border-right |
border-right-color |
border-right-width |
border-start-end-radius (en-US) |
border-start-start-radius (en-US) |
border-top |
border-top-color |
border-top-left-radius |
border-top-right-radius |
border-top-width |
border-width |
bottom |
box-shadow |
caret-color |
clip |
clip-path |
color |
column-count |
column-gap |
column-rule |
column-rule-color |
column-rule-width |
column-width (en-US) |
columns |
filter |
flex |
flex-basis |
flex-grow |
flex-shrink |
font |
font-size |
font-size-adjust |
font-stretch |
font-variation-settings |
font-weight |
gap |
grid-column-gap (en-US) |
grid-gap (en-US) |
grid-row-gap (en-US) |
grid-template-columns |
grid-template-rows |
height |
inline-size |
input-security |
inset (en-US) |
inset-block (en-US) |
inset-block-end (en-US) |
inset-block-start (en-US) |
inset-inline (en-US) |
inset-inline-end (en-US) |
inset-inline-start (en-US) |
left |
letter-spacing |
line-clamp |
line-height |
margin |
margin-block-end (en-US) |
margin-block-start |
margin-bottom |
margin-inline-end (en-US) |
margin-inline-start (en-US) |
margin-left |
margin-right |
margin-top |
mask |
mask-border |
mask-position (en-US) |
mask-size (en-US) |
max-block-size (en-US) |
max-height |
max-inline-size (en-US) |
max-lines |
max-width |
min-block-size (en-US) |
min-height |
min-inline-size (en-US) |
min-width |
object-position |
offset |
offset-anchor (en-US) |
offset-distance (en-US) |
offset-path (en-US) |
offset-position (en-US) |
offset-rotate (en-US) |
opacity |
order |
outline |
outline-color |
outline-offset |
outline-width |
padding |
padding-block-end (en-US) |
padding-block-start (en-US) |
padding-bottom |
padding-inline-end (en-US) |
padding-inline-start |
padding-left |
padding-right |
padding-top |
perspective |
perspective-origin |
right |
rotate |
row-gap |
scale |
scroll-margin |
scroll-margin-block (en-US) |
scroll-margin-block-end (en-US) |
scroll-margin-block-start (en-US) |
scroll-margin-bottom (en-US) |
scroll-margin-inline (en-US) |
scroll-margin-inline-end (en-US) |
scroll-margin-inline-start (en-US) |
scroll-margin-left (en-US) |
scroll-margin-right (en-US) |
scroll-margin-top |
scroll-padding (en-US) |
scroll-padding-block (en-US) |
scroll-padding-block-end (en-US) |
scroll-padding-block-start (en-US) |
scroll-padding-bottom (en-US) |
scroll-padding-inline (en-US) |
scroll-padding-inline-end (en-US) |
scroll-padding-inline-start (en-US) |
scroll-padding-left (en-US) |
scroll-padding-right (en-US) |
scroll-padding-top (en-US) |
scroll-snap-coordinate |
scroll-snap-destination |
scrollbar-color |
shape-image-threshold |
shape-margin |
shape-outside |
tab-size |
text-decoration |
text-decoration-color |
text-decoration-thickness |
text-emphasis (en-US) |
text-emphasis-color (en-US) |
text-indent |
text-shadow |
text-underline-offset (en-US) |
top |
transform |
transform-origin |
translate |
vertical-align |
visibility |
width |
word-spacing |
z-index |
zoom (en- |