Mercurial > hg > ugly-duckling
comparison src/app/visualisations/notes/notes.component.ts @ 380:b81ed55fdee3
Basic notes component in place. Room for reducing dupe across these WaveComponent derived components, but will wait until all of them are implemented to see the common logic.
author | Lucas Thompson <dev@lucas.im> |
---|---|
date | Wed, 31 May 2017 15:15:55 +0100 |
parents | |
children | 1241ca979fd9 |
comparison
equal
deleted
inserted
replaced
379:a3b45218c311 | 380:b81ed55fdee3 |
---|---|
1 /** | |
2 * Created by lucast on 31/05/2017. | |
3 */ | |
4 import {WavesComponent} from '../waves-base.component'; | |
5 import { | |
6 AfterViewInit, | |
7 ChangeDetectionStrategy, | |
8 Component, | |
9 ElementRef, | |
10 Input, | |
11 ViewChild | |
12 } from '@angular/core'; | |
13 import {Note} from '../FeatureUtilities'; | |
14 import Waves from 'waves-ui-piper'; | |
15 | |
16 @Component({ | |
17 selector: 'ugly-notes', | |
18 templateUrl: '../waves-template.html', | |
19 styleUrls: ['../waves-template.css'], | |
20 changeDetection: ChangeDetectionStrategy.OnPush | |
21 }) | |
22 export class NotesComponent extends WavesComponent implements AfterViewInit { | |
23 | |
24 @ViewChild('track') trackDiv: ElementRef; | |
25 | |
26 private mFeature: Note[]; | |
27 private height: number; // As it stands, height is fixed. Store once onInit. | |
28 | |
29 @Input() set notes(notes: Note[]) { | |
30 this.mFeature = notes; | |
31 this.update(); | |
32 } | |
33 | |
34 get notes(): Note[] { | |
35 return this.mFeature; | |
36 } | |
37 | |
38 ngAfterViewInit(): void { | |
39 this.height = this.trackDiv.nativeElement.getBoundingClientRect().height; | |
40 this.renderTimeline(this.trackDiv); | |
41 this.update(); | |
42 } | |
43 | |
44 update(): void { | |
45 if (!this.waveTrack || !this.notes) { return; } | |
46 this.clearTimeline(this.trackDiv); | |
47 | |
48 this.addLayer( | |
49 new Waves.helpers.PianoRollLayer( | |
50 this.notes, | |
51 { | |
52 height: this.height, | |
53 color: this.colour, | |
54 yDomain: findVerticalRange(this.notes) | |
55 } | |
56 ), | |
57 this.waveTrack, | |
58 this.timeline.timeContext | |
59 ); | |
60 } | |
61 } | |
62 | |
63 // TODO there might be scope to create a generic utility function like this | |
64 function findVerticalRange(notes: Note[]): [number, number] { | |
65 let [min, max] = notes.reduce((acc, note) => { | |
66 const [min, max] = acc; | |
67 return [Math.min (min, note.pitch), Math.max (max, note.pitch)]; | |
68 }, [Infinity, -Infinity]); | |
69 if (min === Infinity || min < 0 || max < 0) { | |
70 min = 0; | |
71 max = 127; | |
72 } | |
73 // round min and max to octave boundaries (starting at C as in MIDI) | |
74 return [ | |
75 12 * Math.floor(min / 12), | |
76 12 * Math.ceil(max / 12) | |
77 ]; | |
78 } |