diff src/app/services/render-loop/render-loop.service.ts @ 397:308ea1c2612e

Introduce a render loop service / singleton for work which needs to be animated with the play position. Use it for animating the cross-high. Much dupe with the live-play-head, which should be refactored.
author Lucas Thompson <dev@lucas.im>
date Fri, 02 Jun 2017 16:47:38 +0100
parents
children e06b62d949de
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/app/services/render-loop/render-loop.service.ts	Fri Jun 02 16:47:38 2017 +0100
@@ -0,0 +1,55 @@
+/**
+ * Created by lucast on 02/06/2017.
+ */
+import {Injectable, NgZone} from '@angular/core';
+import {AudioPlayerService} from '../audio-player/audio-player.service';
+import {Subscription} from 'rxjs/Subscription';
+import {OnSeekHandler} from '../../playhead/PlayHeadHelpers';
+
+@Injectable()
+export class RenderLoopService {
+  private playingStateSubscription: Subscription;
+  private seekedSubscription: Subscription;
+  private tasks: OnSeekHandler[];
+
+  constructor(private player: AudioPlayerService,
+              private zone: NgZone) {
+    this.tasks = [];
+    this.seekedSubscription = this.player.seeked$.subscribe(() => {
+      if (!this.player.isPlaying()) {
+        this.zone.runOutsideAngular(() => {
+          this.runTasks();
+        });
+      }
+    });
+    this.playingStateSubscription = this.player.playingStateChange$.subscribe(
+      isPlaying => {
+        if (isPlaying) {
+          this.animate();
+        }
+      });
+  }
+
+  addPlayingTask(task: OnSeekHandler): void {
+    this.tasks.push(task);
+  }
+
+  private animate(): void {
+    this.zone.runOutsideAngular(() => {
+      const animateNextFrame = () => {
+        if (this.player.isPlaying()) {
+          this.runTasks();
+          requestAnimationFrame(animateNextFrame);
+        }
+      };
+      requestAnimationFrame(animateNextFrame);
+    });
+  }
+
+  private runTasks(): void {
+    const currentTime = this.player.getCurrentTime();
+    for (const task of this.tasks) {
+      task(currentTime);
+    }
+  }
+}