【问题标题】:How to achieve smooth CSS animation on CSS width change?如何在 CSS 宽度变化时实现平滑的 CSS 动画?
【发布时间】:2019-08-18 20:57:19
【问题描述】:

我正在制作自己的进度条,该进度条将在 5 分钟到 1 秒的不同时间段内填满。我的想法是:

  1. 我有一个栏,每 x 秒将 CSS 宽度设置为 0%
  2. 然后我使用 JS 将条形宽度增加 1%。

它的工作原理是这样的:https://jsfiddle.net/dnh4y39c/

这种方法存在一些问题:

  1. 动画仅在 https://jsfiddle.net/dnh4y39c/1/,

  2. 我可以用 CSS 过渡来解决这个问题,但它完全崩溃了 时机,如果我在栏上设置transition: all 0.5s;,那么它可以工作 相当长的时间,但它完全打破了更快 负载,例如。进度条应该在 1 秒内完成,但它会停止 持续 0.5 秒,然后一次性设置 100% 的动画,请参阅: https://jsfiddle.net/dnh4y39c/1/

我想知道是否应该调整宽度或者只是移动到画布?我不知道画布那么好,但我想它可能性能更高并且占用的资源更少?我的应用程序中可能有多个进度条,因为我需要单独加载所有模块(所以没有一个简单的加载器,但在某些地方甚至可能超过 50 个 - 我知道,这很疯狂,但我只是在关注文档)。

感谢您的任何意见:)

【问题讨论】:

    标签: javascript css animation progress-bar width


    【解决方案1】:

    需要考虑的几件事是:

    • 避免使用setInterval(),如果间隔回调需要更长的时间来执行它本身的间隔持续时间,它会产生“跳跃”的动画行为。如果需要帧间延迟,请改用setTimeout()
    • 考虑使用window.requestAnimationFrame() 来更新进度条的动画。使用window.requestAnimationFrame() 可确保您的进度条更新与浏览器重绘/重绘周期同步

    包含这两个想法的代码的更新版本可能如下所示:

    function interation(element, iterationDuration, i) {
    
      window.requestAnimationFrame(function() {
    
        /*
        Update the width and transition duration of the element for this iteration
        */
        element.style.width = `${i}%`;
        element.style.transitionDuration = `${iterationDuration}ms`;
    
        /*
        Increment/calculate next percentage value for progress bar
        */
        const next = (i === undefined ? 0 : i) + 1;
        if (next <= 100) {
    
          /* 
          Pass element, timeout, and next value through as arguments
          to next interation() call
          */
          setTimeout(interation, iterationDuration, element, iterationDuration, next);
        }
      })
    }
    
    interation(document.querySelector(".progress__bar"), 20);
    // interation(document.querySelector(".progress__bar"), 2000); Long interval
    // interation(document.querySelector(".progress__bar"), 20); Short interval
    * {
      box-sizing: border-box;
    }
    
    .progress__bar {
      transition: width linear;
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      border-radius: 4px;
      background: #f00;
    }
    <div class="item">
      <div class="item__progress">
        <div class="progress__bar" style="width: 0%;"></div>
      </div>
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多