css3 动画的实现
Posted weixin79893765432...
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了css3 动画的实现相关的知识,希望对你有一定的参考价值。
目录
- 前言
- 一、@keyframes + animation
- 二、transform + transition
- 三、案例
前言
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
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 的比较
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 动画的实现的主要内容,如果未能解决你的问题,请参考以下文章