annotate src/app/visualisations/waves-base.component.ts @ 379:a3b45218c311

Move colour prop to base class
author Lucas Thompson <dev@lucas.im>
date Wed, 31 May 2017 14:49:46 +0100
parents 35234006c3c3
children 1241ca979fd9
rev   line source
dev@354 1 /**
dev@354 2 * Created by lucast on 26/05/2017.
dev@354 3 */
dev@354 4 import {ElementRef, Input} from '@angular/core';
dev@354 5 import {OnSeekHandler} from '../playhead/PlayHeadHelpers';
dev@354 6 import {attachTouchHandlerBodges} from './WavesJunk';
dev@354 7 import Waves from 'waves-ui-piper';
dev@376 8 import {countingIdProvider} from 'piper/client-stubs/WebWorkerStreamingClient';
dev@376 9
dev@376 10 const trackIdGenerator = countingIdProvider(0);
dev@354 11
dev@354 12 export abstract class WavesComponent {
dev@354 13 @Input() set width(width: number) {
dev@354 14 if (this.timeline) {
dev@354 15 requestAnimationFrame(() => {
dev@354 16 this.timeline.timeContext.visibleWidth = width;
dev@354 17 this.timeline.tracks.update();
dev@354 18 });
dev@354 19 }
dev@354 20 }
dev@354 21 @Input() timeline: Timeline;
dev@354 22 @Input() onSeek: OnSeekHandler;
dev@379 23 @Input() colour: string;
dev@354 24
dev@354 25 protected layers: Layer[];
dev@354 26 protected zoomOnMouseDown: number;
dev@354 27 protected offsetOnMouseDown: number;
dev@354 28 protected waveTrack: Track;
dev@376 29 private id: string;
dev@354 30
dev@354 31 constructor() {
dev@354 32 this.layers = [];
dev@376 33 this.id = trackIdGenerator.next().value;
dev@354 34 }
dev@354 35
dev@364 36 protected renderTimeline($el: ElementRef, duration?: number): Timeline {
dev@354 37 const track: HTMLElement = $el.nativeElement;
dev@354 38 track.innerHTML = '';
dev@354 39 const height: number = track.getBoundingClientRect().height;
dev@364 40 if (duration >= 0) {
dev@364 41 const width: number = track.getBoundingClientRect().width;
dev@364 42 this.timeline.pixelsPerSecond = width / duration;
dev@364 43 this.timeline.visibleWidth = width;
dev@364 44 }
dev@354 45 this.waveTrack = this.timeline.createTrack(
dev@354 46 track,
dev@354 47 height,
dev@376 48 this.id
dev@354 49 );
dev@354 50
dev@354 51 if ('ontouchstart' in window) {
dev@354 52 attachTouchHandlerBodges(
dev@354 53 $el.nativeElement,
dev@354 54 this.timeline
dev@354 55 );
dev@354 56 }
dev@356 57 this.resetTimelineState($el);
dev@354 58 }
dev@354 59
dev@354 60 // TODO can likely be removed, or use waves-ui methods
dev@356 61 protected clearTimeline($el: ElementRef): void {
dev@354 62 // loop through layers and remove them, waves-ui provides methods for this but it seems to not work properly
dev@354 63 const timeContextChildren = this.timeline.timeContext._children;
dev@354 64 for (const track of this.timeline.tracks) {
dev@354 65 if (track.layers.length === 0) { continue; }
dev@354 66 const trackLayers: Layer[] = Array.from(track.layers as Layer[]);
dev@354 67 while (trackLayers.length) {
dev@354 68 const layer: Layer = trackLayers.pop();
dev@354 69 if (this.layers.includes(layer)) {
dev@354 70 track.remove(layer);
dev@354 71 this.layers.splice(this.layers.indexOf(layer), 1);
dev@354 72 const index = timeContextChildren.indexOf(layer.timeContext);
dev@354 73 if (index >= 0) {
dev@354 74 timeContextChildren.splice(index, 1);
dev@354 75 }
dev@354 76 layer.destroy();
dev@354 77 }
dev@354 78 }
dev@354 79 }
dev@356 80 this.resetTimelineState($el);
dev@356 81 }
dev@356 82
dev@356 83 private resetTimelineState($el: ElementRef): void {
dev@356 84 const height = $el.nativeElement.getBoundingClientRect().height;
dev@356 85
dev@356 86 // time axis
dev@356 87 const timeAxis = new Waves.helpers.TimeAxisLayer({
dev@356 88 height: height,
dev@356 89 color: '#b0b0b0'
dev@356 90 });
dev@356 91 this.addLayer(timeAxis, this.waveTrack, this.timeline.timeContext, true);
dev@356 92 this.timeline.state = new Waves.states.CenteredZoomState(this.timeline);
dev@364 93 this.timeline.tracks.update(); // TODO this is problematic, shared state across components
dev@354 94 }
dev@354 95
dev@354 96
dev@354 97 // TODO can likely use methods in waves-ui directly
dev@354 98 protected addLayer(layer: Layer,
dev@364 99 track: Track,
dev@364 100 timeContext: any,
dev@364 101 isAxis: boolean = false): void {
dev@354 102 if (!layer.timeContext) {
dev@354 103 layer.setTimeContext(isAxis ?
dev@354 104 timeContext : new Waves.core.LayerTimeContext(timeContext));
dev@354 105 }
dev@354 106 track.add(layer);
dev@354 107 this.layers.push(layer);
dev@354 108 layer.render();
dev@354 109 layer.update();
dev@354 110 }
dev@354 111
dev@354 112 seekStart(): void {
dev@354 113 this.zoomOnMouseDown = this.timeline.timeContext.zoom;
dev@354 114 this.offsetOnMouseDown = this.timeline.timeContext.offset;
dev@354 115 }
dev@354 116
dev@354 117 seekEnd(x: number): void {
dev@354 118 const hasSameZoom: boolean = this.zoomOnMouseDown ===
dev@354 119 this.timeline.timeContext.zoom;
dev@354 120 const hasSameOffset: boolean = this.offsetOnMouseDown ===
dev@354 121 this.timeline.timeContext.offset;
dev@354 122 if (hasSameZoom && hasSameOffset) {
dev@354 123 this.seek(x);
dev@354 124 }
dev@354 125 }
dev@354 126
dev@354 127 seek(x: number): void {
dev@354 128 if (this.timeline) {
dev@354 129 const timeContext: any = this.timeline.timeContext;
dev@354 130 if (this.onSeek) {
dev@354 131 this.onSeek(timeContext.timeToPixel.invert(x) - timeContext.offset);
dev@354 132 }
dev@354 133 }
dev@354 134 }
dev@354 135 }