为旋转元素添加了过渡属性,但它在0度向后移动?

时间:2018-12-12 07:41:43

标签: javascript

我正在构建一个css3时钟,并对其秒针进行了过渡,但它在0deg处回了圈?我试图添加一个一次性事件侦听器,以在达到360度时删除过渡,以使秒针立即从360跳到起点,但这没有用。除了无限增加度数之外,有什么方法可以纠正此问题。

var secHand = document.querySelector('div div:first-child');
var minHand = document.querySelector('div:nth-child(2)');
var hourHand = document.querySelector('div:nth-child(3)');
var myVar = setInterval(myTimer, 1000);

function myTimer() {
  var d = new Date();
  function updateHands() {
    secHand.style.transform = `rotate(${d.getSeconds()*6}deg)`;
    minHand.style.transform = `rotate(${d.getMinutes()*6}deg)`;
    hourHand.style.transform = `rotate(${d.getHours()*(360/12) + d.getMinutes()*6*6/360}deg)`;
  }
  // I tried this but I don't know how to make it work properly.
  if (d.getSeconds() == 0) {
    secHand.style.transform = 'rotate(360deg)';
    secHand.addEventListener('transitionend', function(e){
      e.target.removeEventListener(e.type, arguments.callee);
      this.style.transition = 'transform 0s';
      updateHands();
      this.style.transition = 'transform 0.5s';
    })
  }
  else updateHands();
}
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: url('https://stmed.net/sites/default/files/sky-wallpapers-28043-2711012.jpg'), linear-gradient(to bottom, #1e528e 0%, #265889 50%, #9da671 100%);
  background-repeat: no-repeat;
  background-attachment: fixed;

}
div {
  border-radius: 50%;
}
body > div {
  border: 20px solid white;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  margin: auto;
}
div div:first-child {
  margin: auto;
  width: 3px;
  background-color: black;
  height: 49%;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 50%;
  transform: rotate(180deg);
  transform-origin: 50% 100%;
  transition: transform 0.5s;
  transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1) !important;
}
div:nth-child(2) {
  width: 5px;
  background-color: black;
  height: 46%;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 50%;
  margin: auto;
  transform: rotate(360deg);
  transform-origin: 50% 100%;
  transition: transform 2s;
  
}
div:nth-child(3) {
  width: 5px;
  background-color: black;
  height: 43%;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 50%;
  margin: auto;
  transform: rotate(360deg);
  transform-origin: 50% 100%;
  transition: transform 3s;
  
}
<div>
  <div></div>
  <div></div>
  <div></div>
</div>
观看摘要,当秒针到达60秒时,它会向后旋转。

3 个答案:

答案 0 :(得分:0)

Id进行回调,例如类似

var secHand = document.querySelector('div div:first-child');
var minHand = document.querySelector('div:nth-child(2)');
var hourHand = document.querySelector('div:nth-child(3)');
var myVar = setInterval(myTimer, 1000);

function myTimer() {
  var d = new Date();
  function updateHands() {
    secHand.style.transform = `rotate(${d.getSeconds()*6}deg)`;
    minHand.style.transform = `rotate(${d.getMinutes()*6}deg)`;
    hourHand.style.transform = `rotate(${d.getHours()*(360/12) + d.getMinutes()*6*6/360}deg)`;
  }
  // I tried this but I don't know how to make it work properly.
  if (d.getSeconds() == 0) {
    secHand.style.transform = 'rotate(360deg)';
    secHand.addEventListener('transitionend', function(e){
      e.target.removeEventListener(e.type, arguments.callee);
      this.style.transition = 'transform 0s';
      var localyRechunk = function(callBack) {
        updateHands();
        callBack();
      };

      localyRechunk(function() {
          console.log('give back the transition');
      });

    })
  }
  else updateHands();
}

也做了一个小提琴:https://jsfiddle.net/3qvyxmdu/我只是做了一点,所以它会给人过渡效果。但是简单的回调。您可以in hare来了解它。

答案 1 :(得分:0)

我建议使用计数器来跟踪可能发生的旋转,并使用该数字来判断下一次真正的旋转是什么。

var secHand = document.querySelector('div div:first-child');
var minHand = document.querySelector('div:nth-child(2)');
var hourHand = document.querySelector('div:nth-child(3)');
var myVar = setInterval(myTimer, 1000);
var secRounds = 0;

function myTimer() {
  var d = new Date();
  function updateHands() {
    secHand.style.transform = `rotate(${d.getSeconds()*6 + 360*secRounds }deg)`;
    minHand.style.transform = `rotate(${d.getMinutes()*6}deg)`;
    hourHand.style.transform = `rotate(${d.getHours()*(360/12) + d.getMinutes()*6*6/360}deg)`;
  }
  // I tried this but I don't know how to make it work properly.
  if (d.getSeconds() == 0) {
    secRounds ++;
  }
 updateHands();
}
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: url('https://stmed.net/sites/default/files/sky-wallpapers-28043-2711012.jpg'), linear-gradient(to bottom, #1e528e 0%, #265889 50%, #9da671 100%);
  background-repeat: no-repeat;
  background-attachment: fixed;

}
div {
  border-radius: 50%;
}
body > div {
  border: 20px solid white;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  margin: auto;
}
div div:first-child {
  margin: auto;
  width: 3px;
  background-color: black;
  height: 49%;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 50%;
  transform: rotate(180deg);
  transform-origin: 50% 100%;
  transition: transform 0.5s;
  transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1) !important;
}
div:nth-child(2) {
  width: 5px;
  background-color: black;
  height: 46%;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 50%;
  margin: auto;
  transform: rotate(360deg);
  transform-origin: 50% 100%;
  transition: transform 2s;
  
}
div:nth-child(3) {
  width: 5px;
  background-color: black;
  height: 43%;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 50%;
  margin: auto;
  transform: rotate(360deg);
  transform-origin: 50% 100%;
  transition: transform 3s;
  
}
<div>
  <div></div>
  <div></div>
  <div></div>
</div>


答案 2 :(得分:0)

我相信这就是您想要的,这可以通过暂时禁用过渡来实现。我还意识到,您只想向前旋转,所以这只会使秒针前进6度。

当分钟改变时,它从354旋转到360度,然后从0旋转到6度。您不会看到它从360变为0,因为这样会禁用过渡。

禁用过渡的说明如下: What is the cleanest way to disable CSS transition effects temporarily?

我懒得用这三只手来实现这一点,而且我认为无论如何,从这个简化的示例中您会更容易理解这个想法。

var secHand = document.querySelector('div div:first-child');
setInterval(myTimer, 1000);

function myTimer() {
    var d = new Date();

    // Advance seconds hand 6 degrees each second
    var oldDeg = d.getSeconds()*6;
    var newDeg = oldDeg + 6;
    console.log(`Transitioning from ${oldDeg} to ${newDeg}`);

    // Snap to old rotation by disabling transition
    secHand.classList.add('notransition');
    secHand.style.transform = `rotate(${oldDeg}deg)`;
    secHand.offsetHeight; // Trigger reflow

    // Transition to new rotation
    secHand.classList.remove('notransition');
    secHand.style.transform = `rotate(${newDeg}deg)`;
}
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: url('https://stmed.net/sites/default/files/sky-wallpapers-28043-2711012.jpg'), linear-gradient(to bottom, #1e528e 0%, #265889 50%, #9da671 100%);
  background-repeat: no-repeat;
  background-attachment: fixed;

}
div {
  border-radius: 50%;
}
body > div {
  border: 20px solid white;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  margin: auto;
}
div div:first-child {
  margin: auto;
  width: 3px;
  background-color: black;
  height: 49%;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 50%;
  transform: rotate(180deg);
  transform-origin: 50% 100%;
  transition: transform 0.5s;
  transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1) !important;
}

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  transition: none !important;
}
<div>
  <div></div>
</div>