【问题标题】:Angular Material 2: Progress Bar animation choppyAngular Material 2:进度条动画断断续续
【发布时间】:2019-06-01 04:57:43
【问题描述】:

我正在尝试使用 Angular 构建一个页面,该页面具有各种进度条,这些进度条代表需要一定时间的操作的进度。我想要做的是使用 Angular Material 进度条从时间 0 到结束时间制作平滑的动画。我目前的解决方案是简单地每 50 毫秒更新一次进程的百分比,并将进度条的值设置为该值。我正在使用 rxjs 计时器完成此操作,如下所示:

const start = new Date().getTime();
const source = timer(0, 50);
const subscribe = source.subscribe(() => {
  const time = new Date().getTime();
  if (time - start > length) {
    subscribe.unsubscribe();
  }

  this.progressValue = 100 * (time - start) / length;
});

这是进度条 HTML 本身:

 <mat-progress-bar mode="determinant" [value]="progressValue"></mat-progress-bar>

然而,结果是进度条的进展非常不稳定。有一个更好的方法吗?我每次都知道这个过程的长度,所以我觉得在这段时间内平稳过渡应该相对容易。谢谢!

【问题讨论】:

  • 您是否正确拼写了mode 属性?它应该是 determinate 而不是 determinat
  • 哎呀,好像我做到了。但是,mat-progress-bar 无论如何都默认确定,所以不幸的是它没有帮助解决我的问题。
  • 如果你不介意,我正在做类似的事情,长度代表什么
  • 如果你想要一个流畅的动画,你只能每250ms更新一次进度条,因为.mat-progress-bar-fill的transition-duration是250ms

标签: angular typescript animation


【解决方案1】:

这是我想出的:

html

<mat-progress-bar color="accent" mode="determinate" [value]="uploadPercentage$ | async"></mat-progress-bar>

组件:

@ViewChild(MatProgressBar) progressBar: MatProgressBar;
uploadPercentage$: Observable<number>;
uploadProgress$: Subject<HttpProgressEvent> = new Subject<HttpProgressEvent>();

ngAfterViewInit(): void {
    // wait until animation ends and only then change value
    this.uploadPercentage$ = this.progressBar.animationEnd
      .pipe(
        startWith({
          value: 0
        }),
        switchMap((animationState: ProgressAnimationEnd) => this.uploadProgress$
          .pipe(
            map((progress: HttpProgressEvent): number => this.progressToPercents(progress)),
            distinctUntilChanged((val: number) => animationState.value !== val)
          )
        ),
      );
  }

【讨论】:

    【解决方案2】:

    我已经用 Angular Animations 创建了自己的进度条。这有一个平滑的过渡,看起来就像 ma​​t-progress-bar

    1) 向您的组件添加动画:

      selector: 'app-loading',
      templateUrl: './loading.component.html',
      styleUrls: ['./loading.component.scss'],
      animations: [
        trigger('loading', [
          state('start',
            style({
              width: '0%'
            })
          ),
          state('end',
            style({
              width: '100%'
            })),
    
          transition('start => end', [
            animate(2000)
          ]),
        ])
      ]
    })
    

    2) 设置触发定时器来启动动画。进度结束后我关闭对话框:

    duration: number = 2 * 100;
    step = 100;
    add_step = 10;
    progress = 0;
    
    
    ngOnInit() {
        const interval = setInterval(() => {
          if (this.progress < this.duration) {
            this.progress += this.add_step ;
          } else {
            clearInterval(interval);
            this.dialogRef.close();
          }
        }, this.step);
      }
    

    3) 在 Html 中使用它:

    <div style="background-color: #ff7a7a;height: 4px;width: 100%;">
            <div style="background-color: #760000;height: 4px;"
                 [@loading]="progress === 0 ? 'start':'end'">
            </div>
    </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      • 2016-12-24
      • 2012-02-08
      • 1970-01-01
      • 2011-05-25
      • 2011-02-15
      相关资源
      最近更新 更多