css - 变换旋转和平移圆形图像到另一个图像内

标签 css css-animations css-transforms

我正在尝试制作太阳的动画,其外部光线缓慢旋转。我有两个图像:sun_inner 和 sun_outer。我使用绝对定位和变换:平移将内部太阳置于容器内的中心。然而,当我尝试将内部太阳(有一个笑脸)旋转几度时,它并没有沿着中心轴旋转,并且内部太阳正在上下移动。

任何帮助使内部太阳的旋转在容器内居中的帮助都是值得赞赏的!

这里有一个 fiddle 的例子:https://jsfiddle.net/4mcdLcus/

.sun-inner {
  position: absolute;
  left: 50%;
  top: 50%;
  /*
  In the animation I apply translateY(-50%) translateX(-50%) 
  to keep the inner circle centered, which is not working. 
  If I have translateY(-50%) translateX(-50%) without the rotation 
  it is centered properly
  */
  animation-name: sun_inner_rotate;
  animation-duration: 10s;
  animation-iteration-count: infinite;
  transform-origin: 50% 50%;
}
.sun-inner img {
  height: 150px;
  width: 150px;
}
.sun-outer {
  animation-name: sun_outer_rotate;
  animation-duration: 30s;
  animation-iteration-count: infinite;
  width: 300px;
  height: 300px;
}
.sun-outer img {
  width: 300px;
  height: 300px;
}
@keyframes sunrise {
  0% {
    bottom: -130vh;
  }
  100% {
    bottom: 0;
  }
}
@keyframes sun_inner_rotate {
  0% {
    transform: rotate(0deg) translateY(-50%) translateX(-50%);
    ;
  }
  33% {
    transform: rotate(12deg) translateY(-50%) translateX(-50%);
  }
  66% {
    transform: rotate(-26deg) translateY(-50%) translateX(-50%);
  }
  100% {
    transform: rotate(10deg) translateY(-50%) translateX(-50%);
  }
}
@keyframes sun_outer_rotate {
  0% {
    transform: rotate(0deg);
  }
  33% {
    transform: rotate(360deg);
  }
  66% {
    transform: rotate(-30deg);
  }
  100% {
    transform: rotate(-360deg);
  }
}
.sunContainer {
  width: 300px;
  height: 300px;
  position: relative;
  margin-left: 10%;
  margin-top: 7%;
  animation-iteration-count: 1;
  animation-name: sunrise;
  animation-duration: 1.5s;
  display: flex;
  justify-content: center;
  align-items: center;
}
<div class="sunContainer">
  <div class="sun-inner">
    <img src="https://upload.wikimedia.org/wikipedia/commons/b/b6/Compass_360_%28en%29.svg">
  </div>
  <div class="sun-outer">
    <img src="https://upload.wikimedia.org/wikipedia/commons/b/b6/Compass_360_%28en%29.svg">
  </div>
</div>

最佳答案

不,您不需要使用两个动画或对已配置的 @keyframes 执行任何其他操作。所需要做的只是为内部元素正确设置 transform-origin

内部元素最初位于父元素的 top: 50%left: 50% 处(换句话说,内部元素的左上角元素位于父元素的中心点)。然后使用 transform:translateX(-50%) translateY(-50%) 技巧将其垂直和水平居中。

因此,当您旋转元素时,应将 transform-origin 设置为 left top 以使元素围绕父级的中心点旋转。只有这样它才会保持完美居中。

.sun-inner {
  position: absolute;
  left: 50%;
  top: 50%;
  height: 150px;
  width: 150px;
  animation-name: sun_inner_rotate;
  animation-duration: 10s;
  animation-iteration-count: infinite;
  transform-origin: left top;  /* note the change */
}
.sun-inner img, .sun-outer img {
  height: 100%;
  width: 100%;
}
.sun-outer {
  animation-name: sun_outer_rotate;
  animation-duration: 30s;
  animation-iteration-count: infinite;
  width: 300px;
  height: 300px;
}
@keyframes sunrise {
  0% {
    bottom: -130vh;
  }
  100% {
    bottom: 0;
  }
}
@keyframes sun_inner_rotate {
  0% {
    transform: rotate(0deg) translateY(-50%) translateX(-50%);
  }
  33% {
    transform: rotate(12deg) translateY(-50%) translateX(-50%);
  }
  66% {
    transform: rotate(-26deg) translateY(-50%) translateX(-50%);
  }
  100% {
    transform: rotate(10deg) translateY(-50%) translateX(-50%);
  }
}
@keyframes sun_outer_rotate {
  0% {
    transform: rotate(0deg);
  }
  33% {
    transform: rotate(360deg);
  }
  66% {
    transform: rotate(-30deg);
  }
  100% {
    transform: rotate(-360deg);
  }
}
.sunContainer {
  width: 300px;
  height: 300px;
  position: relative;
  margin-left: 10%;
  margin-top: 7%;
  animation-iteration-count: 1;
  animation-name: sunrise;
  animation-duration: 1.5s;
  display: flex;
  justify-content: center;
  align-items: center;
}
<div class="sunContainer">
  <div class="sun-inner">
    <img src="https://upload.wikimedia.org/wikipedia/commons/b/b6/Compass_360_%28en%29.svg">
  </div>
  <div class="sun-outer">
    <img src="https://upload.wikimedia.org/wikipedia/commons/b/b6/Compass_360_%28en%29.svg">
  </div>
</div>

或者,您可以反转在元素上应用变换的顺序。您可以先在元素上应用 rotate,然后在旋转后的元素上应用 translateXtranslateY。这也将使其保持完美居中。 (当指定多个转换时,右侧第一个始终先执行,右侧最后一个始终最后执行)。

.sun-inner {
  position: absolute;
  left: 50%;
  top: 50%;
  height: 150px;
  width: 150px;
  animation-name: sun_inner_rotate;
  animation-duration: 10s;
  animation-iteration-count: infinite;
  transform-origin: 50% 50%;
}
.sun-inner img, .sun-outer img {
  height: 100%;
  width: 100%;
}
.sun-outer {
  animation-name: sun_outer_rotate;
  animation-duration: 30s;
  animation-iteration-count: infinite;
  width: 300px;
  height: 300px;
}
@keyframes sunrise {
  0% {
    bottom: -130vh;
  }
  100% {
    bottom: 0;
  }
}
@keyframes sun_inner_rotate { /* note the change to the order */
  0% {
    transform: translateY(-50%) translateX(-50%) rotate(0deg);
  }
  33% {
    transform: translateY(-50%) translateX(-50%) rotate(12deg);
  }
  66% {
    transform: translateY(-50%) translateX(-50%) rotate(-26deg);
  }
  100% {
    transform: translateY(-50%) translateX(-50%) rotate(10deg);
  }
}
@keyframes sun_outer_rotate {
  0% {
    transform: rotate(0deg);
  }
  33% {
    transform: rotate(360deg);
  }
  66% {
    transform: rotate(-30deg);
  }
  100% {
    transform: rotate(-360deg);
  }
}
.sunContainer {
  width: 300px;
  height: 300px;
  position: relative;
  margin-left: 10%;
  margin-top: 7%;
  animation-iteration-count: 1;
  animation-name: sunrise;
  animation-duration: 1.5s;
  display: flex;
  justify-content: center;
  align-items: center;
}
<div class="sunContainer">
  <div class="sun-inner">
    <img src="https://upload.wikimedia.org/wikipedia/commons/b/b6/Compass_360_%28en%29.svg">
  </div>
  <div class="sun-outer">
    <img src="https://upload.wikimedia.org/wikipedia/commons/b/b6/Compass_360_%28en%29.svg">
  </div>
</div>

关于css - 变换旋转和平移圆形图像到另一个图像内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37902679/

相关文章:

css - 一行中的两个元素,但不居中

html - 试图在 css 中重新创建加载 gif

javascript - 添加类来 react div onClick

html - 带边框和居中文本的透明梯形按钮

javascript - HTML/CSS/JavaScript - 模式不弹出/出现在其他东西后面?

javascript - 如何将 ngMouseMove 事件计算与我的 div 对齐

html - 过渡效果创建错误

javascript - 从平移点到中心缩放图像

html - 补偿变换移动的区域 : translate

css - IE 9 边界半径不适用于 PIE.js