上一篇文章总结了过渡和2D变动,这一篇来总结一下动画和3D变换,动画可用的场景也很多,比方在加载的页面的时候,能够搁置一个gif图,也能够自定义小动画来缓解用户期待的焦虑感,比方以下三个小圆圈转圈圈的动画。
想要实现一个动画的成果,首先要晓得定义的语法
应用animation来实现动画,@keyframes来定义元素的静止法则(1) animation-name: 动画的名称,即@keyframes定义的动画名字(必写)(2) animation-duration: 动画的执行工夫,一个动画多久执行实现(必写)(3) animation-timing-function: 动画的速度曲线,默认ease(逐步变慢),还有这些选项 linear 匀速 ease-in 减速 ease-in-out 先减速后加速 ease-out 加速(4) animation-delay: 动画执行的延迟时间,默认0s(5) animation-iteration-count: 动画的执行次数,默认为1,还能够选 infinite代表有限次(6) animation-direction: 规定动画在下一周期是否逆向播放,默认 normal 不逆向播放,还能够选alternate 逆向播放比方一个盒子从左走到右,如果执行次数是1,执行实现盒子就会立即从左边弹回到最右边,如果设置了alternate逆向播放,那么盒子就会依照设定的速度曲线通过动画再回到右边(7) animation-fill-mode: 规定动画的完结状态,默认backwards 回到起始状态,还能够选 放弃状态 forwards设置了之后,animation-direction就不失效了(8) animation-play-state: 设置动画的运行状态,默认 running 运行,还能够选 paused 进行// 这么多的属性能够合并在一起写,并不是每一个都须要写,如果应用默认项,就能够省略,animation-play-state没有合并写法animation: name duration timing-function delay iteration-count direction fill-mode
用一个简略的动画来展现一下以上的属性,同时辨别 ease、ease-in、ease-in-out、ease-out的速度曲线有什么不同
以上动画所设定的animation属性如下
// 规定每个工夫的位移@keyframes move { 0%{ transform: translateX(0px) } 100%{ transform: translateX(1000px); }}.box { margin-top: 20px; width: 100px; height: 80px; background-color: brown; animation-name: move; // 动画名称 animation-duration: 6s; // 动画执行工夫 animation-timing-function: ease; // 动画速度曲线,别离为ease、ease-in、ease-in-out、ease-out animation-delay: 1s; // 动画提早1s执行 animation-fill-mode: forwards; // 执行实现后放弃状态}
上面演示一下 animation-direction 、animation-fill-mode和animation-play-state该怎么应用。
第一个方块的animation-direction和animation-fill-mode都是默认的配置,normal不逆向播放,backwards回到起始地位,默认属性能够不必定义。
第二个方块展现了animation-derection: alternate 逆向播放,逆向播放须要配合播放的次数,animation-direction,如果依照默认只播放一次的话,就不会失效。
第三个方块展现了animation-fill-mode: forwards 动画完结后放弃状态。
第四个方块展现了当鼠标滑过期让方块进行静止 animation-play-state: paused
理解完动画的各项配置属性之后,就能够依据2D或者3D的变动来做一些小动画了,上方三个小圈的加载动画用到的就是动画+2D变动,通过缩放盒子的大小来达到一个动的成果,实现代码如下
// html代码<div class="parent"> <div class="circle"></div> <div class="circle"></div> <div class="circle"></div></div>// css代码.parent { width: 80px;}.circle { display: inline-block; width: 20px; height: 20px; background-color: orange; border-radius: 50%; animation: move 1.4s ease-in-out 0s infinite both;}.circle:nth-child(1){ animation-delay: -0.32s;}.circle:nth-child(2){ animation-delay: -0.16s;}@keyframes move { 0%, 80%, 100% { transform: scale(0) } 40% { transform: scale(1) }}
animation-timing-function静止曲线还能够选 steps 步长,代表须要多少步可能实现动画,比方动画的执行工夫是2s,定义步长 steps(10),就代表2s内10步实现变动,即每一步0.2s,步长的执行成果有点像老式打印机,一个字一个字打出内容,可参考上面这个成果。
那用步长能够做出什么样的成果呢,咱们来看看下图,下图里奔跑的白熊是在页面中展现一张gif图吗?
其实它只是一张有不同状态白熊的图片,计算每一个白熊的宽高,通过管制步长,造成动画
实现代码如下
.bear { position: absolute; left: 0; width: 200px; height: 200px; background: url(./media/bear.png) no-repeat; animation: run 1s steps(8) 7s infinite, move 3s linear 7s forwards;}@keyframes run { 100% { background-position: -1600px 0; }}@keyframes move { 100% { left: 50%; transform: translate(-50%) }}
动画还能够和3d变换联合应用,3d变换就是在2d的根底上减少了一个轴,Z轴,示意从人眼到屏幕这段距离,如果不做其它设置,是看不出3d与2d变动区别的,那此时要借助一个属性 透视perspective,增加到父元素下面,透视示意人眼到屏幕的间隔,间隔越小,图像越大,间隔越大,图像越小
transform中有位移的3d变换是translateZ,示意物体沿着Z轴方向的挪动间隔。挪动为正值的话,此时物体在眼睛到屏幕之间,离屏幕越远即离眼睛越近,显示在屏幕的物体则越大,挪动为负值则相当于到屏幕的背地去了,显示在屏幕的物体越小。如下图,d示意透视 perspective,z示意translateZ的大小
用一个图来展现加了3d变动和自身的元素大小比拟,右边盒子的透视设置的是300px,perspective: 300px,不同的电脑显示屏幕显示的大小可能不太一样
translateZ个别会配合rotate一起做3d的变动,rotate能够别离沿着x轴/y轴/z轴做旋转,沿着x轴的旋转成果能够设想一下运动员沿着单杠做高低的翻转,沿着y轴旋转能够设想一个钢管舞者,沿着竖着的钢管静止,沿着z轴的旋转能够参考抽奖的大转盘,就是立体内的旋转,没有平面成果。
旋转方向的判断能够应用左手法令,左手掌心朝外握拳,大拇指指向x轴的正方向,手指蜿蜒方向就是当物体沿着x轴进行旋转时,旋转的正方形,判断物体沿着y轴进行旋转时,左手掌心朝外握拳,大拇指左手掌心朝外握拳,手指蜿蜒方向就是正方向。用本人的手来做个演示
旋转的方向比拟多,各个方向之间旋转的成果能够参考上面的动画,别离展现了从x轴、y轴、z轴、以及x和y轴同时旋转是什么样,3d成果肯定要给父元素增加透视 perspective!
总结一下3d位移和3d旋转的语法
// 父元素肯定要定义 perspectiveperspective: 500px// 位移transform: translateZ(100px)transform: translate3d(0,0,100px)// 也能够定义x和y轴方向的挪动,那就是2d立体内的挪动,没有3d近大远小的成果// 旋转transform: rotateX(45deg)transform: rotateY(45deg)transform: rotateZ(45deg)transform: rotate3d(1, 1, 0, deg) // x轴和y轴都旋转45度, 此时是找矢量, 及对角线地位
3d变换还有一个属性要留神,下面演示的旋转只作用于以后元素,如果父子元素都要进行3d的变换,如果不设置transform-style,父元素进行3d变换的时候,子元素的3d变换就会生效,就像下图一样
联合透视 perspective、transform-style 以及位移transform和旋转rotate,就能够做出一些动画成果了,上面是一个3d导航栏,定义多个导航时,能够选中导航进行一个向上翻转的成果
实现代码如下
// html代码<div class="box"> <div class="top">hello</div> <div class="bottom">world</div></div>// css代码body { perspective: 500px;}.box { position: relative; margin: 100px auto; width: 100px; height: 40px; transform-style: preserve-3d; transition: transform 1s;}.box:hover { transform: rotateX(90deg)}.box div { position: absolute; top: 0; left: 0; width: 100%; height: 100%; text-align: center; color: #fff; line-height: 40px; background-color: rosybrown;}.box .bottom { transform: translateY(20px) rotateX(-90deg)}.box .top { background-color: sandybrown; transform: translateZ(20px)}
联合位移和旋转,能够实现如下图的旋转木马成果,当鼠标移入某个图片时,旋转木马暂停旋转
实现代码如下
// html代码 <section> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div></section>// css代码body { /* 设置透视的间隔 */ perspective: 1400px;}section { position: relative; width: 300px; height: 200px; margin: 100px auto; background: url(./media/pig.jpg) no-repeat; transform-style: preserve-3d; animation: rotateDog 10s linear infinite;}section:hover { /* 当鼠标滑过 动画状态为paused进行 */ animation-play-state: paused;}section div { position: absolute; top: 0; left: 0; height: 100%; width: 100%; background: url(./media/dog.jpg) no-repeat; }@keyframes rotateDog { 0% { transform: rotateY(0); } 100%{ transform: rotateY(360deg); }}section div:nth-child(1){ transform: translateZ(300px)}section div:nth-child(2){ transform: rotateY(60deg) translateZ(300px)}section div:nth-child(3){ transform: rotateY(120deg) translateZ(300px)}section div:nth-child(4){ transform: rotateY(180deg) translateZ(300px)}section div:nth-child(5){ transform: rotateY(240deg) translateZ(300px)}section div:nth-child(6){ transform: rotateY(300deg) translateZ(300px)}
以上就是动画和3d变换的联合应用,应用过渡、动画、2d/3d变换能提供更好的用户体验。