如何平滑 setInterval 动画?

How to smooth out setInterval animation?

一位客户要求为他们的 bootstrap3 网站提供客户徽标的旋转器。徽标大小不一致,旋转器应自动无限循环旋转。

这是CodePen

动画不流畅。特别是在 FireFox 上。有没有更有效的方法来处理动画?

HTML

<div id="clients_carousel" class="col-md-12 hidden-xs hidden-sm">
  <ul id="scroller" class="clearfix">
    <li><img class="img-responsive" src="http://www.cloudaccess.com/wp-content/uploads/2015/01/keesler.png" alt=""></li>
    <li><img class="img-responsive" src="http://www.cloudaccess.com/wp-content/uploads/2015/07/wcd.png" alt=""></li>
    <li><img class="img-responsive" src="http://www.cloudaccess.com/wp-content/uploads/2015/07/viva.png" alt=""></li>
    <li><img class="img-responsive" src="http://www.cloudaccess.com/wp-content/uploads/2015/07/magma.png" alt=""></li>
    <li><img class="img-responsive" src="http://www.cloudaccess.com/wp-content/uploads/2015/07/safe.png" alt=""></li>
    <li><img class="img-responsive" src="http://www.cloudaccess.com/wp-content/uploads/2015/02/2ndimage.png" alt=""></li>
    <li><img class="img-responsive" src="http://www.cloudaccess.com/wp-content/uploads/2015/02/balboa1.png" alt=""></li>
    <li><img class="img-responsive" src="http://www.cloudaccess.com/wp-content/uploads/2015/02/smile.png" alt=""></li>
    <li><img class="img-responsive" src="http://www.cloudaccess.com/wp-content/uploads/2015/02/nfib.png" alt=""></li>
    <li><img class="img-responsive" src="http://www.cloudaccess.com/wp-content/uploads/2015/02/dental1-e1424199396391.png" alt=""></li>
  </ul>
</div>

CSS

#clients_carousel {
  position: relative;
  margin: 0px auto;
  padding: 0px;
  width: 100%;
  height: 40px;
  overflow: hidden;
}

#clients_carousel ul {
  position: absolute;
  list-style-type: none;
  top: 0px;
  left: 0px;
  height: 40px;
  margin: 0px;
  padding: 0px;
  width: 9999px;
}

#clients_carousel ul li {
  float: left;
  position: relative;
  margin: 0px;
  height: 40px;
  padding: 0px 15px;
}

#clients_carousel ul li img {
  height: 40px !important;
  width: auto !important;
}

JS

setInterval(function() {
    if (!$('#clients_carousel ul').is(':animated')) {
      var fWidth = parseInt($('#clients_carousel ul li:first').outerWidth(true), 10);
      var lIndent = parseInt($('#clients_carousel ul').css("left"), 10);
      if (fWidth < Math.abs(lIndent)) {
        $('#clients_carousel ul li:last').after($('#clients_carousel ul li:first'));
        var newIndent = lIndent + fWidth;
        $('#clients_carousel ul').css('left', newIndent + 'px');
        lIndent = newIndent;
      }
      $('#clients_carousel ul').animate({
        left: lIndent - 5
      }, 40, "linear");
    }
  }, 41);

我当然没有查看您的所有代码,只是查看了 javascript 并更改了执行间隔。简而言之,我调整了数学,​​它似乎有所帮助。您可以调整更多以微调它。另外,请确保您的文件尽可能小以便加载。那是 web dev 101,但我想说出来以防万一。

setInterval(function() {
    if (!$('#clients_carousel ul').is(':animated')) {
      var fWidth = parseInt($('#clients_carousel ul li:first').outerWidth(true), 10);
      var lIndent = parseInt($('#clients_carousel ul').css("left"), 10);
      if (fWidth < Math.abs(lIndent)) {
        $('#clients_carousel ul li:last').after($('#clients_carousel ul li:first'));
        var newIndent = lIndent + fWidth;
        $('#clients_carousel ul').css('left', newIndent + 'px');
        lIndent = newIndent;
      }
      $('#clients_carousel ul').animate({
        left: lIndent - 2
      }, 50, "linear");
    }
  }, .001);

动画在 60 fps(每秒帧数)时效果最佳。 60fps 是每 ~16.7ms 更新一次。

考虑到这一点,您应该为 setInterval 使用 16 或 17。您也可以考虑使用 requestAnimationFrame 来驱动动画回调(如果您需要旧版浏览器支持,github 上的某处有一个 polyfill)。