美文网首页
好用的css3特性-动画和3d变换

好用的css3特性-动画和3d变换

作者: 一颗冰淇淋 | 来源:发表于2021-04-26 00:46 被阅读0次

    上一篇文章总结了过渡和2D变化,这一篇来总结一下动画和3D变换,动画可用的场景也很多,比如在加载的页面的时候,可以放置一个gif图,也可以自定义小动画来缓解用户等待的焦虑感,比如以下三个小圆圈转圈圈的动画。

    loding加载动画.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的速度曲线有什么不同


    速度曲线的区别.gif

    以上动画所设定的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


    aniamtion其它属性演示.gif

    了解完动画的各项配置属性之后,就可以根据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,步长的执行效果有点像老式打印机,一个字一个字打出内容,可参考下面这个效果。


    速度曲线steps.gif

    那用步长可以做出什么样的效果呢,我们来看看下图,下图里奔跑的白熊是在页面中展示一张gif图吗?


    奔跑的白熊.gif

    其实它只是一张有不同形态白熊的图片,计算每一个白熊的宽高,通过控制步长,形成动画


    bear.png

    实现代码如下

    .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,添加到父元素上面,透视表示人眼到屏幕的距离,距离越小,图像越大,距离越大,图像越小


    三维坐标系.jpg

    transform中有位移的3d变换是translateZ,表示物体沿着Z轴方向的移动距离。移动为正值的话,此时物体在眼睛到屏幕之间,离屏幕越远即离眼睛越近,显示在屏幕的物体则越大,移动为负值则相当于到屏幕的背后去了,显示在屏幕的物体越小。如下图,d表示透视 perspective,z表示translateZ的大小


    透视.png

    用一个图来展示加了3d变化和本身的元素大小比较,左边盒子的透视设置的是300px,perspective: 300px,不同的电脑显示屏幕显示的大小可能不太一样


    translateZ.png

    translateZ一般会配合rotate一起做3d的变化,rotate可以分别沿着x轴/y轴/z轴做旋转,沿着x轴的旋转效果可以想象一下运动员沿着单杠做上下的翻转,沿着y轴旋转可以想象一个钢管舞者,沿着竖着的钢管运动,沿着z轴的旋转可以参考抽奖的大转盘,就是平面内的旋转,没有立体效果。

    旋转方向的判断可以使用左手法则,左手掌心朝外握拳,大拇指指向x轴的正方向,手指弯曲方向就是当物体沿着x轴进行旋转时,旋转的正方形,判断物体沿着y轴进行旋转时,左手掌心朝外握拳,大拇指左手掌心朝外握拳,手指弯曲方向就是正方向。用自己的手来做个演示


    旋转方向.png

    旋转的方向比较多,各个方向之间旋转的效果可以参考下面的动画,分别展示了从x轴、y轴、z轴、以及x和y轴同时旋转是什么样,3d效果一定要给父元素添加透视 perspective!


    rotate旋转方式比较.gif

    总结一下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变换就会失效,就像下图一样


    transform-style的作用.gif

    结合透视 perspective、transform-style 以及位移transform和旋转rotate,就可以做出一些动画效果了,下面是一个3d导航栏,定义多个导航时,可以选中导航进行一个向上翻转的效果


    3d导航栏.gif

    实现代码如下

    // 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)
    }
    

    结合位移和旋转,可以实现如下图的旋转木马效果,当鼠标移入某个图片时,旋转木马暂停旋转


    旋转木马效果.gif

    实现代码如下

    // 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变换能提供更好的用户体验。

    相关文章

      网友评论

          本文标题:好用的css3特性-动画和3d变换

          本文链接:https://www.haomeiwen.com/subject/zqfsrltx.html