乐趣区

关于前端:好用的css3特性动画和3d变换

上一篇文章总结了过渡和 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 旋转的语法

// 父元素肯定要定义 perspective
perspective: 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 变换能提供更好的用户体验。

退出移动版