【问题标题】:Rotate child element around the parent element with transition使用过渡围绕父元素旋转子元素
【发布时间】:2015-12-28 01:28:08
【问题描述】:

我有一个 CSS 动画,我试图让子元素围绕父元素旋转一定的度数。但是我不能让它围绕父原点旋转,也不能让它从正确的半径旋转,它似乎围绕着一个看不见的小圆圈旋转。

下面是损坏的动画。我该如何解决这个问题?

.center-circle {
    top:100px;
    left:100px;
    width: 180px;
    height: 180px;
  
    border:1px solid black;
    border-radius: 100%;
    position: relative;    
}
.quarter-circle {
    width:65px;
    height:65px;
    position: absolute;
    top: 0%;
    left: 50%;
    border:1px solid #F28B46;
    border-radius: 100%;
    animation: spin-back 2s ease-in-out;
    -webkit-transform-origin: 0% 50%;
}
@-webkit-keyframes spin-back {
    0% {
        transform:rotate(-120deg);
    }
    100% {
        transform:rotate(0deg);
    }
}
<div class="center-circle">
    <div class="quarter-circle"></div>
</div>

JSFiddle

【问题讨论】:

  • 你想像this一样吗?
  • 你的想法是对的,虽然我想要黑色圆圈之外的整个橙色圆圈,就好像它围绕它运行一样。像行星和月亮一样思考。

标签: css css-transitions css-animations


【解决方案1】:

可以通过在开始时将较小的圆设置在父圆之外(使用topleft)然后将transform-origin 设置为父圆的半径+小圆的半径来实现这种类似轨道的动画。这是因为旋转中心应该在大圆的中心,小圆的左上角偏移它们的半径的组合距离。

当我们将transform-origin 设置为0% 50% 时,50% 是小圆圈高度的一半(即 32.5 像素),因此旋转直径和旋转发生在一个较小的假想圆圈周围。而我们实际需要的是让它围绕更大的圆进行动画处理,因此想象的圆半径必须更高。

.center-circle {
  position: relative;
  top: 100px;
  left: 100px;
  width: 180px;
  height: 180px;
  border: 1px solid black;
  border-radius: 100%;
}
.quarter-circle {
  position: absolute;
  width: 65px;
  height: 65px;
  top: -32.5px;
  left: -32.5px;
  border: 1px solid #F28B46;
  border-radius: 100%;
  transform: rotate(-45deg);
  animation: spin-back 2s ease-in-out forwards;
  transform-origin: 122.5px 122.5px;
}
@keyframes spin-back {
  0% {
    transform: rotate(-45deg);
  }
  100% {
    transform: rotate(135deg);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="center-circle">
  <div class="quarter-circle"></div>
</div>

下面的 sn-p 响应更快(在我看来更好一点),但它仍然需要将父级半径硬编码到 transform-origin 中。在这个 sn-p 中,小圆的左上角与父中心圆的偏移量略有不同(与之前的 sn-p 相比),因此transform-origin 的计算也不同。

.center-circle {
  position: relative;
  top: 100px;
  left: 100px;
  width: 180px;
  height: 180px;
  border: 1px solid black;
  border-radius: 100%;
}
.quarter-circle {
  position: absolute;
  width: 80px;
  height: 80px;
  top: 50%;
  left: 0%;
  border: 1px solid #F28B46;
  border-radius: 100%;
  transform: translateX(-100%) translateY(-50%) rotate(0deg);
  animation: spin-back 2s ease-in-out forwards;
  transform-origin: calc(100% + 90px) 40px; /* 90px is radius of the parent */
}
@keyframes spin-back {
  0% {
    transform: translateX(-100%) translateY(-50%) rotate(0deg);
  }
  100% {
    transform: translateX(-100%) translateY(-50%) rotate(180deg);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="center-circle">
  <div class="quarter-circle"></div>
</div>

【讨论】:

  • 有没有办法让它以给定的角度开始并以给定的角度结束?我的最终目标是让它旋转一定量,但不是无限重复,所以它是一个一次性动画围绕一定范围旋转。
  • 是的@Dave。我修改了旋转和迭代计数(无限),只是为了让动画更长时间可见。否则,它们可能与您的原始代码中的相同。只有定位和变换原点设置需要更改。
  • 所以如果我希望它从 9 点钟位置开始并旋转到 3 点钟位置,也就是 180 度,我必须改变什么值才能让它到达那个起始位置?
  • @Dave:小圆圈的原始位置是 45 度角(大约 10:30),所以你必须从(-45 度)旋转到(135 度)。
  • 啊,谢谢 :) 有点混乱!所以 (135deg) 不是“从起始位置旋转的总度数”,而是实际上是圆上的固定位置。
猜你喜欢
  • 2018-08-26
  • 2011-08-22
  • 1970-01-01
  • 2018-04-14
  • 2020-04-07
  • 1970-01-01
  • 2021-11-26
  • 2013-07-12
相关资源
最近更新 更多