【问题标题】:Transform rotate and translate of circle img inside another img在另一个img中变换圆img的旋转和平移
【发布时间】:2016-06-19 14:30:10
【问题描述】:

我正在尝试通过外部光线缓慢旋转来为太阳设置动画。我有两个图像:sun_inner 和 sun_outer。我使用绝对定位和 transform:translate 将容器内的内部太阳居中。但是,当我尝试将内太阳(有一个笑脸)旋转几度时,它并没有沿着中心轴旋转,而是内太阳上下移动。

感谢任何帮助使内部太阳的旋转在容器内居中!

举个例子,这里有一个小提琴: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>

【问题讨论】:

  • @Harry - 是的,它有效,感谢您帮助解释 transform-origin,这是缺失的部分! jsfiddle.net/mxf3jkxt/1

标签: css css-animations css-transforms


【解决方案1】:

不,您不需要使用两个动画或对已配置的@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>

【讨论】:

  • 转换原点更改有效,但与您展示的第二种技术相比,它看起来像 1 px(下面的 jsfiddle)。再次感谢您的回答!! jsfiddle.net/b95k146n/6
  • 这很有趣@RonI。对我来说,两个 sn-ps 的输出看起来都一样。您是否也看到this fiddle 中的问题?也许有一些浏览器问题。我正在使用 Chrome v53.0 dev-m。
  • 那个小提琴看起来不错,我看到你使用了 transform-origin。这是我指的小提琴(1 px off)。我截取了两者的屏幕截图并在 Photoshop 中将它们炸毁以验证,它比另一个低 1px。但是,我无法在评论中添加屏幕截图。
  • @RonI:接下来几天我的日程安排很紧。我会在周末看看它并让你知道。顺便说一句,您是否错过了在评论中添加小提琴链接?
  • @RonI:我只是快速浏览了一下,您还没有像我的小提琴那样将heightwidth.sun-inner img 移动到.sun-inner。这种错位正是我做出这种改变的原因。未对齐的原因是因为.sun-inner 没有固定的高度/宽度,它会扩展以适应img,并且由于某种奇怪的原因,它的尺寸变成了 150 x 154(您可以在开发控制台中查看)。这 4px 的额外高度是错位的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多