CSS和jQuery模拟时钟-平滑动画

CSS and jQuery Analog clock - smooth animation

本文关键字:平滑 动画 时钟 模拟 jQuery CSS      更新时间:2023-09-26

我的CSS3/jQuery模拟时钟有一个小问题。

对于每一步,时钟指针,它是非常困难的。相反,我希望运动/动画是平滑的。我已经试过使用transition: all .1s,但是它搞砸了,当时钟指针到达顶部时。

我用transform: rotate()旋转每只手。每次移动,旋转6度。

也许解决方案是,不只是旋转指针,每6度每秒,分和小时,它每1/6秒旋转1度,秒针每10秒旋转一次,时针每10分钟旋转一次。我认为它可以创建一个更流畅的手工动画,但我不知道如何做到这一点。

这是我的JavaScript代码:
$(function() {
      setInterval( function() {
      var seconds = new Date().getSeconds();
      var sdegree = seconds * 6;
      var srotate = "rotate(" + sdegree + "deg)";
      $("#sec").css({ "transform": srotate });
      }, 1000 );
      setInterval( function() {
      var hours = new Date().getHours();
      var mins = new Date().getMinutes();
      var hdegree = hours * 30 + (mins / 2);
      var hrotate = "rotate(" + hdegree + "deg)";
      $("#hour").css({ "transform": hrotate});
      }, 1000 );
      setInterval( function() {
      var mins = new Date().getMinutes();
      var mdegree = mins * 6;
      var mrotate = "rotate(" + mdegree + "deg)";
      $("#min").css({"transform" : mrotate });
      }, 1000 );
});

jsFiddle演示

希望你能理解这个问题,并能帮助我:)

为手设置一个线性过渡:

#clock div {
    -moz-transition: all 1s linear;
    -webkit-transition: all 1s linear;
    -o-transition: all 1s linear;
    transition: all 1s linear;
}

为了避免手反转到零的奇怪行为,你应该将JS更改为毫秒级。这样旋转值(度)只会增加。CSS旋转没有问题:

$(function() { 
     var i=0;
    setInterval( function() {
        //get time since midnight in milliseconds
         var now = new Date(),
        then = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate(),
        0,0,0),
        mil = now.getTime() - then.getTime(); // difference in milliseconds
          var h = (mil/(1000*60*60));
          var m = (h*60);
          var s = (m*60);
          //console.log(h+":"+m+":"+s);   

      var sdegree = (s * 6);
      var srotate = "rotate(" + sdegree + "deg)";  
      $("#sec").css({ "transform": srotate });
      var hdegree = h * 30 + (h / 2);
      var hrotate = "rotate(" + hdegree + "deg)";
      $("#hour").css({ "transform": hrotate});
      var mdegree = m * 6;
      var mrotate = "rotate(" + mdegree + "deg)";      
      $("#min").css({ "transform" : mrotate });
         if(i>0){
             $("#clock").addClass("transform");       
         }
         i++;
      }, 1000 );
});
http://jsfiddle.net/FHNJf/10/

更新:

这是一个纯JS的解决方案,可以让你的手干净利落。它使用requestAnimationFrame来计时循环,因为它不使用CSS转场,所以它不会遭受那种奇怪的行为,当你将焦点返回到浏览器选项卡时,手必须"赶上"。

//use requestAnimationFrame for smoothness (shimmed with setTimeout fallback)
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
              window.setTimeout(callback, 1000 / 60);
          };
})();
//initialize the clock in a self-invoking function
(function clock(){ 
    var hour = document.getElementById("hour"),
        min = document.getElementById("min"),
        sec = document.getElementById("sec");
    //set up a loop
    (function loop(){
        requestAnimFrame(loop);
        draw();
    })();
    //position the hands
    function draw(){
        var now = new Date(),//now
            then = new Date(now.getFullYear(),now.getMonth(),now.getDate(),0,0,0),//midnight
            diffInMil = (now.getTime() - then.getTime()),// difference in milliseconds
            h = (diffInMil/(1000*60*60)),//hours
            m = (h*60),//minutes
            s = (m*60);//seconds
        //rotate the hands accordingly
        sec.style.webkitTransform = "rotate(" + (s * 6) + "deg)";
        hour.style.webkitTransform = "rotate(" + (h * 30 + (h / 2)) + "deg)";
        min.style.webkitTransform = "rotate(" + (m * 6) + "deg)";
    } 
})();
http://jsfiddle.net/FHNJf/13/

您只需要指定hand元素的转换持续时间。试试这个:

#clock div {
    -webkit-transition-duration: 1.0s;
    -moz-transition-duration: 1.0s;
    -o-transition-duration: 1.0s;
    transition-duration: 1.0s;
}

更新小提琴

你想让第二只手(和其他所有的手)移动顺利吗?尝试将以下css添加到#secdiv:

[prefix-]transition: all 1.00s linear 0.0s;

这只会让你在那里的方式的一部分,你将不得不聪明地告诉你如何告诉变换旋转,因为它可能最终导致bug在12点标记。

不管它的价值是什么,你可能有一个单独的setInterval(...)创建一个单独的new Date(),并相应地更新手