Mercurial > hg > ugly-duckling
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); + } + } +}