有没有一种“更平滑”的方式来编码进度条?

nie*_*lzz 3 typescript angular

我试图添加一个进度条,但有时它会出错并且填充太慢或太快,但大多数时候它工作正常。

我还认为必须有一种更好的方法来对此进行编程,因为我认为我的方法可以对单个进度条进行许多计算。

这是我的代码:

TS:

startProgressbar(timeToWait: number) {
this.progress = 0;
const interval = setInterval(() => {
  let addvalue = (1 / timeToWait * 100) / 64;
  this.progress += addvalue;
  if (this.progress >= 100) {
    this.progress = 100;
    window.clearInterval(interval);
  }
}, 15.625); }
Run Code Online (Sandbox Code Playgroud)

一旦结束,该函数就会再次被调用,因为紧接着就会有幻灯片的下一张幻灯片。

进度值类似于进度条的宽度,它始终是百分比。

数字 15.625 从何而来?它只是 64 秒,因此进度条每秒更新 64 次,给人一种平稳移动的错觉。

我的 html 非常基本:

<div class="progressbar" [ngStyle]="{'width': progress+'%'}"></div>
Run Code Online (Sandbox Code Playgroud)

我希望你有比我更好的方法。提前致谢

[编辑]:我所说的bug的意思是进度条有时开始填充较晚,因此在下一张幻灯片出现之前不会到达末尾(100%),然后下一张幻灯片的时间也会偏移。有时它会提前开始,然后过快地到达结尾 (100%),因此它会在 100% 状态停留一段时间,直到下一张幻灯片出现。

Eli*_*seo 5

为什么不使用 Rxjs 定时器?

interval(timeToWait):Observable<number>
  {
    let progress = 0;
    return timer(0, timeToWait)
      .pipe(
        takeWhile(() => progress <= 100),
        map(()=>progress<100?progress:100),
        tap(() => (progress += 10))
      )
  }
Run Code Online (Sandbox Code Playgroud)

使用

   this.interval(200).subscribe((res) => {
        console.log(res);
      });
Run Code Online (Sandbox Code Playgroud)

更新添加 stackblitz: stackblitz

更新2感谢@Ritaj,计时器返回一个流(0,1,2,3,4,...),所以我们可以使用简单的

 return timer(0, timeToWait)
  .pipe(
    map((progress)=>progress*5<100?progress*5:100),
    takeWhile((progress) => progress <= 100)
  )
Run Code Online (Sandbox Code Playgroud)

更新 3感谢SO 的回答,我们可以在使用 takeWhile 时包含最后一个值,因此,如果 timeToWait 很重要,我们可以将函数间隔替换为

 interval(timeToWait) {
    const initial = new Date().getTime();
    return timer(0, 200).pipe(
      map(()=> new Date().getTime()),
      takeWhile((res) => res<=initial+timeToWait,true),
      map(now=>{
        const porc = (100 * (now - initial)) / timeToWait;
        return porc<100?Math.round(porc):100
      })
    );
Run Code Online (Sandbox Code Playgroud)