美文网首页
【过渡与动画】沿环形路径平移的动画

【过渡与动画】沿环形路径平移的动画

作者: 巴斯光年lip | 来源:发表于2017-06-19 15:35 被阅读0次

    用一个简单的例子来讨论,让一幅头像图片沿着环形路径动起来。它的结构代码如下:

      <div class="path">
          ![](xxx.jpg)
      </div>
    

    在考虑动画之前,先给它加上基本的样式:


    背景圆形的直径为300px

    这时候,我们就开始考虑让头像沿着外圈的橙色大圆以转圈的方式移动了:

    @keyframes spin {
      to {transform:rotate(1turn);}
    }
    .avatar {
      animation: spin 3s infinite linear;
      transform-origin: 50% 150px;   /*路径的半径:150px*/
    

    不过,此时,效果却是不够完美的,因为头像沿着环形路径转动的同时,头像自身也赞自转:


    但是我们想要的效果是:头像沿着环形进行移动,同时保持自己本来的朝向。
    有什么办法呢:用内层的变形来抵消外层的变形效果
    此时需要两层元素,给头像套上一层额外的div:
      <div class="path">
          <div class="avatar">
             ![](xxx.jpg)
          </div>
      </div>
    

    我们给头像元素设置另外一个旋转动画,让它以相反的方向自转一周,把头像的动画设置为相反的角度范围(360 - 0deg)即可:

    @keyframes spin {
     to {transform:rotate(1turn);}
    }
    @keyframes spin-reverse{
     from {transform:rotate(1turn);}
    }
    .avatar {
     animation: spin 3s infinite linear;
     transform-origin: 50% 150px;
    }
    .avatar > img {
     animation: spin-reverse 3s infinite linear;
    }
    
    终于得到我们想要的效果了

    但是,这段代码是不是还可以继续改进呢?比如说两套动画中的各个参数其实是重复了两次了。如果我们需要调整动画周期的话,还要修改两处。我们让内层动画从父元素那里继承所有的动画属性,然后把动画名字覆盖掉就可以了:

    @keyframes spin {
     to {transform:rotate(1turn);}
    }
    @keyframes spin-reverse{
     from {transform:rotate(1turn);}
    }
    .avatar {
     animation: spin 3s infinite linear;
     transform-origin: 50% 150px;
    }
    .avatar > img {
     animation: inherit;
     animation-name: spin-reverse;
    }
    

    不过,不过!我们可不可以利用一套关键帧实现两套旋转动画化?利用reverse 这个值:

    @keyframes spin {
     to {transform:rotate(1turn);}
    }
    .avatar {
     animation: spin 3s infinite linear;
     transform-origin: 50% 150px;
    }
    .avatar > img {
     animation: inherit;
     animation-direction: reverse;   /*原始动画的反向版本*/
    }
    

    这样就差不多了,但是也算不上完美,毕竟需要一层额外的元素。
    单个元素的解决方案:
    我们把头像放在圆心并以此作为起点:


    最终的代码是这样的:
    @keyframes spin {
      from {transform:  rotate(0turn)
                        translateY(-150px) translateY(50%)
                        rotate(1turn);}
      to {transform:  rotate(1turn)
                      translateY(-150px) translateY(50%)
                      rotate(0turn);}
    }
    .avatar {
      animation: spin 3s infinite linear;
    }
    

    transform-origin 可以用 translate() 来代替。
    最后仍然能得到我们想要的效果,并且代码更加简洁了。

    <u>查看demo</u>

    demo里面代码和文章中有点不一样,原因是头像图片使用的是网络上的图片,并且用css进行了缩小和剪裁。


    参考书籍:Lea Verou《CSS揭秘》

    相关文章

      网友评论

          本文标题:【过渡与动画】沿环形路径平移的动画

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