dev@380: /** dev@380: * Created by lucast on 31/05/2017. dev@380: */ dev@380: import {WavesComponent} from '../waves-base.component'; dev@380: import { dev@380: AfterViewInit, dev@380: ChangeDetectionStrategy, dev@380: Component, dev@380: ElementRef, dev@380: Input, dev@380: ViewChild dev@380: } from '@angular/core'; dev@380: import {Note} from '../FeatureUtilities'; dev@380: import Waves from 'waves-ui-piper'; dev@380: dev@380: @Component({ dev@380: selector: 'ugly-notes', dev@380: templateUrl: '../waves-template.html', dev@380: styleUrls: ['../waves-template.css'], dev@380: changeDetection: ChangeDetectionStrategy.OnPush dev@380: }) dev@380: export class NotesComponent extends WavesComponent implements AfterViewInit { dev@380: dev@380: @ViewChild('track') trackDiv: ElementRef; dev@380: dev@380: private mFeature: Note[]; dev@380: private height: number; // As it stands, height is fixed. Store once onInit. dev@380: dev@380: @Input() set notes(notes: Note[]) { dev@380: this.mFeature = notes; dev@380: this.update(); dev@380: } dev@380: dev@380: get notes(): Note[] { dev@380: return this.mFeature; dev@380: } dev@380: dev@380: ngAfterViewInit(): void { dev@380: this.height = this.trackDiv.nativeElement.getBoundingClientRect().height; dev@380: this.renderTimeline(this.trackDiv); dev@380: this.update(); dev@380: } dev@380: dev@380: update(): void { dev@380: if (!this.waveTrack || !this.notes) { return; } dev@380: this.clearTimeline(this.trackDiv); dev@380: dev@380: this.addLayer( dev@380: new Waves.helpers.PianoRollLayer( dev@380: this.notes, dev@380: { dev@380: height: this.height, dev@380: color: this.colour, dev@380: yDomain: findVerticalRange(this.notes) dev@380: } dev@380: ), dev@380: this.waveTrack, dev@380: this.timeline.timeContext dev@380: ); dev@380: } dev@380: } dev@380: dev@380: // TODO there might be scope to create a generic utility function like this dev@380: function findVerticalRange(notes: Note[]): [number, number] { dev@380: let [min, max] = notes.reduce((acc, note) => { dev@380: const [min, max] = acc; dev@380: return [Math.min (min, note.pitch), Math.max (max, note.pitch)]; dev@380: }, [Infinity, -Infinity]); dev@380: if (min === Infinity || min < 0 || max < 0) { dev@380: min = 0; dev@380: max = 127; dev@380: } dev@380: // round min and max to octave boundaries (starting at C as in MIDI) dev@380: return [ dev@380: 12 * Math.floor(min / 12), dev@380: 12 * Math.ceil(max / 12) dev@380: ]; dev@380: }