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 AfterViewInit,
|
dev@380
|
7 ChangeDetectionStrategy,
|
dev@380
|
8 Component,
|
dev@380
|
9 ElementRef,
|
dev@380
|
10 Input,
|
dev@380
|
11 ViewChild
|
dev@380
|
12 } from '@angular/core';
|
dev@380
|
13 import {Note} from '../FeatureUtilities';
|
dev@380
|
14 import Waves from 'waves-ui-piper';
|
dev@380
|
15
|
dev@380
|
16 @Component({
|
dev@380
|
17 selector: 'ugly-notes',
|
dev@380
|
18 templateUrl: '../waves-template.html',
|
dev@380
|
19 styleUrls: ['../waves-template.css'],
|
dev@380
|
20 changeDetection: ChangeDetectionStrategy.OnPush
|
dev@380
|
21 })
|
dev@380
|
22 export class NotesComponent extends WavesComponent implements AfterViewInit {
|
dev@380
|
23
|
dev@380
|
24 @ViewChild('track') trackDiv: ElementRef;
|
dev@380
|
25
|
dev@380
|
26 private mFeature: Note[];
|
dev@380
|
27 private height: number; // As it stands, height is fixed. Store once onInit.
|
dev@380
|
28
|
dev@380
|
29 @Input() set notes(notes: Note[]) {
|
dev@380
|
30 this.mFeature = notes;
|
dev@380
|
31 this.update();
|
dev@380
|
32 }
|
dev@380
|
33
|
dev@380
|
34 get notes(): Note[] {
|
dev@380
|
35 return this.mFeature;
|
dev@380
|
36 }
|
dev@380
|
37
|
dev@380
|
38 ngAfterViewInit(): void {
|
dev@380
|
39 this.height = this.trackDiv.nativeElement.getBoundingClientRect().height;
|
dev@380
|
40 this.renderTimeline(this.trackDiv);
|
dev@380
|
41 this.update();
|
dev@380
|
42 }
|
dev@380
|
43
|
dev@380
|
44 update(): void {
|
dev@380
|
45 if (!this.waveTrack || !this.notes) { return; }
|
dev@380
|
46 this.clearTimeline(this.trackDiv);
|
dev@380
|
47
|
dev@380
|
48 this.addLayer(
|
dev@380
|
49 new Waves.helpers.PianoRollLayer(
|
dev@380
|
50 this.notes,
|
dev@380
|
51 {
|
dev@380
|
52 height: this.height,
|
dev@380
|
53 color: this.colour,
|
dev@380
|
54 yDomain: findVerticalRange(this.notes)
|
dev@380
|
55 }
|
dev@380
|
56 ),
|
dev@380
|
57 this.waveTrack,
|
dev@380
|
58 this.timeline.timeContext
|
dev@380
|
59 );
|
dev@380
|
60 }
|
dev@380
|
61 }
|
dev@380
|
62
|
dev@380
|
63 // TODO there might be scope to create a generic utility function like this
|
dev@380
|
64 function findVerticalRange(notes: Note[]): [number, number] {
|
dev@380
|
65 let [min, max] = notes.reduce((acc, note) => {
|
dev@380
|
66 const [min, max] = acc;
|
dev@380
|
67 return [Math.min (min, note.pitch), Math.max (max, note.pitch)];
|
dev@380
|
68 }, [Infinity, -Infinity]);
|
dev@380
|
69 if (min === Infinity || min < 0 || max < 0) {
|
dev@380
|
70 min = 0;
|
dev@380
|
71 max = 127;
|
dev@380
|
72 }
|
dev@380
|
73 // round min and max to octave boundaries (starting at C as in MIDI)
|
dev@380
|
74 return [
|
dev@380
|
75 12 * Math.floor(min / 12),
|
dev@380
|
76 12 * Math.ceil(max / 12)
|
dev@380
|
77 ];
|
dev@380
|
78 }
|