comparison 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
comparison
equal deleted inserted replaced
396:3eab26a629e1 397:308ea1c2612e
1 /**
2 * Created by lucast on 02/06/2017.
3 */
4 import {Injectable, NgZone} from '@angular/core';
5 import {AudioPlayerService} from '../audio-player/audio-player.service';
6 import {Subscription} from 'rxjs/Subscription';
7 import {OnSeekHandler} from '../../playhead/PlayHeadHelpers';
8
9 @Injectable()
10 export class RenderLoopService {
11 private playingStateSubscription: Subscription;
12 private seekedSubscription: Subscription;
13 private tasks: OnSeekHandler[];
14
15 constructor(private player: AudioPlayerService,
16 private zone: NgZone) {
17 this.tasks = [];
18 this.seekedSubscription = this.player.seeked$.subscribe(() => {
19 if (!this.player.isPlaying()) {
20 this.zone.runOutsideAngular(() => {
21 this.runTasks();
22 });
23 }
24 });
25 this.playingStateSubscription = this.player.playingStateChange$.subscribe(
26 isPlaying => {
27 if (isPlaying) {
28 this.animate();
29 }
30 });
31 }
32
33 addPlayingTask(task: OnSeekHandler): void {
34 this.tasks.push(task);
35 }
36
37 private animate(): void {
38 this.zone.runOutsideAngular(() => {
39 const animateNextFrame = () => {
40 if (this.player.isPlaying()) {
41 this.runTasks();
42 requestAnimationFrame(animateNextFrame);
43 }
44 };
45 requestAnimationFrame(animateNextFrame);
46 });
47 }
48
49 private runTasks(): void {
50 const currentTime = this.player.getCurrentTime();
51 for (const task of this.tasks) {
52 task(currentTime);
53 }
54 }
55 }