Javascript CSS旋转不准确

时间:2018-03-13 23:19:55

标签: javascript css rotation

我一直在通过CSS和Javascript制作一个小模拟时钟图标,并遇到了一个奇怪的图形故障。

function r() {
  var vwMin, r;
  if (window.innerWidth < window.innerHeight) {
    vwMin = window.innerWidth;
  } else {
    vwMin = window.innerHeight;
  }
  r = vwMin * .0225 - 1;
  if (r < 0) {
    r += 1;
  }
  document.getElementById("min").style.transformOrigin = "50% calc(100% - " + r + "px)";
  document.getElementById("min").style.bottom = "calc(50% - " + r + "px)";
  document.getElementById("hr").style.transformOrigin = "50% calc(100% - " + r + "px)";
  document.getElementById("hr").style.bottom = "calc(50% - " + r + "px)";
}

function clock() {
  r();
  var date = new Date(),
      hours;
  if (date.getHours() > 12) {
    hours = ((date.getHours() - 12) / 12) + (date.getMinutes() / 720);
  } else {
    hours = (date.getHours() / 12) + (date.getMinutes() / 720);
  }
  var mins = date.getMinutes() / 60;
  var hours = .5;
  var mins = 0;
  document.querySelector('#hr').style.transform = 'rotate(' + hours + 'turn)';
  document.querySelector('#min').style.transform = 'rotate(' + mins + 'turn)';
}

$(document).ready(function() {
  clock();
  window.onresize = function(event) {
    r();
  };
});
#clock {
  position: absolute;
  border: solid;
  width: 70vmin;
  height: 70vmin;
  border-radius: 50%;
  border-width: 6vmin;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

#clock>* {
  position: absolute;
  left: 50%;
  margin-left: -2.25vmin;
  border: 2.25vmin solid;
  border-radius: 2.25vmin;
  background: black;
}

#min {
  height: 25vmin;
}

#hr {
  height: 16vmin;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clock">
  <div id="hr"></div>
  <div id="min"></div>
</div>

脚本找到wherr到transform-origin的位置并偏移div,使得时钟指针始终干净地交叉。但是,CSS旋转似乎没有在div的精确水平中心旋转。例如,如果我手动将时钟设置为6:00,则分针将被清洁,而旋转的时针将会模糊。

发生了什么,以及如何解决这个问题(如果可能的话)?

2 个答案:

答案 0 :(得分:0)

变换对于子像素移动可能会非常奇怪,即使不应该有。您通常可以通过设置select cast(sum(TimeFullInSeconds) / 3600 as varchar(2)) + ':' + right('0' + cast(sum(TimeFullInSeconds) % 3600 / 60 as varchar(2)), 2) + ':' + right('0' + cast(sum(TimeFullInSeconds) % 60 as varchar(2)), 2) as TimeFull, /* assumes same day */ 100 - sum(TimeFullInSeconds) * 100 / datediff(ss, @StartTime, @EndTime) as "Downtime%" from ( select datediff(ss, EventTime, ( select min(EventTime) from EventLog l2 where l2.EventTime > l.EventTime and l2.EventID = 1201 and Description like left(l.Description, 6) + ' Full PE%') ) as TimeFullInSeconds from EventLog l where EventID = 1200 and Description like 'Lane _ Full PE%' ) t 来解决此问题,看起来它适用于您的情况。由于您已经在修改内联translateZ(0),因此只需将Z添加到其中:

transform

编辑:

有趣的是,这似乎实际上使得时针模糊有时基于屏幕尺寸 - 在我的全屏幕片段中工作得很好但在微小的片段盒中有点模糊

 document.querySelector('#hr').style.transform = 'rotate(' + hours + 'turn) translateZ(0)';
 document.querySelector('#min').style.transform = 'rotate(' + mins + 'turn) translateZ(0)';
function r() {
  var vwMin, r;
  if (window.innerWidth < window.innerHeight) {
    vwMin = window.innerWidth;
  } else {
    vwMin = window.innerHeight;
  }
  r = vwMin * .0225 - 1;
  if (r < 0) {
    r += 1;
  }
  document.getElementById("min").style.transformOrigin = "50% calc(100% - " + r + "px)";
  document.getElementById("min").style.bottom = "calc(50% - " + r + "px)";
  document.getElementById("hr").style.transformOrigin = "50% calc(100% - " + r + "px)";
  document.getElementById("hr").style.bottom = "calc(50% - " + r + "px)";
}

function clock() {
  r();
  var date = new Date(),
    hours;
  if (date.getHours() > 12) {
    hours = ((date.getHours() - 12) / 12) + (date.getMinutes() / 720);
  } else {
    hours = (date.getHours() / 12) + (date.getMinutes() / 720);
  }
  var mins = date.getMinutes() / 60;
  
  hours = 6;
  mins = 0;
  document.querySelector('#hr').style.transform = 'rotate(' + hours + 'turn)';
  document.querySelector('#min').style.transform = 'rotate(' + mins + 'turn) translateZ(0)';
}

$(document).ready(function() {
  clock();
  window.onresize = function(event) {
    r();
  };
});
#clock {
  position: absolute;
  border: solid;
  width: 70vmin;
  height: 70vmin;
  border-radius: 50%;
  border-width: 6vmin;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

#clock>* {
  position: absolute;
  left: 50%;
  border: 2.25vmin solid;
  border-radius: 2.25vmin;
  background: black;
}

#min {
  height: 25vmin;
}

#hr {
  height: 16vmin;
}

答案 1 :(得分:0)

我最终提出的解决方案是使用SVG而不是使用div进行返工。我认为发生的事情是,由于手div的中心几乎总是在一个子像素上,大多数浏览器会别名或舍入到最近的像素,从而导致时钟指针在旋转时被分离。 SVG允许人们从解决问题的不同来源中抽取。以下是解决此问题的代码:

HTML

<html>
  <body>
    <div class="analog-clock">
      <svg width="100vmin" height="100vmin" viewBox="-50 -50 100 100">
        <circle id="clock-face" cx="0" cy="0" r="45"/>
        <line id="h-hand" x1="0" y1="0" x2="0" y2="-22"/>
        <line id="m-hand" x1="0" y1="0" x2="0" y2="-33"/>
      </svg>
    </div>
  </body>
</html>

CSS

html {
  overflow: hidden;
}
.analog-clock{
  position: absolute;
  width: 100vmin;
  height: 100vmin;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
#clock-face{
  stroke: black;
  stroke-width: 6;
  fill: white;
}
#h-hand, #m-hand{
  stroke: black;
  stroke-linecap: round;
  stroke-width: 4.5;
}

JS

function clock() {
  var d = new Date();
  function setAttr(id,deg) {
    document.getElementById(id).setAttribute('transform', 'rotate(' + deg + ', 0, 0)');
  };
  setAttr('h-hand', 30 * ((d.getHours() % 12) + d.getMinutes() / 60));
  setAttr('m-hand', 6 * d.getMinutes());
}

window.onload = clock();
setInterval(function() {
  clock();
}, 1000);