css3 动画的实现

Posted weixin79893765432...

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了css3 动画的实现相关的知识,希望对你有一定的参考价值。

目录


前言

css3 动画的实现的方案,大概有以下方案:

  • js 的 animation() 方法实现动画(这是一个实验功能,此功能某些浏览器尚在开发中。详见这里)。
  • @keyframes + animation:这是一个实现动画的组合,必须一起使用。
  • transition:表示过渡。transition 可以单独使用,
  • transform:表示变形。使用 transform 实现动画时有两种选择:
    • transform + transition:一次性动画。transform 定义行为,transition 驱动,但一次仅能驱动一次。
    • transform + @keyframes + animation:支持循环动画。在 @keyframes 里使用 transform 定义行为,animation 驱动,可充分调整动画的实现,包括:指定动画任意的执行次数,指定动画的结束与开始的状态等等。

transition 和 animation 实现动画的区别

  • transition:需要触发一个事件才执行动画。
  • animation:自动执行动画,可循环执行。

一、@keyframes + animation

CSS animation 属性

1、@keyframes——创建动画

@keyframes 用来创建动画。其内部规定一个动画——从目前的样式更改为新的样式。

(1)、在 @keyframes 中用 from 和 to 创建动画

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

/* Safari 与 Chrome */
@-webkit-keyframes myfirst
    from background: red;
    to background: yellow;

(2)、在 @keyframes 中用 “百分比” 创建动画

// 当动画为 25% 及 50% 时改变背景色,然后当动画 100% 完成时再次改变:
@keyframes myfirst

    0%   background: red;
    25%  background: yellow;
    50%  background: blue;
    100% background: green;

 
@-webkit-keyframes myfirst /* Safari 与 Chrome */

    0%   background: red;
    25%  background: yellow;
    50%  background: blue;
    100% background: green;

(3)、将 @keyframes 嵌套进要添加动画的元素的样式里

将 @keyframes 嵌套进要添加动画的元素的样式里,然后,通过 animation 执行这个动画:

.action-move 
    animation: box-move 3s ease-out;
    -webkit-animation: activity-move 3s ease-out;
    animation-fill-mode: forwards;
    @keyframes box-move 
        0% transform: scale(1); opacity: 1
        20% transform: scale(1.3); opacity: 1
        40% transform: scale(1.3); opacity: 1
        60% transform: scale(1); opacity: 1
        80% transform: scale(1.2); opacity: 1
        100% transform: scale(1); opacity: 0
    

2、animation 执行动画

在 @keyframes 创建动画后,必须通过 animation 属性把该 keyframes 绑定到指定的选择器上,否则动画不会有任何效果。

语法:

animation: name duration timing-function delay iteration-count direction 
fill-mode play-state;

animation 属性是以下属性的简写形式:

  • animation-name:必须的。规定 @keyframes 动画的名称。
  • animation-duration:必须的。指定一个动画周期的时长。默认是 0s,表示无动画。
  • animation-timing-function:可选的。规定动画的速度曲线。
  • animation-delay:可选的。规定动画何时开始,值可以是所有的整数。默认是 0。(这是一个实验中的功能,某些浏览器尚在开发中)
  • animation-iteration-count:可选的。规定动画被播放的次数。默认是 1。(这是一个实验中的功能,某些浏览器尚在开发中)
  • animation-direction:可选的。指示动画是否反向播放。(这是一个实验中的功能,某些浏览器尚在开发中)
  • animation-fill-mode:可选的。规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式。
  • animation-play-state:可选的。规定动画是否运行或暂停。默认是 “running”。

将创建的动画绑定到一个指定的选择器上:

// 把 "myfirst" 动画捆绑到 div 元素,时长:5 秒:
div
    animation: myfirst 5s;
    -webkit-animation: myfirst 5s; /* Safari 与 Chrome */

实现一个完全属性的动画——该动画只执行一次,且动画结束后停留在最后一帧的状态:

animation: set_touch 1s ease 0s 1 normal forwards running;

3、animation 的具体属性的解读如下

(1)、animation-name 属性

必须的。规定 @keyframes 动画的名称。

animation-name 属性的值:

  • none:特殊关键字,表示无关键帧。可以不改变其他标识符的顺序而使动画失效,或者使层叠的动画样式失效。
  • IDENT:标识动画的字符串,由大小写敏感的字母a-z、数字0-9、下划线(_)和/或横线(-)组成。第一个非横线字符必须是字母,数字不能在字母前面,不允许两个横线出现在开始位置。

(2)、 animation-duration 属性

必须的。指定一个动画周期的时长。默认是 0s,表示无动画。

  • <time>:一个动画周期的时长,单位为秒(s)或者毫秒(ms)。

案例:

// 一个值
animation-duration: 6s;

//多个值
animation-duration: 10s, 30s, 230ms;

(3)、animation-timing-function 属性

可选的。规定动画的速度曲线。

animation-timing-function 属性的值:

  • ease:默认值。动画开始时做加速运动,在结束前变慢。
  • ease-in:动画以低速开始。
  • ease-out:动画以低速结束。
  • ease-in-out:动画以低速开始和结束。
  • linear:动画始终保持匀速运动。
  • steps-start:表示动画是从时间段的开头连续。
  • steps-end:表示动画是从时间段的末尾连续。

函数值:

  • cubic-bezier() 函数:值必须在集合 [0, 1] 的浮点数集合里。
  • steps() 函数:指定了时间函数中的间隔数量(步数)。有两个参数:
    • 间隔数量(步数):必须的。一个正整数。
    • 动画的连续状态:表示动画是从时间段的开头连续还是末尾连续。
      • end:默认值,表示戛然而止。
      • start:表示直接开始。
  • frames() 函数:值是一个正整数。

案例:

// 一个值
animation-timing-function: linear;

// 多个值
animation-timing-function: ease, step-start, cubic-bezier(0.1, 0.7, 1.0, 0.1);

// cubic-bezier() 函数
animation-timing-function: cubic-bezier(0, 0.7, 1, 0.1);

// steps() 函数
animation-timing-function: steps(4, end);

// frames() 函数
animation-timing-function: frames(10);

(4)、animation-delay 属性

可选的。规定动画何时开始,值可以是所有的整数。默认是 0。(这是一个实验中的功能,某些浏览器尚在开发中)

animation-delay 属性的值:

  • <time>:从动画样式应用到元素上到元素开始执行动画的时间差。该值可用单位为秒(s)和毫秒(ms)。

案例:

// 一个值
animation-delay: 3s;

// 多个值
animation-delay: 2s, 4ms;

(5)、animation-iteration-count 属性

可选的。规定动画被播放的次数。默认是 1。(这是一个实验中的功能,某些浏览器尚在开发中)

animation-iteration-count 属性的值:

  • infinite:无限循环播放动画。
  • <number>:动画播放的次数;默认值为1。可以用小数定义循环,来播放动画周期的一部分:例如,0.5 将播放到动画周期的一半。不可为负值。

案例:

// infinite
animation-iteration-count: infinite;

// <number>
animation-iteration-count: 3;

// 多个值
animation-iteration-count: 2, 0.5, infinite;

(6)、animation-direction 属性

可选的。指示动画是否反向播放。(这是一个实验中的功能,某些浏览器尚在开发中)

animation-direction 属性的值:

  • normal:默认值。正向运行动画,每周期动画循环结束,动画重置到起点重新开始。
  • alternate:动画交替反向运行,反向运行时,动画按步后退,同时,带时间功能的函数也反向。比如,ease-in 在反向时成为 ease-out。计数取决于开始时是奇数迭代还是偶数迭代。
  • reverse:反向运行动画,每周期动画循环结束,动画由尾到头运行。
  • alternate-reverse:反向交替, 反向开始交替。动画第一次运行时是反向的,然后下一次是正向,后面依次循环。决定奇数次或偶数次的计数从 1 开始。

案例:

// 一个值
animation-direction: normal;

// 多个值
animation-direction: alternate, reverse, normal;

(7)、animation-fill-mode 属性

可选的。规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式。

animation-fill-mode 属性的值:

  • none:默认值。动画将不会将任何样式应用于目标。
  • forwards:动画停留在动画执行到最后一个关键帧的状态值。
  • backwards:动画恢复到第一个关键帧的状态值。
  • both:动画遵循 forwards 和 backwards 二者的规则,从而在两个方向上扩展动画属性。

案例:

// 单个值
animation-fill-mode: backwards;

// 多个值
animation-fill-mode: both, forwards, none;

(8)、animation-play-state 属性

可选的。规定动画是否运行或暂停。默认是 “running”。

animation-play-state 属性的值:

  • running:默认值。当前动画正在运行。
  • paused:当前动画已被停止。

案例:

// 单个值
animation-play-state: paused;

// 多个值
animation-play-state: paused, running, running;

二、transform + transition

CSS transform 属性
CSS transition 属性

1、transform——变形

用 transform 实现的动画必须用 transition 来驱动。

(1)、transform 2D 与 3D 的比较

transform 2D 与 3D 的比较表
2D 3D
属性 描述 属性 描述
- - backface-visibility 定义元素在不面对屏幕时是否可见。
- - transform-style 定义被嵌套元素如何在 3D 空间中显示。
- - perspective(n) 定义 3D 元素的透视效果。
transform-origin 改变元素的中心原点的位置。 perspective-origin 定义 3D 元素的底部的中心位置位置。
rotate(angle) 旋转。在一个给定度数顺时针旋转的元素。负值是允许的,这样是元素逆时针旋转。 rotate3d(x, y, z, angle) 同 2D 的 rotate。

- rotateX(angle)
- rotateY(angle)
- rotateZ(angle)
translate(x, y) 位移。根据左(X轴)和顶部(Y轴)位置给定的参数,从当前元素位置移动。

- translateX(n):沿着 X 轴移动元素。
- translateY(n):沿着 Y 轴移动元素。
translate3d(x, y, z) 同 2D 的 translate。

- translateX(n)
- translateY(n)
- translateZ(n)
scale(x, y) 缩放。该元素增加或减少的大小,取决于宽度(X轴)和高度(Y轴)的参数。

- scaleX(x):改变元素的宽度。
- scaleY(y):改变元素的高度。
scale3d(x, y, z) 同 2D 的 scale。

- scaleX(x)
- scaleY(y)
- scaleZ(z)
skew(x-angle, y-angle) 倾斜。包含两个参数值,分别表示X轴和Y轴倾斜的角度,如果第二个参数为空,则默认为0,参数为负表示向相反方向倾斜。

- skewX(angle):表示只在 X 轴(水平方向)倾斜。
- skewY(angle):表示只在 Y 轴(竖直方向)倾斜。
- -
matrix(n,n, n,n, n,n) 整合。将上面 2D 变化所有的方法整合成一个使用。使用 2x3 的矩阵。包含旋转,缩放,移动(平移)和倾斜功能。 matrix3d(n,n,n,n, n,n,n,n, n,n,n,n, n,n,n,n) 整合。将上面 3D 变化所有的方法整合成一个使用。使用 16 个值的 4x4 的矩阵。

(2)、transform 属性的使用

// translate——位移
div 
    transform: translate(50px, 100px);
    transition: transform 500ms;

 
// rotate——旋转
div 
    transform: rotate(30deg);
    transition: transform 500ms;

 
// scale——缩放
div 
    transform: scale(2, 3);
    transition: transform 500ms;

 
// skew——倾斜
div 
    transform: skew(30deg, 20deg);
    transition: transform 500ms;

 
// matrix——整合
div 
    transform:matrix(0.866, 0.5, -0.5, 0.866, 0, 0);
    transition: transform 500ms;

2、transition——过渡

从一种样式转变到另一种样式的过程叫做 过渡。

语法:

 transition: property | duration | timing-function | delay 
  • transition-property:规定应用过渡的 CSS 属性的名称。
  • transition-duration:定义过渡效果花费的时间。默认是 0。
  • transition-timing-function:规定过渡效果的时间曲线。默认是 “ease”。
  • transition-delay:规定过渡效果何时开始。默认是 0。

(1)、transition 的实现

要实现这一点,必须定义好两项内容:

  • 指定要添加效果的CSS属性
  • 指定效果的持续时间。

例如:

// 定义宽度属性的过渡效果,时长为 2 秒
div
    width: 100px;
    transition: width 2s;
    -webkit-transition: width 2s; /* Safari */

【注意】如果未指定的期限,transition 将没有任何效果,因为默认值是 0。

(2)、多项改变

要添加多个样式的变换效果,添加的属性由逗号分隔:

div
    width: 100px;
    height: 100px;
    transform: rotateX(120deg);
    transition: width 2s, height 2s, transform 2s;
    -webkit-transition: width 2s, height 2s, -webkit-transform 2s;

三、案例

1、transform + @keyframes + animation 实现 loadding 加载

.iconfont-loadding 
  animation: start_loadding 800ms linear 100ms infinite normal none running;


@keyframes start_loadding 
  from  transform: rotate(0deg);
  to  transform: rotate(360deg);

进一步组件化:

// 封装一个使用动画的函数,接受一个表示位置的参数(通过调用这个函数就可以使用这个动画)
.entry-animation(@position: top) 
  animation: entry 800ms ease 100ms forwards;
  @keyframes entry 
    0% 
      @position: 0px;
      opacity: 0;
    
    100% 
      @position: 50px;
      opacity: 1;
    
  

// 创建一个动画
@keyframes start_loadding 
  0%  transform: rotate(0deg);
  100%  transform: rotate(360deg);

【注意】经实际验证:

  • 关键字 from 和 to,以及百分比进度,是不能被抽离成变量的。
  • 对于 @keyframes <动画名>,其中“动画名”是不能被抽离成变量的。

2、transition 实现页面头部导航栏的颜色过渡变化

首先,假设在 template 里已经写好了页面头部导航栏,接下来要在 css 中定义好相关的类:

.dark 
  color: #333;
  background: rgba(255, 255, 255, 1);
  transition: color 3s, background 3s;

.light 
  color: #fff;
  background: rgba(255, 255, 255, 0);
  transition: color 3s, background 3s;

.empty 
  opacity: 0;
  transition: opacity 3s;

然后,在 js 中使用这些类:

export default 
  mounted () 
    window.addEventListener('scroll', this.handleScroll)
  ,
  beforeDestroy () 
    window.removeEventListener('scroll', this.handleScroll)
  ,
  methods: 
    // 监听页面滚动
    handleScroll (e) 
      let scrollTop = window.pageYOffset ||
      	document.documentElement.scrollTop ||
      	document.body.scrollTop
      if (scrollTop >=0 && scrollTop <= 30) 
        this.$refs.tagTopMenu.className = `tag-top-menu light`
       else if (scrollTop >= 100) 
        this.$refs.tagTopMenu.className = `tag-top-menu dark`
       else 
        this.$refs.tagTopMenu.className = `tag-top-menu empty`
      
    
  

【遇到的问题】:

  • 在 vue 中 window.addEventListener(‘scroll‘, xxx) 监听失效,怎么办?

入参加上 true。让其在捕获阶段而非冒泡阶段执行这个监听。(如果是 true,表示在捕获阶段调用事件处理程序;如果是 false,表示在冒泡阶段调用事件处理程序。)

例如:

  mounted () 
    window.addEventListener('scroll', this.handleScroll, true)
  ,
  beforeDestroy () 
    window.removeEventListener('scroll', this.handleScroll, true)
  
  • 在 vue 中使用 document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset 这三个值都是 0,怎么办?

我这边是,代码里面写了 min-height: calc(100vh - 268px);,这个一直是不超出屏幕的。并且,我给父元素 div 加了 overflow-y: scroll; 实现了滚动条,但带来了现在的这个问题。可是又不得不加 overflow,否则我就可以通过改 overflow 来解决这个问题了。

此时,还有一种办法:改取 e.target 的 scrollTop 即可。

例如:

// 监听页面滚动
    handleScroll (e) 
      // let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
      let scrollTop = e.target.scrollTop
      this.isShowTagTitle = false
      if (scrollTop <= 30) 
        this.$refs.tagTopMenu.className = `tag-top-menu light`
       else if (scrollTop >= 130) 
        this.$refs.tagTopMenu.className = `tag-top-menu dark`
        this.isShowTagTitle = true
       else 
        this.$refs.tagTopMenu.className = `tag-top-menu empty`
      
    ,

【参考】
vue中window.addEventListener(‘scroll‘, xx)失效解决办法
解决window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop获取距离顶部距离都为0的问题
为什么scrollTop设置后一直为0的解释和解决方案(精品)

CSS实现动画真的性能更好么?

最近在优化页面动画效果时,和同事探讨到了页面动画卡顿的问题,即使大致了解CSS实现的动画会比JS性能更佳,卡顿更少,但是一直没有深究这样的问题原理是什么。这次在优化过程中,发现即使使用CSS动画,但是在使用height,width,margin,padding作为transition的值的时候,依然会卡顿,但是使用CSS transform就会有明显的改善。问题类似就不赘述了,在参考中附一个类似的问题。
这里主要讲一讲CSS到底哪些动画效果帧数高,性能好,背后的原理到底又是什么。

以上是关于css3 动画的实现的主要内容,如果未能解决你的问题,请参考以下文章

前端Css3那些事

如何解决css3动画在安卓机上卡顿现象

前端制作动画的几种方式(css3,js)

18个强大的纯CSS3动画案例分享

前端实现动画

CSS3CSS3动画——我离前端的炫酷又近了一步