数字计数动画角度2

时间:2018-01-11 11:24:01

标签: angular typescript animation

您好我需要在角度2中使用动画进行数字计数。我在Jquery中有一个例子。我需要在角度2中实现这一点。我需要像下面的示例Codepen Example

那样做

4 个答案:

答案 0 :(得分:5)

尝试以下代码:

  

$ npm install ng2-odometer --save

<强> app.module.ts

 import { Ng2OdometerModule } from 'ng2-odometer';
import { FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent,
    DashboardComponent,

  ],
  imports: [
    HttpClientModule,
    BrowserModule,
    AppRoutingModule,FormsModule, 
    Ng2OdometerModule.forRoot(),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

<强> home.html的

  <div style="font-size: 30px;color: white;">
        <ng2-odometer [number]="number" [config]="{ }"></ng2-odometer>
    </div>

<强> home.ts

export class HomeComponent implements OnInit {

  public number: number = 1000;

  constructor() { }

  ngOnInit() {
  }

}

more info

答案 1 :(得分:1)

由于ng2-odometer已旧且未更新,我建议使用与Angular 5兼容的angular2-counto包。您可以看到demo

答案 2 :(得分:1)

您可以在RXJS的帮助下实现这一目标。

number-tracker.component.ts

import { Component, Input, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { timer } from 'rxjs/observable/timer';
import { switchMap, startWith, scan, takeWhile, takeUntil, mapTo } from 'rxjs/operators';

@Component({
  selector: 'number-tracker',
  template: `
    <h3> {{ currentNumber }}</h3>
  `
})
export class NumberTrackerComponent implements OnDestroy {
  @Input()
  set end(endRange: number) {
    this._counterSub$.next(endRange);
  }
  @Input() countInterval = 20;
  public currentNumber = 0;
  private _counterSub$ = new Subject();
  private _onDestroy$ = new Subject();

  constructor() {
    this._counterSub$
      .pipe(
        switchMap(endRange => {
          return timer(0, this.countInterval).pipe(
            mapTo(this.positiveOrNegative(endRange, this.currentNumber)),
            startWith(this.currentNumber),
            scan((acc: number, curr: number) => acc + curr),
            takeWhile(this.isApproachingRange(endRange, this.currentNumber))
          )
        }),
        takeUntil(this._onDestroy$)
      )
      .subscribe((val: number) => this.currentNumber = val);
  }

  private positiveOrNegative(endRange, currentNumber) {
    return endRange > currentNumber ? 1 : -1;
  }

  private isApproachingRange(endRange, currentNumber) {
    return endRange > currentNumber
      ? val => val <= endRange
      : val => val >= endRange;
  }

  ngOnDestroy() {
    this._onDestroy$.next();
    this._onDestroy$.complete();
  }
}

用法

<p>
  <input
    type="number"
    (keyup.enter)="counterNumber = vanillaInput.value"
    #vanillaInput
  />
  <button (click)="counterNumber = vanillaInput.value">
    Update number
  </button>
</p>
<number-tracker [end]="counterNumber"></number-tracker>

祝你好运!

答案 3 :(得分:0)

当它们出现在视口中时,我面临着计算数字的任务 - 所以,我的用法:

npm i ngx-countup 作为动画计数的指令,以及我的自定义指令来确定出现的视口。无依赖,无交集观察者,ngx-countUp 支持 Angular Universal。

InViewport 自定义指令:

HTML:

<div isInViewport (onView)="card.count = card.endCount" class="stats-count">
     <span *ngIf="card.count" [countUp]="card.count">0</span>
</div>

指令代码:

import { Directive, ElementRef, Output, EventEmitter, OnDestroy } from '@angular/core';
import { fromEvent, Subject, Subscription } from 'rxjs';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';

@Directive({
  // tslint:disable-next-line:directive-selector
  selector: '[isInViewport]',
})
export class IsInViewportDirective implements OnDestroy {
  private wasViewed$ = new Subject<void>();
  private subs = new Subscription();
  @Output() onView = new EventEmitter<void>();

  constructor(private elementRef: ElementRef) {
    this.listenScroll();
  }

  ngOnDestroy() {
    this.wasViewed$.complete();
    this.subs.unsubscribe();
  }

  private listenScroll() {
    this.subs.add(
      fromEvent(window, 'scroll')
        .pipe(takeUntil(this.wasViewed$))
        .pipe(debounceTime(100))
        .subscribe(() => {
          if (this.isInViewport()) {
            this.onView.emit();
            this.wasViewed$.next();
            this.wasViewed$.complete();
          }
        })
    );
  }

  private isInViewport() {
    const elem = this.elementRef.nativeElement;
    const bounding = elem.getBoundingClientRect();
    return (
      bounding.top >= 0 &&
      bounding.left >= 0 &&
      bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
      bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
  }
}

@NgModule({
  imports: [CommonModule],
  declarations: [IsInViewportDirective],
  exports: [IsInViewportDirective],
})
export class IsInViewportModule {}