CSS 中的进度条无论长度如何都具有恒定的移动速度

Mit*_*tar 10 html css

我用以下 CSS 制作了一个进度条:

.progress-bar-short,
.progress-bar-long {
  animation-duration: 2.2s;
  animation-iteration-count: infinite;
  animation-delay: 200ms;
  will-change: left, right;
}

.progress-bar-short {
  animation-name: indeterminate-short-ltr;
}

.progress-bar-long {
  animation-name: indeterminate-ltr;
}

@keyframes indeterminate-ltr {
  0% {
    left: -90%;
    right: 100%;
  }
  60% {
    left: -90%;
    right: 100%;
  }
  100% {
    left: 100%;
    right: -35%;
  }
}

@keyframes indeterminate-short-ltr {
  0% {
    left: -200%;
    right: 100%;
  }
  60% {
    left: 107%;
    right: -8%;
  }
  100% {
    left: 107%;
    right: -8%;
  }
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <div class="progress-bar-long" style="left: 0%; right: 100%; top: 0; bottom: 0; position: absolute; background-color: red;"></div>
  <div class="progress-bar-short" style="left: 0%; right: 100%; top: 0; bottom: 0; position: absolute; background-color: red;"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

我认为这是一个非常标准的进度条。但我发现有问题的是,根据进度条的长度(宽度、大小),移动速度会发生变化。时间越长,速度越快,因为动画必须遍历更大的距离才能按时完成动画(以 2.2 秒为单位)。因为我想在顶部的站点级进度条和组件内部的较小进度条上使用相同的进度条,这让我很困扰。

如何制作一个无论进度条长度如何都以恒定速度移动的进度条?

Codepen 演示

Ant*_*ton 12

尝试使用calc()函数和变量的纯 CSS 解决方案,我们使用它们来更改持续时间和变换。所以我们需要一个绝对宽度值,因为使用纯CSS我们无法像JavaScript中那样找到相对宽度值。类中.progress--speed,--width--duration变量,这很重要,因为我们使用它们进行计算。增加--speed将使动画播放速度加快,减少--speed则减慢动画播放速度。

为什么我使用该transform属性而不是left. 网络开发

更新:

对于响应式设计,您可以使用媒体查询断点来更改--length变量,我们有两种方法:在类内使用变量(或添加额外的类)或使用!important.

.progress-bar {
  --height: 3rem;
  width: calc(var(--length) * 1px);
  height: var(--height);
  outline: 1px solid rgb(125, 164, 255);
  position: relative;
  overflow: hidden;
}

/* example with responsive class */
.flexible-class {
  --length: 450;
  outline: 1px solid rgb(238, 125, 255);
}

@media screen and (max-width: 680px) {
  .flexible-class {
    --length: 350;
  }
  .progress-bar {
    /* --length: 350 !important; */ /* if you want change inline variable*/
  }
}
@media screen and (max-width: 480px) {
  .flexible-class {
    --length: 250;
  }
  .progress-bar {
    /* --length: 250 !important; */ /* if you want change inline variable*/
  }
}

.progress {
  --speed: 50;
  --width: 80;  /* 5rem / 5 * 16 = 80 */
  --duration: calc((var(--width) + var(--length)) / var(--speed) * 1s);
  position: absolute;
  top: 0;
  left: calc(-1px * var(--width));
  background-color: rgb(68, 0, 255);
  height: inherit;
  width: calc(1px * var(--width));
  animation-duration: var(--duration);
  animation-iteration-count: infinite;
  animation-delay: 200ms;
  animation-name: animation;
  animation-timing-function: linear;
}

@keyframes animation {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(calc((var(--length) + var(--width)) * 1px));
  }
}
Run Code Online (Sandbox Code Playgroud)
<div class="progress-bar" style="--length: 450">
  <div class="progress"></div>
</div>
<div class="progress-bar" style="--length: 350">
  <div class="progress"></div>
</div>
<div class="progress-bar" style="--length: 250">
  <div class="progress"></div>
</div>
<div class="progress-bar flexible-class">
  <div class="progress"></div>
</div>
Run Code Online (Sandbox Code Playgroud)


Mr-*_*sir 4

这是一个使用 javascript 的简单进度条,它具有恒定的速度:D

怎么运行的?

它的作用是每毫秒遍历一个或两个或三个像素...(取决于给第一个名为“Pixles_traversed_in_ms”的变量的值),并在该间隔内,我们检查进度条是否已到达其容器的末尾,如果是这样,我们将像素设置为 0 s,这意味着它将返回到容器的最左侧。并且它不断地一次又一次地这样做。

let Pixles_traversed_in_ms = 2; // Change this to lower or increase the speed

// Variables
let container = document.querySelector('.container')
let progress_bar = document.querySelector('.container .progress_bar');

let pixels = 1;
setInterval(()=>{
  pixels += Pixles_traversed_in_ms
  progress_bar.style.left = pixels + 'px';
  if (pixels >= container.clientWidth ) {
    pixels = - progress_bar.clientWidth;
  }
}, 1)
Run Code Online (Sandbox Code Playgroud)
.container {
  width:100%;
  background:#f48225;
  height:100px;
  position:relative;
  overflow:hidden;
}
.container .progress_bar {
  position:absolute;
  width:200px;
  height:100%;
  background:black;
  /* You can get rid of these style below*/
  display:flex;
  align-items:center;
  justify-content:center;
  font-family:sans-serif;
  font-size:12px;
  color:#f48225;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
  <div class="progress_bar">
      Progress Bar :D
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

实时预览