让元素绕一个圆形的路径运动

104 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

了解transform-origin

其默认值为元素的中心 所以在不修改transform-origin的情况下 设置rotate 元素是会自旋转

如 transform-origin:0% 0%

1663574460667-d6eff7a5-8458-41ad-9baf-8946a12b4ba7.png

div {
            margin: 100px auto;
            width: 100px;
            height: 100px;
            background-color: #ffbb33;
            transform-origin: 0px 0px;
            /* 等价于
            transform-origin: 0% 0%;
            transform-origin: left top; */
            animation: spin-45 3s infinite linear;
        }
        @keyframes spin-45 {
            to{ 
                transform: rotate(45deg);
            }
        }


查看运行效果:codepen.io/liujing0921…

本例的 transform-origin: 50% 150px;效果如下

1663574719071-e666b201-890f-430e-a232-ee1abe1cc3cf.png

实现步骤:

1.改变元素变形的原点-修改transform-origin

2.设置旋转动画

<div class="path">
      <div class="inner">1</div>
    </div>
.path {
        width: 300px;
        height: 300px;
        padding: 20px;
        border-radius: 50%;
        background: #fb3;
        margin: 50px auto;
      }
      .inner {
        width: 50px;
        height: 50px;
        margin: 0 auto;
        border-radius: 50%;
        background-color: antiquewhite;
        text-align: center;
        line-height: 50px;
        animation: spin 3s infinite linear;
        transform-origin: center 150px;
      }
      @keyframes spin {
    to { transform: rotate(1turn); }
}

查看运行效果:codepen.io/liujing0921…

文本始终保持不变

解决方法:小圆球绕圆旋转的同时 让 文本内容 反向旋转

    <div class="path">
      <div class="inner"><div class="content">1</div></div>
    </div>
 .path {
        width: 300px;
        height: 300px;
        padding: 20px;
        border-radius: 50%;
        background: #fb3;
        margin: 50px auto;
      }
      .inner {
        width: 50px;
        height: 50px;
        margin: 0 auto;
        border-radius: 50%;
        background-color: antiquewhite;
        text-align: center;
        line-height: 50px;
        animation: spin 3s infinite linear;
        transform-origin: 50% 150px;
      }
      .content{
        /* 继承父类的动画  */
        animation: inherit;
         /* animation-direction 用于设置动画是否反向播放*/
        animation-direction: reverse;
      }
      @keyframes spin {
    to { transform: rotate(1turn); }
}

查看运行效果:codepen.io/liujing0921…

该方法 需要再创建一个盒子 还可以方法简化吗? 通过一个盒子来实现

首先要了解 transform-origin是一个语法糖 每个transform-origin可以模拟两次translate()

transform: rotate(30deg); 
transform-origin: 100px 50px;

等价于

transform: translate(100px 50px)
rotate(30deg) 
translate(-100px, -50px);
transform-origin: 0 0;

所以代码可以改写为

 <div class="path">
      <div class="inner">1</div>
    </div>
.path {
        width: 300px;
        height: 300px;
        padding: 20px;
        border-radius: 50%;
        background: #fb3;
        margin: 50px auto;
      }
      .inner {
        width: 50px;
        height: 50px;
        margin: 0 auto;
        border-radius: 50%;
        background-image: linear-gradient(to right , #7A88FF, #7AFFAF);
        text-align: center;
        line-height: 50px;
        animation: spin 3s infinite linear;
      }
      @keyframes spin {
        from {
          transform: translate(50%, 150px) rotate(0turn) translate(-50%, -150px)
            
            translate(50%, 50%) rotate(1turn) translate(-50%, -50%);
        }
        to {
          transform: translate(50%, 150px) rotate(1turn) translate(-50%, -150px)
            
            translate(50%, 50%) rotate(0turn) translate(-50%, -50%);
        }
      }

查看运行效果:codepen.io/liujing0921…

也就是让小圆在绕圆环轨迹运动的同时 让小圆反向旋转