Angular TimelineLite时间功能不适用于OnInit

时间:2019-04-08 09:23:57

标签: angular gsap tweenlite

我尝试使用TimelineLite实现进度条和计时器:

HTML:

<div id="progress"></div>
{{timeline.time()}}

CSS:

#progress {
  width: 100%;
  height: 30px;
  background-color: red;
}

enter image description here

这就是我想要的:
页面加载后,进度条将开始从100%宽度到0%宽度(持续10秒)进行动画处理。另外,我想显示time函数的结果。
这是我所做的:

public timeline = new TimelineLite();

ngOnInit() {
  this.start();
}

start() {
  const progress = document.getElementById('progress');
  this.timeline.fromTo(progress, 10, {width: '100%'}, {width: 0, ease: Linear.easeNone});
}

因此,当页面加载时,进度条可以工作,但计时器不能工作。我不知道为什么如果我尝试将ngOnInit的超时时间设置为3秒,那么它将起作用:

ngOnInit() {
  setTimeout(() => this.start(), 3000);
}

如果我创建一个按钮,而不是单击时调用start函数,它也会起作用:

<button (click)="start()">Start</button>

所以问题是,如果我尝试从fromTo调用ngOnInit函数,计时器将不起作用。

3 个答案:

答案 0 :(得分:1)

嗨,您应该使用@ViewChild来定位元素,并在需要操作时使用AfterViewInit lifeCycleHook |访问您的DOMElement(当前组件或子组件)。

export class AppComponent implements AfterViewInit {

  @ViewChild('progress') progressElement: ElementRef;

  constructor(private changeRef: ChangeDetectorRef) { } 

  public timeline = new TimelineLite();
  ngAfterViewInit() {
    this.start();
  }

  start() {
    this.timeline.eventCallback('onUpdate', () => {
      this.time = this.timeline.time();
      this.changeRef.detectChanges();
    }, [] );

    // Here i use the ViewChild Binding instead of pure javascript fetching.
    this.timeline.fromTo(this.progressElement.nativeElement, 10, {width: '100%'}, {width: 0, ease: Linear.easeNone});
  }
}

为方便您的测试,我进行了Github Pull request。阅读您原始问题的任何人都可以轻松看到其中的区别。


更新1:在视图上,您​​调用一个函数,该函数从TimelineLite返回当前计时器。因为只是函数调用,所以不会在每次内部TimelineLite更新时一次又一次地调用它。

要执行此操作,必须使用TimelineLite event binding

现在,默认情况下,每次从以下代码更新属性时,视图都不会“更新”:

this.timeline.eventCallback('onUpdate', () => {
  // angular is not inform by default than something happen here.
 }, [] );

这就是为什么,您应该使用ChangeDetectorRef来强制angular来检测最新的组件属性。

请求拉动更新

答案 1 :(得分:0)

这显然是调用角度生命周期方法的时间线的一种情况。问题很可能是在onInit中,您没有立即获得DOM元素progress。您已成功使用settimeout来进行其他操作,即保持setinterval直到找到progress
看来最好的方法是在this.start()中写ngAfterViewInit()而不是ngOnInit()

答案 2 :(得分:0)

可能是因为超时在模板初始化之后开始,然后代码在OnInit外部运行而发生。我不确定。

您可能要在这里使用zone.run()。

这是一个链接,可能对您有帮助:https://medium.com/@MertzAlertz/what-the-hell-is-zone-js-and-why-is-it-in-my-angular-2-6ff28bcf943e