前端旧约

今天做别人不愿意做的事, 明天做别人不能做的事

CSS 动画一站式指南

CSS 动画一站式指南

1. CSS 动画

在 CSS3 出现之前,简单的交互都需要使用 JS 才能完成,如今 CSS3 增加了 transformtransitionanimation 三大交互属性,为 CSS 的单调性增加了很多趣味,CSS 也可以实现比较复杂的动画了。

1.1 变换

变换对应的 CSS 属性为 transform ,变换可分为 2D 变换和 3D 变换,可以由 transform-style 来指定。 transform-style 需要声明在父节点中,即需要发生变化的节点的父节点。

  • flat:2D 变换(所有变换效果在平面上呈现)

  • preserve-3d:3D 变换(所有变换效果在空间上呈现)

不同的变换对应不同的变换函数,在不同的变换空间使用对应的变换函数即可,接下来简单介绍一下这些变换函数。

1.1.1 变换属性介绍

1)translate 位移

  • translate(x,y):2D位移

  • translate3d(x,y,z):3D位移

  • translateX(x):X轴位移,等同于 translate(x,0)translate3d(x,0,0)

  • translateY(y):Y轴位移,等同于 translate(0,y)translate3d(0,y,0)

  • translateZ(z):Z轴位移,等同于 translate3d(0,0,z)

  • 描述

    • 单位: Length 长度,可用任何长度单位,允许负值
    • 默认:XYZ轴不声明默认是 0
    • 正值:沿X轴向右位移/沿Y轴向上位移/沿Z轴向外位移
    • 负值:沿X轴向左位移/沿Y轴向下位移/沿Z轴向内位移

2)scale 缩放

  • scale(x,y):2D缩放

  • scale3d(x,y,z):3D缩放

  • scaleX(x):X轴缩放,等同于 scale(x,1)scale3d(x,1,1)

  • scaleY(y):Y轴缩放,等同于 scale(1,y)scale3d(1,y,1)

  • scaleZ(z):Z轴缩放,等同于 scale3d(1,1,z)

  • 描述

    • 单位: Number 数值或 Percentage 百分比,允许负值
    • 默认:XYZ轴不声明默认是 1100%
    • 正值: 0<(x,y,z)<1 沿X轴缩小/沿Y轴缩小/沿Z轴变厚, (x,y,z)>1 沿X轴放大/沿Y轴放大/沿Z轴变薄
    • 负值: 1<(x,y,z)<0 翻转沿X轴缩小/沿Y轴缩小/沿Z轴变厚, (x,y,z)<-1 翻转沿X轴放大/沿Y轴放大/沿Z轴变薄

3)skew 扭曲

  • skew(x,y):2D扭曲

  • skewX(x):X轴扭曲,等同于 skew(x,0)

  • skewY(y):Y轴扭曲,等同于 skew(0,y)

  • 描述

    • 单位: Angle 角度或 Turn
    • 默认:XY轴不声明默认是 0
    • 正值:沿X轴向左扭曲/沿Y轴向下扭曲
    • 负值:沿X轴向右扭曲/沿Y轴向上扭曲

4)rotate 旋转

  • rotate():2D旋转

  • rotate3d(x,y,z,a):3D旋转, [x,y,z] 是一个向量,数值都是 0~1

  • rotateX(a):X轴旋转,等同于 rotate(1,0,0,a) ,正值时沿X轴向上逆时针旋转,负值时沿X轴向下顺时针旋转

  • rotateY(a):3D Y轴旋转,等同于 rotate(0,1,0,a) ,正值时沿Y轴向右逆时针旋转,负值时沿Y轴向左顺时针旋转

  • rotateZ(a):3D Z轴旋转,等同于 rotate(0,0,1,a) ,正值时沿Z轴顺时针旋转,负值时沿Z轴逆时针旋转

  • 描述

    • 单位: Angle 角度或 Turn
    • 正值:2D旋转时顺时针旋转
    • 负值:2D旋转时逆时针旋转

5)视距效果 perspective

transform: perspective() 可以声明视距效果,除此之外还有一个 perspective 属性也可以用来声明视距效果。

perspectivetransform:perspective() 都能声明视距,那为何要存在两种声明方式呢?

  • perspectivetransform:perspective() 的作用相同

  • perspective舞台节点 (变换节点的父节点)上使用, transform:perspective()当前变换节点 上使用,也可与其他变换函数一起使用

视距效果在 3D 动画中记得要声明,否则有些 3D 变换效果可能无法得到更好的展现。

  • 值越小,用户与空间Z轴距离越近,视觉效果越强

  • 值越大,用户与空间Z轴距离越远,视觉效果越弱

1.1.2 变换动画实践

1)❤️

通过纯 CSS 也可以实现一个心形 ❤️。

undefined

使用单个 div 元素结合 ::before::after 两个伪元素通过错位叠加的方式就可以轻松实现,搞起来。

步骤:

  • 声明 <div> 的尺寸为一个 正方形 并以中心顺时针旋转 45deg

  • 声明两个伪元素继承 <div> 的尺寸并实行绝对定位

  • 声明两个伪元素的圆角率为 100% 并平移到相应位置

在线源码和演示

2)0.5px 边框

在移动端由于屏幕的分辨率较高,因此 1px 边框看起来会有点粗,那么可以直接声明 0.5px 的边框吗?可以,但是即便声明成功了,有些浏览器还是会按照 1px 来渲染。为了实现 0.5px 的边框,我们可以利用 CSS 中的 transform 来实现。

undefined

步骤:

  • 声明一个伪元素,令其宽高为 200%,border 宽度为 1px

  • 通过 transform: scale(.5) 将该伪元素缩小为原来的 0.5 倍。

在线源码和演示

1.2 过渡

过渡的出现让状态间的切换更加丝滑,先简单介绍一下与过渡相关的属性,相关的动画实践稍候奉上。

1.2.1 过渡属性介绍

1)transition-property:属性

  • all :全部属性过渡( 默认 )

  • none :无属性过渡

  • String :某个属性过渡

2)transition-duration:时间

  • Time :秒或毫秒(默认 0 )

3)transition-timing-function:缓动函数

  • ease :逐渐变慢,等同于 cubic-bezier(.25,.1,.25,1) ( 默认 )

  • linear :匀速,等同于 cubic-bezier(0,0,1,1)

  • ease-in :加速,等同于 cubic-bezier(.42,0,1,1)

  • ease-out :减速,等同于 cubic-bezier(0,0,.58,1)

  • ease-in-out :先加速后减速,等同于 cubic-bezier(.42,0,.58,1)

  • cubic-bezier :贝塞尔曲线, (x1,y1,x2,y2) 四个值指定于曲线上的点 P1P2 ,所有值需在 [0,1] 区域内

4)transition-delay:时延

  • Time :秒或毫秒(默认 0 )

由于 durationdelay 的取值都是时间,所以可能会发生混淆。

  • durationdelay 作用于所有节点,包括自身的 ::before::after

  • transition 中出现两个时间值时,第一个解析为 duration ,第二个解析为 delay

  • transition 中出现一个时间值时,解析为 duration

变换属性中一个比较重要的属性是 transition-timing-function ,它决定了过渡时间内速度是如何变化的。它的值实际上是一个贝塞尔曲线,推荐一个设置贝塞尔曲线的网站,可以根据需要设计出符合需求的贝塞尔曲线。

1.2.2 过渡动画实践

1)IOS 设置页面中的开关按钮

下面这个开关在 IOS 手机的设置面板中太常见了,开关的动画效果利用 transition 这个属性也可以很轻松地实现,而且这里利用上面讲到的设置贝塞尔曲线的网站调试出了一种贝塞尔曲线使得开关按钮被打开的过程有一个刹车的效果。

undefined

在线源码和演示

1.3 动画

CSS 可以通过设置多个点精确地控制一个或一组动画,用来实现复杂的动画效果。动画由多个点组成,每个点拥有独立的状态,这些状态通过浏览器处理成过渡效果,点与点之间的过渡效果串联起来就是一个完整的动画。

1.3.1 Animation 属性介绍

1)animation-name:名称

  • none :无动画( 默认 )

  • String :动画名称

2)animation-duration:时间

  • Time :秒或毫秒(默认 0 )

3)animation-timing-function:缓动函数

  • ease :逐渐变慢,等同于 cubic-bezier(.25,.1,.25,1) ( 默认 )

  • linear :匀速,等同于 cubic-bezier(0,0,1,1)

  • ease-in :加速,等同于 cubic-bezier(.42,0,1,1)

  • ease-out :减速,等同于 cubic-bezier(0,0,.58,1)

  • ease-in-out :先加速后减速,等同于 cubic-bezier(.42,0,.58,1)

  • cubic-bezier :贝塞尔曲线, (x1,y1,x2,y2) 四个值指定于曲线上的点 P1P2 ,所有值需在 [0,1] 区域内

  • steps([,[start|end]]?) :把动画平均划分成 n等分 ,直到平均走完该动画

  • step-start :等同于 steps(1,start) ,把动画分成一步,动画执行时以左侧端点 0% 为开始

  • step-end :等同于 steps(1,end) ,把动画分成一步,动画执行时以右侧端点 100% 为开始

4)animation-delay:时延

  • Time :秒或毫秒(默认 0 )

5)animation-iteration-count:播放次数

  • Number :数值(默认 1 )

  • infinite :无限次

6)animation-direction:轮流反向播放(播放次数为一次则该属性无效果)

  • normal :正常播放( 默认 )

  • alternate :轮流反向播放,奇数次数正常播放,偶数次数反向播放

7)animation-play-state:播放状态

  • running :正在播放( 默认 )

  • paused :暂停播放

8)animation-fill-mode:播放前后其效果是否可见

  • none :不改变默认行为( 默认 )

  • backwards :在时延所指定时间内或在动画开始前应用开始属性( 在第一个关键帧中定义 )

  • forwards :在动画结束后保持最后一个属性( 在最后一个关键帧中定义 )

  • both :向前和向后填充模式都被应用

CSS 中动画分为两种,关键帧动画和逐帧动画。关键帧动画是将人为定义好的每一帧的状态串联成一个动画,需要通过 animation@keyframes 声明。逐帧动画的声明较为简单,使用一张逐帧长图然后配合 animation-timing-function: steps() 来完成。

逐帧动画的声明步骤一般如下:

  • 准备一张 逐帧长图 ,该图像包含动画效果的每一帧且每帧宽高必须一致

  • steps() 里声明逐帧长图及其展示方式

  • 在指定节点中声明 animation 调用动画

关键帧动画的声明步骤一般如下:

  • @keyframes 里声明动画名称和动画每个关键帧的状态

  • 在指定节点中声明 animation 调用动画

关键帧动画声明示例:

@keyframes animation-name {
    from {}
    to {}
}

/* 或 */
@keyframes animation-name {
    p1 {}
    p2 {}
    p3 {}
}

关键帧的取值必须是 fromtoPercentagefrom 可用 0% 代替, to 可用 100% 代替,若开始或结束的关键帧无对应的状态,可不用声明 fromto0%% 不能省略,否则关键帧解析会失败。通过 animation-fill-mode 属性设置动画结束后的样式。

1.3.2 Animation 动画实践

1)自动打字器

很多在线编辑器网站都有一些自动打字的效果,例如CodePen。很多同学都以为是JS实现的效果,其实查看 Chrome Devtools 发现是纯CSS实现的。观察多几次自动打字器,可发现其存在以下特点。

  • 字体都是等宽字体,等宽字体可保证每次打字时光标的移动距离都是一致的

  • 打字器的宽度由最初的 0px 逐渐增加内容后变成最终固定字数的宽度,宽度以等宽字体的个数为准

  • 光标随着每打一个字就闪烁一次,打字速度均匀,打字完毕再次重复打字

  • 整个打字过程存在两个动画,一个是打字器自增宽度,一个是光标闪烁

  • 整个打字过程一闪一闪地完成,根据其断断续续的特点可判断该动画为逐帧动画

这里用 CSS 简单实现了一个自动打字器,在线源码和演示

2. CSS 动画综合实践(太空舱)

2.1 太空舱动画介绍

先简单介绍一下这个动画的一些背景:

  • 用户点击中间的抽奖按钮后会展示抽奖动画,然后展示将要前进的步数,小人会在跑道上跑动到相应的位置,到达此次终点后,小人展示停止动画并且显示中奖结果。

  • 用户还可以通过长按中奖按钮触发显示五连抽和十连抽,当点击五连抽时,首先会展示抽奖动画,然后展示将要前进的步数,小人会在跑道上瞬间移动到相应的位置,然后展示停止的动画,紧接着展示中奖动画。十连抽的过程和五连抽相同。

2.2 太空舱动画实现流程

整体流程

大体思路是将各个功能封装为类,并且控制每个类实现的功能较小,这样可以更大程度地实现类的复用。像下面介绍的 Animate CSS 这个动画库也是封装了很多类,想要什么效果直接引用即可,这里也是同理。并在此基础上定义了一些函数对跑动等功能进行了封装,整体流程如下图所示。

undefined

结合上图对太空舱动画中的一些点做一些简单的说明。

跑动的实现

通过关键帧动画,将各个方向相邻两格之间的跑动封装为一个类。每一帧代表跑动的姿态,并且每一帧通过 translate 向前进的方向移动,最后一帧刚好到达下一格。

以向南方向的跑动为例。

  • 向南奔跑的类

@translateSouthX@translateSouthY 代表向南每两格 X 和 Y 方向的距离, .run-south-animation 是一个 mixin ,代表向南跑动的动画。

@import "./animation.less";

@translateSouthX: -25px;
@translateSouthY: 13.5px;

// 向南方向跑动
.run-south {
  background: url("...");
  background-size: 1680px 255px;
  .run-south-animation(@translateSouthX, @translateSouthY);
}
  • 向南奔跑的动画

.run-south-animation 这个 mixin 是向南奔跑动画的实现,注意 animation-timing-function

的值要设置为 steps(1) ,因为这里每两帧之间不需要补间动画。 forwards 表示最后的状态保持为动画结束时的状态。 animation-iteration-count 的值为 1 表示动画只执行一次不需要重复,因为这里是为了封装一个移动一格的动画,每次使用这个封装好的类时只应该跑动一格。

关键帧 runSouth 中,经过多次测试最终选择了使用 28 帧,因为在此帧数下,动画较为流畅,图片的大小也可以接受。在关键帧动画中,帧数的选取至关重要,要根据具体的需求反复测试,太多或太少都不合适。

@animationDuration: .7s

// 向南奔跑动画
.run-south-animation(@translateX, @translateY) {
  animation: runSouth @animationDuration forwards;
  animation-iteration-count: 1;
  animation-timing-function: steps(1);

  @keyframes runSouth {
    0% {
      transform: translate(0, 0);
      background-position: 0px -2*(@singleAstronautWidth+@verticalInterval);
    }

...   

    50.4% {
      transform: translate(@translateX / 28 * 14, @translateY / 28 * 14);
      background-position: -840px -2*(@singleAstronautWidth+@verticalInterval);
    }

...

    100% {
      transform: translate(@translateX / 28 * 28, @translateY / 28 * 28);
      background-position: -1680px -2*(@singleAstronautWidth+@verticalInterval);
    }
  }
}

如何再次触发跑动动画

当第一次将跑动的类(假设向南)赋予展示小人的元素时小人可以正常跑动,但是如果紧接着再将这个类赋予这个元素时,即使组件中的 state 改变了,也不会触发小人继续向南跑动了。

为了验证这一点,写了一个小 demo,如下代码所示,在 3 s 后改变 state 中的 cls 和 doc,由于 cls 没有发生变化,即使 doc 发生了变化,也不会触发 first 类中的动画重新执行,在线源码和演示

class App extends React.Component {
  
  state = {
    cls: 'first',
    doc: 'hello hello'
  }
  
  componentDidMount() {
    setTimeout(() => {
      this.setState({
        cls: 'first',
        doc: 'world world'
      })
    }, 3000)
  }

  render() {
    return <div>
      <h1 className={this.state.cls}>
        {this.state.doc}
      </h1>
    </div>;
  }
  
}

ReactDOM.render(<App />, document.getElementById("root"));
body {
  height: 100vh;
  margin: 0;
  display: grid;
  place-items: center;
  max-width: 250px;
  margin: 0 auto;
}

.first {
  animation: myfirst 2s linear both;
  animation-iteration-count: 1;
}

@keyframes myfirst
{
    from {background: red;}
    to {background: yellow;}
}

当 state 中的 doc 发生变化时,h1 元素只会更新变化的属性,并不会将整个元素重新渲染。由 react 中的 diff 算法可知,要想让 h1 元素重新渲染,可以给它赋予一个 key 值,然后在 3s 后改变这个 key 值,此时两次 key 值不同就会触发 h1 元素整个重新渲染,然后就可以让动画再次执行。

因此在 state 中新增一个 key 值,并将其赋予 h1 元素的 key 属性,在 3s 后改变这个 key 值就可以使动画重新执行。具体的代码可以参考:在线源码和演示

移动航天小人到指定位置的实现(moveToSpecialPosByCurPos)

  • 获取航天小人将要到的指定位置

  • 根据将要到的指定位置获取下一步的前进方向

  • 改变展示小人元素的位置(使用 transform 属性)

监听动画结束事件,来对下一步的行为做出判断

CSS 动画事件

  • animationstart 某个 CSS 动画开始时触发。

  • animationend 某个 CSS 动画完成时触发。

  • animationiteration 某个 CSS 动画完成后重新开始时触发。

前面我们封装的各个方向的类,每调用一次,小人会向前跑一步,跑完一步后会触发 animationend 事件,在 animationend 事件的回调函数中处理下面应该如何走。

  • 判断是否是连抽,如果是连抽走连抽逻辑

  • 如果不是连抽,将剩余的步数减 1,当前的步数加 1

  • 判断当前的位置是否大于赛道的总步数,如果大于赛道总步数,将当前位置设置为起点

  • 如果小人当前剩余的步数为0,那么改变ELotteryStatus的状态触发中奖动画的展示,并且触发小人停止时的发光动画,在1s后隐藏小人的发光动画。

  • 如果小人当前的剩余步数不为0,根据当前的位置获取下一步的前进方向,然后将相应前进方向跑动动画的类赋予给展示小人的元素

  • 改变展示小人元素的 key 值触发再次执行动画,小人继续向前跑动。

连抽时瞬间移动的实现

  • 当前位置加上抽奖的步数得到最终的位置

  • 最终的位置是否超过赛道长度,如果超过了赛道长度,利用最终的位置减去赛道的总长度

  • 调用 moveToSpecialPosByCurPos 函数移动到指定位置

  • 触发小人停止时的发光动画,并且在 1s 后隐藏小人的发光动画,改变 ELotteryStatus 状态展示中动画

  • 从后台拉取最新的位置,校正小人的位置

3. CSS 动画库

在了解 CSS 动画的原理之后,实际做动画需求的时候,一种比较推荐的做法是站在巨人的肩膀上。业界已经有很多优秀的开源动画库了,可以看一下这些开源的动画库是否可以用得上。

这里主要介绍两个比较常用的 CSS 动画库 Animista Animate CSS

Animista 提供了很多动画类型,并且还提供了很多参数供你设置,设置完成之后就可以获得该动画的 CSS 代码了。

Animate CSS 则是提供了很多动画类,通过给元素设置不同的类就可以实现不同的动画效果。

3.1 Animista

Animista 是一个在线动画生成器,同时也是一个动画库,基本使用步骤如下:

1)选择动画,调节参数

首先选择你想要的动画类型,然后根据你的需求对该动画的参数进行调节。

undefined

2)生成CSS代码

设置完满足自己需求的动画后,我们可以直接从网站上获取代码,甚者还可以进行压缩。

undefined

3.2 Animate CSS

Animate CSS 是最著名的动画库之一,接下来介绍一下 Animate CSS 的一些基本用法,详细的用法可以去官网查询。

基本用法

首先在需要添加动画的元素上添加类 animated ,然后是动画的名字。

<div class="animated slideInLeft"></div>

Animate CSS ****还提供了一些类来控制动画的一些属性,例如动画的延迟和速度等。

  • delay

    通过添加 delay 类来延迟动画的播放。

<div class="animated slideInLeft animate__delay-2s"><div>
  • speed

通过添加这些类(slow|slower|fast|faster)之一来控制动画速度。

<div class="animated slideInLeft slow|slower|fast|faster"><div>

这里用 Animate CSS 库写了一个小的 demo ,在线源码和演示

4. CSS 动画性能优化

回流又叫重排,指几何属性需要改变的渲染,例如当元素的尺寸,布局等发生变化时一般会引发回流。重绘,指外观属性需要改变的渲染,例如当元素的背景色发生变化时一般会引发重绘。

一个 CSS 动画往往会涉及尺寸,位置,颜色等属性的变化,如果处理不当就会引发不断地回流和重绘,导致页面卡顿,尤其在性能有限的移动端这种问题尤为严重。

在上面提到,几何属性改变时一般会引发回流,外观属性改变时一般会引发重绘,那么在 CSS 中哪些属性是几何属性,哪些属性是外观属性呢?这里简单地总结了一下。

几何属性:包括布局、尺寸等可用数学几何衡量的属性。

  • 布局: displayfloatpositionlisttableflexcolumnsgrid

  • 尺寸: marginpaddingborderwidthheight

外观属性:包括界面、文字等可用状态向量描述的属性

  • 界面: appearanceoutlinebackgroundmaskbox-shadowbox-reflectfilteropacityclip

  • 文字: textfontword

我们知道回流一定会引发重绘,重绘不一定会引发回流。回流成本比重绘成本高得多,一个节点的回流很有可能导致子节点、兄弟节点或祖先节点的回流。频繁触发回流会使得页面不断渲染,从而引发严重的性能问题,因此我们一定要尽可能地避免回流,减少重绘。

接下来介绍一些 CSS 动画性能优化的方法。

4.1 使用 visibility:hidden 替换 display:none

从以下四个方面对比一下 display:nonevisibility:hidden ,方便书写, display:none 简称 DNvisibility:hidden 简称 VH

  • 占位表现

  • DN不占据空间

  • VH占据空间

  • 触发影响

  • DN触发回流重绘

  • VH触发重绘

  • 过渡影响

  • DN影响过渡不影响动画

  • VH不影响过渡不影响动画

  • 株连效果

  • DN后自身及其子节点全都不可见

  • VH后自身及其子节点全都不可见但可声明子节点 visibility:visible 单独显示

两者的 占位表现触发影响株连效果 就能说明 VH 代替 DN 的好处,如果两者都能实现需求的情况下推荐使用 visibility:hidden

4.2 使用 transform 代替 top

top 是几何属性,操作 top 会改变节点位置从而引发回流,使用 transform:translate3d(x,0,0) 代替 top ,只会引发图层重绘,还会间接启动GPU加速,因此更加推荐使用 transform 来代替 top。

4.3 避免使用 Table 布局

当然 Table 布局现在已经很少用了,不过在这里还是提一下,来指出它所带来的问题,避免引入类似的问题。牵一发而动全身用在 Table 布局身上再合适不过了,可能很小的一个改动就会造成整个 <table> 回流,大家如果感兴趣可以用 Chrome DevtoolsPerformance 调试看看。对于类似 table 布局的结构,建议用 <ul><li><span> 等标签进行取代。

4.4 避免规则层级过多

浏览器的CSS解析器在解析css文件时,对CSS规则是从右到左匹配查找的,样式层级过多会影响回流重绘效率,建议保持CSS规则在 3层 左右。

4.5 避免节点属性值放在循环里当成循环变量

像下面这段代码就存在很大的问题,每次循环操作 DOM 都会发生回流,应该在循环外使用变量保存一些不会变化的DOM 映射值。

for (let i = 0; i < 10000; i++) {
const top = document.getElementById("css").style.top;
    console.log(top);
}

建议修改为下面这样:

const top = document.getElementById("css").style.top;
for (let i = 0; i < 10000; i++) {
    console.log(top);
}

4.6 将频繁回流重绘的节点设置为图层

在浏览器中设置频繁回流或重绘的节点为一张新图层,因为新图层能够阻止节点的渲染行为影响别的节点,这张图层里如何变化都无法影响到其他图层。

设置新图层通常有以下两种方式:

  • 将节点设置为 <video><iframe>

  • 为节点添加 will-change

4.7 开启 GPU 硬件加速模式

为节点声明 transform:translate3d()transform:translateZ() ,这两个声明都会开启GPU硬件加速模式,从而让浏览器在渲染动画时从CPU转向GPU,实现硬件加速。

transform:translate3d()transform:translateZ() 其实是为了渲染3D样式,但声明为 0
后并无真正使用3D效果,但浏览器却因此开启了GPU硬件加速模式。在 Webkit内核 下使用 transform:translate3d() 加速效果会更明显。

CSS 性能优化的方法还有很多很多,这里就不一一列举了,感兴趣的同学可以自行学习一哈。

5. 总结

本文主要讲了 CSS 动画方面的知识并给出了一些简单的实践以及一些性能上的优化方法,希望通过本文可以帮助你对 CSS 动画有一个简单的认识并能上手一些简单的动画。

虽然在 CSS3 中引入三大交互属性后,让 CSS 也能实现一些比较复杂的动画了,但是不得不承认 CSS 可以实现的动画效果还是非常有限。

不过好在业界还有很多可以实现动画的方案,例如 canvas,three.js,zrender,d3 等等,提到动画一般还会联想到数据可视化这个领域,数据可视化的应用在我们日常工作和生活中随处可见,例如前端监控平台上的各种绘图,某些网站上各种商品的 3D 展示等等,如果对数据可视化的方向比较感兴趣也可以研究学习一哈,很有趣的一个方向。

posted on 2022-11-02 09:56  前端旧约  阅读(396)  评论(2编辑  收藏  举报

导航