前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >animation

animation

作者头像
ayqy贾杰
发布2023-03-15 18:49:58
1.1K0
发布2023-03-15 18:49:58
举报
文章被收录于专栏:黯羽轻扬黯羽轻扬

一.CSS动画

CSS动画相对JS动画有2个主要优势:

1.流畅

因为渲染引擎可以通过跳帧(frame-skipping)及其它技术来确保性能尽量流畅

2.浏览器性能优化

把动画序列交给浏览器去控制,这样浏览器就能优化性能和效率,比如对于看不见的tab,可以减少刷新频率

定义动画分为2部分

  • 配置animation各项子属性
  • 通过@keyframes定义关键帧样式

浏览器根据这些东西来创建补间动画,计算插值把各个关键帧连接起来

二.animation子属性

代码语言:javascript
复制
animation-name @keyframes定义的关键帧名,默认none
animation-duration 动画时长,默认0s,与transition完全一致
animation-timing-function easying函数,默认ease,与transition完全一致
animation-delay 延迟时间,默认0s,,与transition完全一致
animation-iteration-count 重复次数,默认1
animation-direction 方向,默认normal
animation-fill-mode 样式应用模式,默认none
animation-play-state 用来暂停/恢复动画序列,默认running

需要注意:

  • durationdelay,其它参数顺序随意
  • animation-name不要和关键字重名,会优先匹配属性

animation-iteration-count

代码语言:javascript
复制
animation-iteration-count = infinite | <number>

动画重复次数,各值分别表示无限次、指定次数

animation-direction

代码语言:javascript
复制
animation-direction = normal | reverse | alternate | alternate-reverse

动画执行方向,各值分别表示正向、反向、交替(奇数次正向偶数次反向)、反向交替(奇数次反向偶数次正向)

animation-fill-mode

代码语言:javascript
复制
animation-fill-mode = none | forwards | backwards | both

样式应用模式,各值分别表示不应用关键帧样式、(结束后)应用终态样式、(delay期间)应用初态样式、(delay期间)应用初态样式且(结束后)应用终态样式

注意:初态和终态可能是0%也可能是100%,由animation-iteration-countanimation-direction共同决定

关键字含义如下:

代码语言:javascript
复制
none 在动画结束后,去掉@keyframes定义的样式,恢复原样式
forwards 在动画结束后,保持终态样式
backwards 在动画开始前(delay期间),保持初态样式
both 同时具有forwards和backwards的效果,即在delay期间保持初态样式,在动画结束后保持终态样式

具体差异见Demo:http://www.ayqy.net/temp/animation/animation-fill-mode.html,点击红色块开始动画

animation-play-state

代码语言:javascript
复制
animation-play-state = running | paused

决定动画执行还是暂停,可以用来控制动画暂停/恢复,比delay更强大更灵活一些

具体效果见Demo:http://www.ayqy.net/temp/animation/animation-play-state.html

三.@keyframes

语法如下:

代码语言:javascript
复制
@keyframes anmiationName {
   0% {}
   /*...*/
   100% {}
}

如果没有定义0%100%,浏览器就根据其它时刻的关键帧给所有属性算一组值

P.S.tofrom分别是0%100%的别名,因为初态和终态比较重要,有权申请英文名

四.事件

transition只有一个end事件,animation提供了3个事件:

代码语言:javascript
复制
animationstart      开始
animationend        结束
animationiteration  开始下一次重复

事件对象有3个特殊属性:

  • animationName 即animation-name
  • elapsedTime 单位是秒,对于animationstartanimationend表示动画执行到此刻的时间,对于animationiteration,表示下一次重复开始的时间,与transitionend事件类似,一般不受delay影响 特殊的,animationstart中的elapsedTime一般为0,除非animation-delay是个负值,此时elapsedTime-1 * delay
  • pseudoElement 以::开头的伪元素名,如果动画不是应用在伪元素上,就是空串

注意:最后一次重复结束的时候,不会触发animationiteration,而是触发animationend

五.技巧

1.steps(1)去掉平滑过渡

steps(1)linear很像,去掉一个linear动画的补间过渡,只留下关键帧,关键帧之间的帧延续上一个关键帧,就得到了steps(1)

制作Flash时,先插入两个关键帧,此时两个关键帧之间的都是普通帧(用来延长上一个关键帧的播放时间),这时的效果就是steps(1)。右键后一个关键帧,创建补间动画,此时得到的就是linear效果

实例如下:

代码语言:javascript
复制
.rgb {
   -webkit-animation: rgb 1.5s linear infinite;
   animation: rgb 1.5s linear infinite;
}
@keyframes rgb {
   0% {
       opacity: red;
   }
   33% {
       background: green;
   }
   66% {
       background: blue;
   }
}

效果是背景色红绿蓝平滑渐变,想去掉渐变的平滑过渡,直接把linear改为steps(1)即可,如下:

代码语言:javascript
复制
.rgb-step {
   -webkit-animation: rgb 1.5s steps(1) infinite;
   animation: rgb 1.5s steps(1) infinite;
}

效果就变成了每0.5秒切换一次背景色,没有渐变过渡

具体应用:两种状态无限切换(闪烁)

代码语言:javascript
复制
.blink {
   -webkit-animation: blink 1s steps(1) infinite;
   animation: blink 1s steps(1) infinite;
}
@keyframes blink {
   0% {
       opacity: 0;
   }
   50% {
       opacity: 1;
   }
}

2.添加关键帧去掉平滑过渡

闪烁效果有另一种有趣的实现方式:

代码语言:javascript
复制
.blink {
   -webkit-animation: blink 1s linear infinite;
   animation: blink 1s linear infinite;
}
@keyframes blink {
   0% {
       opacity: 0;
   }
   50% {
       opacity: 0;
   }
   50.01% {
       opacity: 1;
   }
   100% {
       opacity: 1;
   }
}

虽然还是linear平滑过渡,但插入的:

代码语言:javascript
复制
50.01% {
   opacity: 1;
}

去掉了50% -> 100%的补间,把透明度补间转移到50% -> 50.01%,时间较短的情况下,这个补间变化不会被察觉,当然,如果时间足够长,比如:

代码语言:javascript
复制
.blink {
   -webkit-animation: blink 10000s linear infinite;
   animation: blink 10000s linear infinite;
}

就应该能看到透明度在某1秒内从0渐变到1,但一般情况下,这样实现闪烁在效果上是没有问题的

3.关键帧控制延迟

animation-delay只在动画开始前有效,每次重复不会插入延迟。类似于上面50.01%的技巧,可以通过插入空白关键帧来给每次重复插入延迟,实现loading转一圈等一等的效果:

代码语言:javascript
复制
.wait {
   -webkit-animation: wait 1s linear infinite;
   animation: wait 1s linear infinite;
}
@keyframes wait {
   0% {
       -webkit-transform: rotateZ(0);
       transform: rotateZ(0);
   }
   40% {
       -webkit-transform: rotateZ(0);
       transform: rotateZ(0);
   }
   100% {
       -webkit-transform: rotateZ(360deg);
       transform: rotateZ(360deg);
   }
}

做到了每转一圈等0.4s

4.steps逐帧动画

把序列帧平铺在一张图片上,修改background-position

steps()实现的话需要在末尾复制第一帧(比如6帧动画,需要7帧平铺图),例如:

代码语言:javascript
复制
.walk {
   background: url(walk.svg);
   width: 162px;
   height: 230px;   -webkit-animation: walk 1s steps(22) infinite;
   animation: walk 1s steps(22) infinite;
}
@keyframes walk {
   0% {
       background-position: 0 0;
   }
   100% {
       background-position: -3564px 0;
   }
}

其中walk.svg横向铺满了23帧,每帧尺寸是162 * 230,向左抽背景图片,最多能抽162 * 22 = 3564,此时显示最后一帧(图片帧内容与第一帧相同),首尾接起来

当然,还有另一种方法,用steps(1)去掉平滑过渡,然后手动设置22个关键帧,比较费劲,这里不给例子,但肯定是可行的

在线Demo:http://www.ayqy.net/temp/animation/css-animation-tricks.html

六.总结

CSS animation的定义方式和Flash非常相似,比如Flash中的几个概念:

  • 关键帧:如果你希望某处的内容要跟前面不一样,就插入关键帧
  • 空白关键帧:表示上面没内容,以小白点显示。他可以跟关键帧互相转换,放了内容就成关键帧了。关键帧上的内容去掉就是空白关键帧
  • 普通帧:关键帧或者空白关键帧后面延续的是普通帧。普通帧是延续之前关键帧的内容,所以他的作用可以来控制动画的显示时间

对应到CSS的@keyframes定义中感受一下,是不是有点意思?

参考资料

  • Using CSS animations – CSS | MDN
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端问问 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二.animation子属性
    • animation-iteration-count
      • animation-direction
        • animation-fill-mode
          • animation-play-state
          • 三.@keyframes
          • 四.事件
          • 五.技巧
            • 1.steps(1)去掉平滑过渡
              • 2.添加关键帧去掉平滑过渡
                • 3.关键帧控制延迟
                  • 4.steps逐帧动画
                  • 六.总结
                    • 参考资料
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档