annotate src/app/waveform/waveform.component.ts @ 36:e58fb181a11d

Import waves-ui with TypeScript (ambient module, no typings for now) over angular-cli global scripts. Include there instead a TypeScript file, for creating a webpack scripts bundle of external modules (unused currently, but can provide a way for importing npm modules to a worker).
author Lucas Thompson <dev@lucas.im>
date Thu, 01 Dec 2016 14:05:49 +0000
parents 35350929f23b
children e6eb133fa47c
rev   line source
dev@10 1 import {
dev@31 2 Component, OnInit, ViewChild, ElementRef, Input, AfterViewInit, NgZone
dev@10 3 } from '@angular/core';
dev@31 4 import {AudioPlayerService} from "../services/audio-player.service";
dev@36 5 import wavesUI from 'waves-ui';
dev@8 6
dev@20 7 type Timeline = any; // TODO what type actually is it.. start a .d.ts for waves-ui?
dev@6 8
dev@6 9 @Component({
dev@6 10 selector: 'app-waveform',
dev@6 11 templateUrl: './waveform.component.html',
dev@6 12 styleUrls: ['./waveform.component.css']
dev@6 13 })
dev@20 14 export class WaveformComponent implements OnInit, AfterViewInit {
dev@20 15
dev@8 16 @ViewChild('track') trackDiv: ElementRef;
dev@6 17
dev@16 18 private _audioBuffer: AudioBuffer = undefined;
dev@16 19
dev@16 20 @Input()
dev@16 21 set audioBuffer(buffer: AudioBuffer) {
dev@16 22 this._audioBuffer = buffer || undefined;
dev@20 23 if (this.audioBuffer)
dev@20 24 this.renderWaveform(this.audioBuffer);
dev@16 25 }
dev@16 26
dev@16 27 get audioBuffer(): AudioBuffer {
dev@16 28 return this._audioBuffer;
dev@16 29 }
dev@16 30
dev@31 31 constructor(private audioService: AudioPlayerService,
dev@31 32 public ngZone: NgZone) {}
dev@10 33 ngOnInit() {}
dev@10 34
dev@10 35 ngAfterViewInit(): void {
dev@20 36 this.renderTimeline();
dev@20 37 }
dev@20 38
dev@20 39 renderTimeline(duration: number = 1.0): Timeline {
dev@18 40 const track: HTMLElement = this.trackDiv.nativeElement;
dev@20 41 track.innerHTML = "";
dev@18 42 const height: number = track.getBoundingClientRect().height;
dev@18 43 const width: number = track.getBoundingClientRect().width;
dev@18 44 const pixelsPerSecond = width / duration;
dev@18 45 const timeline = new wavesUI.core.Timeline(pixelsPerSecond, width);
dev@33 46 timeline.timeContext.offset = 0.5 * timeline.timeContext.visibleDuration;
dev@18 47 timeline.createTrack(track, height, 'main');
dev@18 48
dev@18 49 // time axis
dev@18 50 const timeAxis = new wavesUI.helpers.TimeAxisLayer({
dev@18 51 height: height,
dev@18 52 color: 'gray'
dev@18 53 });
dev@18 54
dev@18 55 timeline.addLayer(timeAxis, 'main', 'default', true);
dev@20 56 return timeline;
dev@16 57 }
dev@16 58
dev@20 59 renderWaveform(buffer: AudioBuffer): void {
dev@20 60 const height: number = this.trackDiv.nativeElement.getBoundingClientRect().height;
dev@20 61 const timeline: Timeline = this.renderTimeline(buffer.duration);
dev@20 62 const waveformLayer = new wavesUI.helpers.WaveformLayer(buffer, {
dev@10 63 top: 10,
dev@20 64 height: height * 0.9,
dev@16 65 color: 'darkblue'
dev@16 66 });
dev@20 67 (timeline as any).addLayer(waveformLayer, 'main');
dev@31 68
dev@31 69 const cursorLayer = new wavesUI.helpers.CursorLayer({
dev@31 70 height: height
dev@31 71 });
dev@31 72 timeline.addLayer(cursorLayer, 'main');
dev@31 73 timeline.state = new wavesUI.states.CenteredZoomState(timeline);
dev@31 74 this.ngZone.runOutsideAngular(() => {
dev@31 75 // listen for time passing...
dev@31 76 // TODO this gets the fans going on large files... worth fixing? or waiting to write a better component?
dev@31 77 // or, can this be updated in a more efficient manner?
dev@31 78 const updateSeekingCursor = () => {
dev@31 79 cursorLayer.currentPosition = this.audioService.getCurrentTime();
dev@31 80 cursorLayer.update();
dev@34 81 if (timeline.timeContext.offset + this.audioService.getCurrentTime() >= timeline.timeContext.visibleDuration) {
dev@33 82 timeline.timeContext.offset -= timeline.timeContext.visibleDuration;
dev@34 83 timeline.tracks.update();
dev@34 84 }
dev@34 85 if (-this.audioService.getCurrentTime() > timeline.timeContext.offset) {
dev@33 86 timeline.timeContext.offset += timeline.timeContext.visibleDuration;
dev@34 87 timeline.tracks.update();
dev@34 88 }
dev@31 89 requestAnimationFrame(updateSeekingCursor);
dev@31 90 };
dev@31 91 updateSeekingCursor();
dev@31 92 });
dev@6 93 }
dev@16 94
dev@6 95 }