annotate src/app/visualisations/waves-base.component.ts @ 354:a9ce5516c17d

Introduce an abstract base class for components using waves-ui.
author Lucas Thompson <dev@lucas.im>
date Fri, 26 May 2017 18:17:31 +0100
parents
children b852bace6b14
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@354 8
dev@354 9 export abstract class WavesComponent {
dev@354 10 @Input() set width(width: number) {
dev@354 11 if (this.timeline) {
dev@354 12 requestAnimationFrame(() => {
dev@354 13 this.timeline.timeContext.visibleWidth = width;
dev@354 14 this.timeline.tracks.update();
dev@354 15 });
dev@354 16 }
dev@354 17 }
dev@354 18 @Input() timeline: Timeline;
dev@354 19 @Input() trackIdPrefix: string;
dev@354 20 @Input() onSeek: OnSeekHandler;
dev@354 21
dev@354 22 protected layers: Layer[];
dev@354 23 protected zoomOnMouseDown: number;
dev@354 24 protected offsetOnMouseDown: number;
dev@354 25 protected waveTrack: Track;
dev@354 26
dev@354 27 constructor() {
dev@354 28 this.layers = [];
dev@354 29 }
dev@354 30
dev@354 31 protected renderTimeline($el: ElementRef, duration: number = 1.0): Timeline {
dev@354 32 const track: HTMLElement = $el.nativeElement;
dev@354 33 track.innerHTML = '';
dev@354 34 const height: number = track.getBoundingClientRect().height;
dev@354 35 const width: number = track.getBoundingClientRect().width;
dev@354 36 this.timeline.pixelsPerSecond = width / duration;
dev@354 37 this.timeline.visibleWidth = width;
dev@354 38 this.waveTrack = this.timeline.createTrack(
dev@354 39 track,
dev@354 40 height,
dev@354 41 `wave-${this.trackIdPrefix || 'default'}`
dev@354 42 );
dev@354 43
dev@354 44 if ('ontouchstart' in window) {
dev@354 45 attachTouchHandlerBodges(
dev@354 46 $el.nativeElement,
dev@354 47 this.timeline
dev@354 48 );
dev@354 49 }
dev@354 50 }
dev@354 51
dev@354 52 // TODO can likely be removed, or use waves-ui methods
dev@354 53 protected clearTimeline(): void {
dev@354 54 // loop through layers and remove them, waves-ui provides methods for this but it seems to not work properly
dev@354 55 const timeContextChildren = this.timeline.timeContext._children;
dev@354 56 for (const track of this.timeline.tracks) {
dev@354 57 if (track.layers.length === 0) { continue; }
dev@354 58 const trackLayers: Layer[] = Array.from(track.layers as Layer[]);
dev@354 59 while (trackLayers.length) {
dev@354 60 const layer: Layer = trackLayers.pop();
dev@354 61 if (this.layers.includes(layer)) {
dev@354 62 track.remove(layer);
dev@354 63 this.layers.splice(this.layers.indexOf(layer), 1);
dev@354 64 const index = timeContextChildren.indexOf(layer.timeContext);
dev@354 65 if (index >= 0) {
dev@354 66 timeContextChildren.splice(index, 1);
dev@354 67 }
dev@354 68 layer.destroy();
dev@354 69 }
dev@354 70 }
dev@354 71 }
dev@354 72 }
dev@354 73
dev@354 74
dev@354 75 // TODO can likely use methods in waves-ui directly
dev@354 76 protected addLayer(layer: Layer,
dev@354 77 track: Track,
dev@354 78 timeContext: any,
dev@354 79 isAxis: boolean = false): void {
dev@354 80 timeContext.zoom = 1.0;
dev@354 81 if (!layer.timeContext) {
dev@354 82 layer.setTimeContext(isAxis ?
dev@354 83 timeContext : new Waves.core.LayerTimeContext(timeContext));
dev@354 84 }
dev@354 85 track.add(layer);
dev@354 86 this.layers.push(layer);
dev@354 87 layer.render();
dev@354 88 layer.update();
dev@354 89 }
dev@354 90
dev@354 91 seekStart(): void {
dev@354 92 this.zoomOnMouseDown = this.timeline.timeContext.zoom;
dev@354 93 this.offsetOnMouseDown = this.timeline.timeContext.offset;
dev@354 94 }
dev@354 95
dev@354 96 seekEnd(x: number): void {
dev@354 97 const hasSameZoom: boolean = this.zoomOnMouseDown ===
dev@354 98 this.timeline.timeContext.zoom;
dev@354 99 const hasSameOffset: boolean = this.offsetOnMouseDown ===
dev@354 100 this.timeline.timeContext.offset;
dev@354 101 if (hasSameZoom && hasSameOffset) {
dev@354 102 this.seek(x);
dev@354 103 }
dev@354 104 }
dev@354 105
dev@354 106 seek(x: number): void {
dev@354 107 if (this.timeline) {
dev@354 108 const timeContext: any = this.timeline.timeContext;
dev@354 109 if (this.onSeek) {
dev@354 110 this.onSeek(timeContext.timeToPixel.invert(x) - timeContext.offset);
dev@354 111 }
dev@354 112 }
dev@354 113 }
dev@354 114 }