annotate src/app/visualisations/notes/notes.component.ts @ 389:29b817e49a22

Introduce interface VerticallyBounded, which describes a component with a vertical range and the ability to render a scale on itself. VerticallyBoundedWavesComponent partially implements this interface, in that it adds a ScaleLayer to itself - derived instances provide the means of obtaining the scale.
author Lucas Thompson <dev@lucas.im>
date Thu, 01 Jun 2017 10:04:41 +0100
parents afe2fa4a3215
children 26ca17e67364
rev   line source
dev@380 1 /**
dev@380 2 * Created by lucast on 31/05/2017.
dev@380 3 */
dev@380 4 import {WavesComponent} from '../waves-base.component';
dev@380 5 import {
dev@380 6 ChangeDetectionStrategy,
dev@380 7 Component,
dev@380 8 Input,
dev@380 9 } from '@angular/core';
dev@380 10 import {Note} from '../FeatureUtilities';
dev@380 11 import Waves from 'waves-ui-piper';
dev@380 12
dev@380 13 @Component({
dev@380 14 selector: 'ugly-notes',
dev@380 15 templateUrl: '../waves-template.html',
dev@380 16 styleUrls: ['../waves-template.css'],
dev@380 17 changeDetection: ChangeDetectionStrategy.OnPush
dev@380 18 })
dev@383 19 export class NotesComponent extends WavesComponent<Note[]> {
dev@380 20
dev@380 21 @Input() set notes(notes: Note[]) {
dev@383 22 this.feature = notes;
dev@380 23 }
dev@380 24
dev@383 25 protected get featureLayers(): Layer[] {
dev@383 26 return [
dev@380 27 new Waves.helpers.PianoRollLayer(
dev@383 28 this.feature,
dev@380 29 {
dev@380 30 height: this.height,
dev@380 31 color: this.colour,
dev@383 32 yDomain: findVerticalRange(this.feature)
dev@380 33 }
dev@383 34 )
dev@383 35 ];
dev@380 36 }
dev@380 37 }
dev@380 38
dev@380 39 // TODO there might be scope to create a generic utility function like this
dev@380 40 function findVerticalRange(notes: Note[]): [number, number] {
dev@380 41 let [min, max] = notes.reduce((acc, note) => {
dev@380 42 const [min, max] = acc;
dev@380 43 return [Math.min (min, note.pitch), Math.max (max, note.pitch)];
dev@380 44 }, [Infinity, -Infinity]);
dev@380 45 if (min === Infinity || min < 0 || max < 0) {
dev@380 46 min = 0;
dev@380 47 max = 127;
dev@380 48 }
dev@380 49 // round min and max to octave boundaries (starting at C as in MIDI)
dev@380 50 return [
dev@380 51 12 * Math.floor(min / 12),
dev@380 52 12 * Math.ceil(max / 12)
dev@380 53 ];
dev@380 54 }