【问题标题】:Javascript timer progress barJavascript 计时器进度条
【发布时间】:2025-12-23 17:55:12
【问题描述】:

我有定时器功能,有进度条。它工作得很好,但我想制作一个流畅的进度条动画,60 FPS

function started(duration) {
    var TotalSeconds = 40;
    var documentWidth = $(document).width();
    var start = Date.now();
    var intervalSetted = null;

    function timer() {
        var diff = duration - (((Date.now() - start) / 1000) | 0);
        var seconds = (diff % 60) | 0;
        seconds = seconds < 10 ? "0" + seconds : seconds;
        $('#timer').html("00:" + seconds);
        var progresBarWidth = (seconds * documentWidth / TotalSeconds);

        $('#progress').css({
            width: progresBarWidth + 'px'
        });

        if (diff <= 0) {
            clearInterval(intervalSetted);
        }
    }

    timer();
    intervalSetted = setInterval(timer, 1000);
}

started(40);

如何实现60FPS动画?

这是我的代码演示:JSFiddle!

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    您可以使用 CSS3 动画。 我写了一些示例代码,它显示了一个进度条,该进度条使用您可以选择的持续时间进行倒计时。你也可以在动画结束时进行回调。

    CSS3 动画是硬件加速的,因此使用它时您将获得最流畅的体验。

    /*
     *  Creates a progressbar.
     *  @param id the id of the div we want to transform in a progressbar
     *  @param duration the duration of the timer example: '10s'
     *  @param callback, optional function which is called when the progressbar reaches 0.
     */
    function createProgressbar(id, duration, callback) {
      // We select the div that we want to turn into a progressbar
      var progressbar = document.getElementById(id);
      progressbar.className = 'progressbar';
    
      // We create the div that changes width to show progress
      var progressbarinner = document.createElement('div');
      progressbarinner.className = 'inner';
    
      // Now we set the animation parameters
      progressbarinner.style.animationDuration = duration;
    
      // Eventually couple a callback
      if (typeof(callback) === 'function') {
        progressbarinner.addEventListener('animationend', callback);
      }
    
      // Append the progressbar to the main progressbardiv
      progressbar.appendChild(progressbarinner);
    
      // When everything is set up we start the animation
      progressbarinner.style.animationPlayState = 'running';
    }
    
    addEventListener('load', function() {
      createProgressbar('progressbar1', '40s');
      createProgressbar('progressbar2', '30s');
      createProgressbar('progressbar3', '20s', function() {
        alert('20s progressbar is finished!');
      });
      createProgressbar('progressbar4', '10s', function() {
        alert('10s progressbar is finished!');
      });
    });
    .progressbar {
      width: 80%;
      margin: 25px auto;
      border: solid 1px #000;
    }
    .progressbar .inner {
      height: 15px;
      animation: progressbar-countdown;
      /* Placeholder, this will be updated using javascript */
      animation-duration: 40s;
      /* We stop in the end */
      animation-iteration-count: 1;
      /* Stay on pause when the animation is finished finished */
      animation-fill-mode: forwards;
      /* We start paused, we start the animation using javascript */
      animation-play-state: paused;
      /* We want a linear animation, ease-out is standard */
      animation-timing-function: linear;
    }
    @keyframes progressbar-countdown {
      0% {
        width: 100%;
        background: #0F0;
      }
      100% {
        width: 0%;
        background: #F00;
      }
    }
    <div id='progressbar1'></div>
    <div id='progressbar2'></div>
    <div id='progressbar3'></div>
    <div id='progressbar4'></div>

    【讨论】:

      【解决方案2】:

      在 jquery 中使用.animate() 方法而不是.css()

      .animate() 方法允许我们在任何物体上创建动画效果 数字 CSS 属性。唯一需要的参数是一个普通对象 CSS 属性。此对象类似于可以发送到的对象 .css() 方法,只是属性的范围比较多 限制性的。

      $('#progress').animate({
              width: progresBarWidth + 'px'
       }, 1000);
      

      Fiddle

      【讨论】: