GIF全称为“Graphics Interchange Format”,是一种基于LZW算法的连续色调无损压缩格式。
由于其文件小、无损压缩、易于播放等优点,GIF成为了网页动画的最初选择。然而,GIF动画的色彩数量和帧数有限,而且不能包含声音,因此其表现力相对有限。
Flash动画是一种使用Macromedia公司开发的Flash软件创建的动画。它具有以下特点:
然而,随着移动设备的普及和HTML5技术的兴起,Flash逐渐被淘汰。
随着JavaScript库如jQuery的出现,开发者开始使用JavaScript来创建更丰富的交互式动画。这些库简化了DOM操作和动画效果的实现。
HTML5引入了<canvas>
和<svg>
元素,提供了原生绘图功能。CSS3开始,引入了更多的动画和过渡效果。
通过使用CSS3的动画关键帧(@keyframes)、过渡(transition)等特性,可以轻松地创建各种复杂的动画效果。
同时,CSS3动画也具有更好的兼容性和性能。
WebGL是一种基于OpenGL ES 2.0的图形渲染协议,可以在不需要任何插件的情况下在浏览器中进行3D图形渲染。通过WebGL,开发者可以创建更复杂的3D动画和交互式体验。
随着前端框架的发展,例如React和Vue,也提供了专门的动画库(如React Spring、Vue.js的过渡效果),简化了在组件级别实现动画的过程。
Web动画API是一组用于控制动画序列的JavaScript接口。例如Animation
、AnimationTimeline
等;它允许开发者使用JavaScript直接控制CSS动画和SVG动画。
动画属性用于决定动画的播放时长、播放次数以及播放速度等。
animation: duration | easing-function | delay | iteration-count
| direction | fill-mode | play-state | name
// 实例:
animation: 3s ease-in 1s infinite reverse both running animateName;
CSS animation 属性是一个简写属性,用于设置六个动画属性:
旋转元素
动态更改元素大小及透明度
可访问代码地址查看源码实现
关键帧用于定义动画在不同阶段的状态,可以通过百分比或关键词(例如“from”和“to”)来定义动画的起始和结束状态。
使用from(0%) 和to(100%),指定动画的开始或结束状态。
@keyframes animation-name {
from {
transform: translateX(0%);
}
to {
transform: translateX(100%);
}
}
使用百分比,指定动画在不同阶段需要触发的样式。
@keyframes animation-name {
0% {
top: 0;
left: 0;
}
30% {
top: 50px;
}
68%,
72% {
left: 50px;
}
100% {
top: 100px;
left: 100%;
}
}
使用from,to定义单词“Hello”从左向右移动;使用百分比使单词"World"从右向左移动。
CSS transform
属性允许旋转,缩放,倾斜或平移给定元素。这是通过修改 CSS 视觉格式化模型的坐标空间来实现的。
transform: none | transform-function | initial | inherit;
none
表示没有任何转换效果。transform-functions
表示一个或多个转换函数,如translate()
, rotate()
, scale()
等。initial
表示将属性设置为初始值。inherit
表示从父元素继承该属性。<transform-function>
属性用于对元素进行转换操作,它提供了多种转换方式,包括旋转(rotate)、缩放(scale)、移动(translate)、倾斜(skew)和矩阵变换(matrix)等。这些转换操作可以单独使用,也可以组合在一起使用,以实现更复杂的变换效果。
使用
rotate()
函数是一种将元素围绕一个定点旋转而不变形的转换。旋转角度可以是正值(顺时针旋转)或负值(逆时针旋转)。其中,转换定点由transform-origin
属性指定,默认值是center
。
// 将元素顺时针旋转45度
transform: rotate(45deg);
使用
scale()
函数可以按指定的倍率缩放元素。当只有一个参数时,表示水平和垂直方向同时缩放该倍率;当有两个参数时,第一个参数指定水平方向的缩放倍率,第二个参数指定垂直方向的缩放倍率。
// 将元素水平方向和垂直方向同时缩小到原来的一半
transform: scale(0.5);
二维平移: 使用
translate()
函数可以将元素在X轴和Y轴方向上平移指定的距离。可以使用translateX()
函数仅在X轴方向上平移元素,使用translateY()
函数仅在Y轴方向上平移元素。三维平移:如果设置三个长度值或百分比,表示分别指定 X 轴、Y 轴、Z 轴的值进行三维平移。等同于
translate3d()
函数(3D 平移)。
// 将元素在X轴方向上平移100像素,在Y轴方向上平移50像素。
transform: translate(100px, 50px);
// 将元素在X轴方向上平移100像素,在Y轴方向上平移50像素,在Z轴方向上平移20像素。
transform: translate(100px, 50px, 20px);
translate
也支持独立于 transform
属性,单独声明平移变换。
translate: 50% 105px 5rem;
使用
skew()
函数可以将元素在水平方向和垂直方向上倾斜指定的角度。当只有一个参数时,表示水平方向的倾斜角度;当有两个参数时,第一个参数表示水平方向的倾斜角度,第二个参数表示垂直方向的倾斜角度。
// 将元素在水平方向上倾斜30度
transform: skew(30deg);
CSS的
matrix
属性是用于实现2D变换效果的函数,它基于数学中的矩阵概念。通过矩阵的乘法运算,可以将多个变换效果组合在一起,实现复杂的变换效果。
语法
matrix(a, b, c, d, tx, ty);
matrix( scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY() )
其中,a
和d
控制元素在水平方向和垂直方向上的缩放,b
和c
控制元素在水平和垂直方向上的倾斜,tx
和ty
控制元素在水平和垂直方向上的平移。
矩阵的六个参数对应于一个2x3的矩阵。这六个参数给定特定的值,可以实现特殊的变换效果。
实现平移效果,修改参数
tx
和ty
;实现缩放效果,修改参数
a
和d
;实现旋转效果,修改参数
a
,b
,c
, 和d
。
例如,要实现一个元素的平移效果,可以将矩阵设置为:
transform: matrix(1, 0, 0, 1, 100px, 50px);
这个例子将元素在X轴方向上平移100像素,在Y轴方向上平移50像素。
需要注意的是,CSS中的矩阵变换是基于2D变换的,不包含3D变换效果。对于更复杂的3D变换效果,可能需要使用其他的转换函数,如rotateX、rotateY、rotateZ等。
旋转+缩放动画
多种组合变换
在这个示例中:
translate(x, y)
用于在X轴和Y轴上移动对象。rotate(angle)
用于按指定角度旋转对象。scale(x, y)
用于在X轴和Y轴上缩放对象。skew(x-angle, y-angle)
用于在X轴和Y轴上倾斜对象。matrix(a, b, c, d, e, f)
是一个综合性的函数,允许组合多个变换。可访问代码地址查看源码实现
CSS 过渡可以决定哪些属性发生动画效果(通过明确地列出这些属性),何时开始(通过设置延时),持续多久(通过设置时长)以及如何动画(通过定义缓动函数,比如线性或先快后慢)。
transition: property | duration
| timing-function | delay;
transition属性是一个简写属性,用于设置四个过渡相关的子属性:
这些子属性也可以单独设置:
transition-property: width;
transition-duration: 2s;
transition-timing-function: ease-in-out;
transition-delay: 1s;
鼠标悬浮,修改卡片的缩放、背景颜色和阴影
可访问代码地址查看源码实现
CSS原生动画的性能瓶颈主要来自于两个方面:计算复杂度和渲染性能。
计算复杂度指浏览器在处理动画效果时所需的计算量。这主要涉及到样式的计算、布局(Layout)和绘制(Paint)操作。如果动画涉及复杂的样式计算或引发频繁的布局和绘制,可能会导致性能瓶颈。以下是一些具体的例子:
// 复杂样式计算
.element {
width: calc(50% + 100px);
height: calc(30vh - 20px);
background-color: hsl(120, 70%, 80%);
}
// 在动画中频繁获取布局属性
const elementWidth = element.offsetWidth;
// 复杂的选择器可能需要更多的计算资源来匹配元素
.container > div:not(:last-child):hover {
transform: scale(1.2);
}
渲染性能涉及浏览器如何绘制动画帧以及如何在屏幕上显示它们。这包括合成图层的创建、纹理的合成和屏幕的刷新。过于复杂或频繁的渲染操作可能导致动画不流畅,尤其是在性能较低的设备上。
// 鼠标悬停时会导致频繁的重绘和回流
.element {
left: 10px;
top: 10px;
transition: left 1s, top 1s;
}
.element:hover {
left: 100px;
top: 100px;
}
// 在某些情况下,为多个元素应用硬件加速可能会导致更多的复合层,增加渲染工作量。
.element1, .element2, .element3 {
transform: translateZ(0);
}
// 过于频繁的透明度变化可能导致浏览器强制进行重绘
.element {
transition: opacity 0.5s;
}
.element:hover {
opacity: 0.5;
}
此外,还有一些其他因素也会影响CSS原生动画的性能,例如浏览器对CSS动画的支持程度、硬件性能等。例如,一些老旧的浏览器可能不支持某些CSS动画特性,或者在某些设备上,GPU性能不足也会影响动画的性能。
通过开启硬件加速,将计算密集型的任务交给GPU处理,可以大大提高动画的性能。
在CSS中,可以使用transform
属性或opacity
等属性来开启硬件加速。
在个别复杂的计算场景下,也可以使用will-change
属性。该属性提供了一种告知浏览器该元素会有哪些变化的方法,这样浏览器可以在元素属性真正发生变化之前提前做好对应的优化准备工作。具体需要结合业务场景综合考量并使用。
requestAnimationFrame是一个高性能的API,它可以根据屏幕的刷新率来同步动画的帧率,从而保证动画的流畅度。应尽量使用requestAnimationFrame来控制动画的播放和暂停。
重绘和重排是导致动画卡顿的主要原因之一。可以通过减少不必要的样式计算和布局更新来减少重排和重绘。例如,避免在动画过程中频繁改变元素的布局或大小,尽可能使用transform属性代替top、left等属性,因为transform属性的改变不会触发重排。
box-shadow和gradients会消耗大量的GPU资源,特别是在移动设备上。如果可以,尽量避免在动画元素上使用它们,或者尽量减少它们的数量和复杂性。
复杂的CSS选择器会导致浏览器进行大量的样式计算,从而影响动画性能。应尽量避免使用过于复杂的选择器,或者尽量减少它们的数量和使用频率。
对于关键帧动画,可以通过合理地拆分和组织关键帧来减少动画的复杂度,从而提高性能。例如,将多个动画拆分成多个独立的动画,或者将一些不重要的动画移到非关键帧中。
随着前端开发的发展,出现了一系列独立的CSS动画库,这些库旨在提供更丰富的特性、更简洁的API、更好的性能和更好的开发体验。
原生CSS动画和CSS动画库各有适用场景,选择哪种主要取决于项目的具体需求。