CSS 3D对象不绕真轴旋转

时间:2017-08-03 05:53:37

标签: css css3 sass

正如您在下面所看到的那样,数字和标记不会与它们所在的红色圆圈轴齐平地旋转,表面上是连接的。那是为什么?

看起来在蜱开始旋转的位置和圆的实际中心之间存在某种不可见的填充,导致它们在旋转时旋转。

var x = true;

$(document).on("click", function() {
	if(x) $("#pomodoro").css("transform", "rotateX(85deg) rotateZ(540deg)");
	else $("#pomodoro").css("transform", "rotateX(85deg) rotateZ(180deg)");
	
	x=!x;
}); // provided for quick viewing of the issue
@import url("https://fonts.googleapis.com/css?family=Roboto+Mono");
html, body {
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  background-color: #bbddff;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  font-family: 'Roboto Mono', monospace;
  font-size: 16px;
  height: 100%;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  margin: 0;
  padding: 0;
  width: 100%;
}

.mark-face {
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  margin: 0;
  padding: 0;
  -webkit-transform: rotateX(-90deg) rotateY(180deg);
          transform: rotateX(-90deg) rotateY(180deg);
  -webkit-transform-origin: bottom;
          transform-origin: bottom;
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
}

.time-mark {
  height: 250px;
  left: calc(50% - 1ex);
  margin: 0;
  padding: 0;
  padding-bottom: 16px;
  position: absolute;
  text-align: center;
  top: calc(50vh - 266px);
  -webkit-transform-origin: center center;
          transform-origin: center center;
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  width: 19.2px;
}

#pomodoro {
  background-color: #ff9999;
  border-radius: 50%;
  height: 500px;
  margin: 0;
  padding: 0;
  position: absolute;
  -webkit-transform: rotateX(85deg) rotateZ(180deg);
          transform: rotateX(85deg) rotateZ(180deg);
  -webkit-transform-origin: center center;
          transform-origin: center center;
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-transition: -webkit-transform 6s linear 0s;
  transition: -webkit-transform 6s linear 0s;
  transition: transform 6s linear 0s;
  transition: transform 6s linear 0s, -webkit-transform 6s linear 0s;
  width: 500px;
}

#pomodoro-container {
  background-color: transparent;
  height: 500px;
  margin: 0;
  padding: 0;
  position: absolute;
  -webkit-transform-origin: center center;
          transform-origin: center center;
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  width: 500px;
}

#tick1 {
  -webkit-transform: rotate(6deg);
          transform: rotate(6deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick2 {
  -webkit-transform: rotate(12deg);
          transform: rotate(12deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick3 {
  -webkit-transform: rotate(18deg);
          transform: rotate(18deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick4 {
  -webkit-transform: rotate(24deg);
          transform: rotate(24deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick5 {
  -webkit-transform: rotate(30deg);
          transform: rotate(30deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick6 {
  -webkit-transform: rotate(36deg);
          transform: rotate(36deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick7 {
  -webkit-transform: rotate(42deg);
          transform: rotate(42deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick8 {
  -webkit-transform: rotate(48deg);
          transform: rotate(48deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick9 {
  -webkit-transform: rotate(54deg);
          transform: rotate(54deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick10 {
  -webkit-transform: rotate(60deg);
          transform: rotate(60deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick11 {
  -webkit-transform: rotate(66deg);
          transform: rotate(66deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick12 {
  -webkit-transform: rotate(72deg);
          transform: rotate(72deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick13 {
  -webkit-transform: rotate(78deg);
          transform: rotate(78deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick14 {
  -webkit-transform: rotate(84deg);
          transform: rotate(84deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick15 {
  -webkit-transform: rotate(90deg);
          transform: rotate(90deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick16 {
  -webkit-transform: rotate(96deg);
          transform: rotate(96deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick17 {
  -webkit-transform: rotate(102deg);
          transform: rotate(102deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick18 {
  -webkit-transform: rotate(108deg);
          transform: rotate(108deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick19 {
  -webkit-transform: rotate(114deg);
          transform: rotate(114deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick20 {
  -webkit-transform: rotate(120deg);
          transform: rotate(120deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick21 {
  -webkit-transform: rotate(126deg);
          transform: rotate(126deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick22 {
  -webkit-transform: rotate(132deg);
          transform: rotate(132deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick23 {
  -webkit-transform: rotate(138deg);
          transform: rotate(138deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick24 {
  -webkit-transform: rotate(144deg);
          transform: rotate(144deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick25 {
  -webkit-transform: rotate(150deg);
          transform: rotate(150deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick26 {
  -webkit-transform: rotate(156deg);
          transform: rotate(156deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick27 {
  -webkit-transform: rotate(162deg);
          transform: rotate(162deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick28 {
  -webkit-transform: rotate(168deg);
          transform: rotate(168deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick29 {
  -webkit-transform: rotate(174deg);
          transform: rotate(174deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick30 {
  -webkit-transform: rotate(180deg);
          transform: rotate(180deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick31 {
  -webkit-transform: rotate(186deg);
          transform: rotate(186deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick32 {
  -webkit-transform: rotate(192deg);
          transform: rotate(192deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick33 {
  -webkit-transform: rotate(198deg);
          transform: rotate(198deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick34 {
  -webkit-transform: rotate(204deg);
          transform: rotate(204deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick35 {
  -webkit-transform: rotate(210deg);
          transform: rotate(210deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick36 {
  -webkit-transform: rotate(216deg);
          transform: rotate(216deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick37 {
  -webkit-transform: rotate(222deg);
          transform: rotate(222deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick38 {
  -webkit-transform: rotate(228deg);
          transform: rotate(228deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick39 {
  -webkit-transform: rotate(234deg);
          transform: rotate(234deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick40 {
  -webkit-transform: rotate(240deg);
          transform: rotate(240deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick41 {
  -webkit-transform: rotate(246deg);
          transform: rotate(246deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick42 {
  -webkit-transform: rotate(252deg);
          transform: rotate(252deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick43 {
  -webkit-transform: rotate(258deg);
          transform: rotate(258deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick44 {
  -webkit-transform: rotate(264deg);
          transform: rotate(264deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick45 {
  -webkit-transform: rotate(270deg);
          transform: rotate(270deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick46 {
  -webkit-transform: rotate(276deg);
          transform: rotate(276deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick47 {
  -webkit-transform: rotate(282deg);
          transform: rotate(282deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick48 {
  -webkit-transform: rotate(288deg);
          transform: rotate(288deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick49 {
  -webkit-transform: rotate(294deg);
          transform: rotate(294deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick50 {
  -webkit-transform: rotate(300deg);
          transform: rotate(300deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick51 {
  -webkit-transform: rotate(306deg);
          transform: rotate(306deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick52 {
  -webkit-transform: rotate(312deg);
          transform: rotate(312deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick53 {
  -webkit-transform: rotate(318deg);
          transform: rotate(318deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick54 {
  -webkit-transform: rotate(324deg);
          transform: rotate(324deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick55 {
  -webkit-transform: rotate(330deg);
          transform: rotate(330deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick56 {
  -webkit-transform: rotate(336deg);
          transform: rotate(336deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick57 {
  -webkit-transform: rotate(342deg);
          transform: rotate(342deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick58 {
  -webkit-transform: rotate(348deg);
          transform: rotate(348deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick59 {
  -webkit-transform: rotate(354deg);
          transform: rotate(354deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}

#tick60 {
  -webkit-transform: rotate(360deg);
          transform: rotate(360deg);
  -webkit-transform-origin: bottom center;
          transform-origin: bottom center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<div id="pomodoro-container">
	<div id="pomodoro">
		<div class="time-mark" id="tick1">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick2">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick3">
			<div class="mark-face">|</div>
		</div> 
		<div class="time-mark" id="tick4">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick5">
			<div class="mark-face">5</div>
		</div>
		<div class="time-mark" id="tick6">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick7">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick8">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick9">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick10">
			<div class="mark-face">10</div>
		</div>
		<div class="time-mark" id="tick11">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick12">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick13">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick14">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick15">
			<div class="mark-face">15</div>
		</div>
		<div class="time-mark" id="tick16">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick17">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick18">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick19">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick20">
			<div class="mark-face">20</div>
		</div>
		<div class="time-mark" id="tick21">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick22">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick23">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick24">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick25">
			<div class="mark-face">25</div>
		</div>
		<div class="time-mark" id="tick26">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick27">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick28">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick29">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick30">
			<div class="mark-face">30</div>
		</div>
		<div class="time-mark" id="tick31">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick32">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick33">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick34">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick35">
			<div class="mark-face">35</div>
		</div>
		<div class="time-mark" id="tick36">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick37">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick38">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick39">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick40">
			<div class="mark-face">40</div>
		</div>
		<div class="time-mark" id="tick41">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick42">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick43">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick44">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick45">
			<div class="mark-face">45</div>
		</div>
		<div class="time-mark" id="tick46">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick47">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick48">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick49">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick50">
			<div class="mark-face">50</div>
		</div>
		<div class="time-mark" id="tick51">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick52">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick53">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick54">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick55">
			<div class="mark-face">55</div>
		</div>
		<div class="time-mark" id="tick56">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick57">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick58">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick59">
			<div class="mark-face">|</div>
		</div>
		<div class="time-mark" id="tick60">
			<div class="mark-face">60</div>
		</div>
	</div>
</div>

为方便起见,您可以找到上述代码段here的CodePen。

2 个答案:

答案 0 :(得分:1)

即使我不是3D专家,我也能说出我在这里看到的内容。你的圈子对齐有问题。红圈的起源和标记圆的起源不在同一个地方。实际上,X和Y对齐都是错误的,因此time-mark类需要进行一些小的修改。

像这样修复X对齐(不是完美的解决方案)。

left: calc(50% - 9.6px);

像这样修复Y对齐

top: calc(50% - 266px);

这里的主要问题是 vh 单位,它是视口高度的百分比,而不是容器的高度。将其更改为百分数,然后修复top属性(Y)对齐。我不明白你如何计算left,但也需要调整。

无论如何,为了获得对齐的视觉辅助,只需将视角从85改为例如。 25,将一些背景颜色设置为标记并禁用{comment} backface-visibility mark-face类的属性。

下方图片的左侧显示了您的代码的可能结果。在右侧,您可以看到我在应用我提到的更改后得到的结果。

enter image description here

这并不完美,但非常接近完美。当然,如果我一开始就做对了你想做的事。

要点是将两个圆圈的原点放在同一个地方。否则,对象围绕两个圆心之间的点旋转,这就是旋转看起来扭曲的原因。

答案 1 :(得分:1)

检查你的路线:

enter image description here

这就是为什么在轮换时它似乎偏离了中心点,但事实并非如此。你的div没有正确对齐。

尝试更改

top: calc(50vh - 266px);

top: calc(50% - 266px);

https://codepen.io/anon/pen/YxGYbj