changeset 345:ce598b654044

Add a component to drive a play head component, animating it with RAF.
author Lucas Thompson <dev@lucas.im>
date Thu, 25 May 2017 17:51:46 +0100
parents 7b099900f049
children f87a96ab1e3f
files src/app/playhead/live-play-head.component.ts
diffstat 1 files changed, 69 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/app/playhead/live-play-head.component.ts	Thu May 25 17:51:46 2017 +0100
@@ -0,0 +1,69 @@
+/**
+ * Created by lucast on 23/05/2017.
+ */
+import {
+  ChangeDetectionStrategy,
+  Component,
+  Input,
+  OnDestroy,
+  AfterViewInit,
+  ChangeDetectorRef,
+  NgZone
+} from '@angular/core';
+import {
+  AudioPlayerService
+} from '../services/audio-player/audio-player.service';
+import {TimePixelMapper} from './PlayHeadHelpers';
+import {Subscription} from 'rxjs/Subscription';
+
+@Component({
+  selector: 'ugly-live-play-head',
+  template: `<ugly-play-head
+    [currentTime]="currentTime"
+    [timeToPixel]="timeToPixel"
+    [colour]="colour"></ugly-play-head>`,
+  changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class LivePlayHeadComponent implements AfterViewInit, OnDestroy {
+  @Input() timeToPixel: TimePixelMapper;
+  @Input() colour: string;
+  private playingStateSubscription: Subscription;
+  private seekedSubscription: Subscription;
+  private currentTime = 0;
+
+  constructor(private player: AudioPlayerService,
+              private ref: ChangeDetectorRef,
+              private zone: NgZone) {}
+
+  ngAfterViewInit(): void {
+    this.seekedSubscription = this.player.seeked$.subscribe(() => {
+      if (!this.player.isPlaying()) {
+        this.animate();
+      }
+    });
+    this.playingStateSubscription = this.player.playingStateChange$.subscribe(
+      isPlaying => {
+        if (isPlaying) {
+          this.animate();
+        }
+      });
+  }
+
+  animate(): void {
+    this.zone.runOutsideAngular(() => {
+      const animateNextFrame = () => {
+        this.currentTime = this.player.getCurrentTime();
+        this.ref.markForCheck();
+        if (this.player.isPlaying()) {
+          requestAnimationFrame(animateNextFrame);
+        }
+      };
+      requestAnimationFrame(animateNextFrame);
+    });
+  }
+
+  ngOnDestroy(): void {
+    this.playingStateSubscription.unsubscribe();
+    this.seekedSubscription.unsubscribe();
+  }
+}