这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战
动画的基本原理
什么是动画
在维基百科上,对于
动画(Animation)的定义是指多个连续的图像以一定频率连续变化、运动(播放)的速度(如每秒16张)而导致肉眼的视觉残象产生的错觉——而误以为图画或物体(画面)的作品及其视频技术。
计算机动画原理
计算机动画
计算机动画是指利用计算机图形学,通过计算机硬件和软件生成连续的图像,主要包含2D、3D动画。当图片切换的速度达到一定程度时,也就是达到一定帧率时,就可以利用人眼和大脑的视觉暂留效果,使得动画看起来不那么“卡”。
帧
帧:连续变换的多张画面中每一张静态图片就是一帧。
帧率:画面每秒刷新的次数,单位HZ或者FPS(Frames Per Second)。
就像是小时候看的厚厚的翻页动画书,手速多快,帧率就有多快。在Chrome浏览器上我们可以通过Performance 查看网页的帧率。现在主流的显示屏输出帧率为60HZ,一般情况下帧数越高看起来越流畅。
补间动画和逐帧动画
逐帧动画从词语来说意味着全片每一帧都是纯手绘,比如翻页动画书。
补间动画我们只需要准备好关键帧,中间的转变过程由计算机自动生成,如图所示,我们只需要确认开始状态和结束状态,就可以由计算机完成中间的多个差值状态。
前端动画分类
前端动画主要可以由CSS动画、SVG动画和JS动画实现。
CSS动画
CSS有多种实现动画的方式。
Transform
Transform属性应用于元素的2D或3D转换,比较常用的操作有旋转,缩放,移动,倾斜变换,代码如下:
transform:rotate(7deg); //旋转
transform:scale(0.5); //缩放
transform:translate(200px); //移动
transform:skew(7deg); //倾斜
Transition
transition CSS 属性是 transition-property,transition-duration,transition-timing-function 和 transition-delay 的一个简写属性。
它可以让元素变换过程添加一个过渡的效果。
transition-property指定哪些CSS属性用于过渡。
transition-duration指定过渡的时长。
transition-timing-function指定一个函数,定义属性值怎么变化。
transition-delay指定延迟,即开始变化时与过渡开始发生时之间的时长。
keyframes
关键帧动画和Transition相比,可以定义关键帧的样式来控制动画的中间步骤。
@keyframes myfirst
{
0% {background:red;}
25% {background:yellow;}
50% {background:blue;}
100% {background:green;}
}
SVG动画
基于XML的矢量图形描述语言,和html比较像,可以与CSS和JS配合,实现SVG动画通常有三种方式:SMIL/JS/CSS。
SMIL: 同步多媒体集成语言,由于兼容性不好,不太推荐。
JS:使用JS操作SVG动画已经有很多现成的类库,比如Snap.svg和 anime.js,HTML本身也有原生的web animation实现。
CSS:这里主要是使用animation,transition,transform来实现动画,他比JS更加简洁方便。
JS动画
JS可以实现复杂的动画,它可以更精细地去控制动画图像的中间状态,也可以操作canvas动画API上进行绘制。
如何做选择?
CSS优点: 浏览器会对CSS3动画做一些优化,导致动画性能上稍有优势。为了提升每帧的渲染效率,Chrome 引入了分层和合成的机制。浏览器对有些CSS3特性会新建一个图层专门去跑渲染,所以相较于JS性能会更好,当然相反地,需要牺牲一些内存。其中,以下几个属性可以触发GPU加速:
transform
opacity
filter
will-change
CSS缺点:动画控制上不够灵活。兼容性不佳。部分动画无法实现。
JS优点:使用灵活,在定义一个动画的keyframe序列时,可以根据不同的条件调节参数。JS的颗粒度更粗,可以弥补CSS本身时间函数的有限性。
JS缺点:使用JS运行时,调优方面不如CSS简单,CSS调优方式固定。对于性能较差的浏览器,CSS可以做到优雅降级。而JS还需要额外兼容。
因此
- 当UI元素采用较小的独立状态时,使用CSS。
- 在需要对动画进行大量控制时,使用JavaScript。
- 特定场景下可以使用SVG,可以使用css和JS去操作SVG变化。
实践
在这里我使用transform和transition来模仿B站夏季头部的动画效果,通过监听鼠标移动,根据鼠标位置变化实时调整translatex来修改背景图片的位置,当鼠标移出图片时,触发transition动画,在0.5秒内缓缓回归原来的位置。
此外,在鼠标放在图层上时设置transition = 'none',就可以中断transition属性对JS操作的影响。
videoLayer.addEventListener('mousemove', (e) => {
let movePercent = (e.clientX - StartPosition) / window.outerWidth // 鼠标位移量
offset = movePercent * 20 + 0
videoLayer.style.setProperty('--offset', `${offset}px`)
})
videoLayer.addEventListener('mouseleave', () => {
videoLayer.style.transition = '.5s all'
videoLayer.style.setProperty('--offset', `0px`)
})
position: absolute;
margin: auto;
height: 100%;
width: 110%;
object-fit: cover;
transform: translatex(var(--offset));
transition: 0.5s all;
结语
好了今天的笔记就到这里啦,关于CSS为什么比JS更快,怎么样可以优化动画效果,每一个细节都可以单来出来研究
,页面每快一点点,都可以带来更好的体验,深入研究一下再更新一波。非常感谢您的阅读!