【青训营】- 前端动画实现笔记

576 阅读5分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

动画的基本原理

什么是动画

在维基百科上,对于 动画Animation)的定义是指多个连续的图像以一定频率连续变化、运动(播放)的速度(如每秒16张)而导致肉眼的视觉残象产生的错觉——而误以为图画或物体(画面)的作品及其视频技术。

计算机动画原理

计算机动画

计算机动画是指利用计算机图形学,通过计算机硬件和软件生成连续的图像,主要包含2D、3D动画。当图片切换的速度达到一定程度时,也就是达到一定帧率时,就可以利用人眼和大脑的视觉暂留效果,使得动画看起来不那么“卡”。

帧:连续变换的多张画面中每一张静态图片就是一帧。

帧率:画面每秒刷新的次数,单位HZ或者FPS(Frames Per Second)。

就像是小时候看的厚厚的翻页动画书,手速多快,帧率就有多快。在Chrome浏览器上我们可以通过Performance 查看网页的帧率。现在主流的显示屏输出帧率为60HZ,一般情况下帧数越高看起来越流畅。

补间动画和逐帧动画

逐帧动画从词语来说意味着全片每一帧都是纯手绘,比如翻页动画书。

补间动画我们只需要准备好关键帧,中间的转变过程由计算机自动生成,如图所示,我们只需要确认开始状态和结束状态,就可以由计算机完成中间的多个差值状态。

image.png

前端动画分类

前端动画主要可以由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-propertytransition-durationtransition-timing-functiontransition-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.svganime.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;

chrome-capture.gif

结语

好了今天的笔记就到这里啦,关于CSS为什么比JS更快,怎么样可以优化动画效果,每一个细节都可以单来出来研究 ,页面每快一点点,都可以带来更好的体验,深入研究一下再更新一波。非常感谢您的阅读!33ZP(L0_BU5T9%IEMWO_`OE.png