-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrender-vex.mjs
118 lines (92 loc) · 3.08 KB
/
render-vex.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { Flow } from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm';
import { lyPatternToAscii } from './ly-pattern-parser.mjs';
import { parseAsciiPattern, asciiPatternToHelperLy } from './ascii-pattern-parser.mjs';
const { StaveNote, Stave, Renderer, Voice, Formatter, Beam, EasyScore, System, Factory, Fraction } = Flow;
const lookup = {
hh: 'G/5/x1', // x(=x2) x0 x1 x2 x3
sn: 'C/5',
bd: 'D/4',
};
const colors = {
hh: '#700',
sn: '#070',
bd: '#007',
};
export async function renderLyPattern(lyPattern, linearTime = false) {
const asciiPattern = await lyPatternToAscii(lyPattern);
return renderAsciiPattern(asciiPattern, linearTime);
}
export async function renderAsciiPattern(asciiPattern, linearTime = false) {
const parsedAsciiPattern = parseAsciiPattern(asciiPattern);
const arr = asciiPatternToHelperLy(parsedAsciiPattern);
return _render(arr, linearTime);
}
export function _render(arr, linearTime = false) {
const FOUR_FOUR = {
num_beats: 4,
beat_value: 4,
};
const PAD_X = 20;
const PAD_Y = 20;
const WW = window.innerWidth;
const W = WW - 2 * PAD_X;
const H = 150;
const HH = H + 2 * PAD_Y;
const containerEl = document.createElement('div');
document.body.appendChild(containerEl);
const renderer = new Renderer(
containerEl,
Renderer.Backends.SVG,
//Renderer.Backends.CANVAS,
);
renderer.resize(WW, HH);
const context = renderer.getContext();
const formatter = new Formatter();
// posX, posY, W
const stave = new Stave(PAD_X, PAD_Y, W);
stave.addClef('percussion').addTimeSignature('4/4');
stave.setContext(context);
//stave.draw();
const noteXs = [];
const notes = arr.map(([pitches, toNext, fromPrev, ratioOfMeasure]) => {
noteXs.push(ratioOfMeasure);
const note = new StaveNote({
keys: pitches.map((pitch) => lookup[pitch]),
duration: `${toNext}`,
});
// https://github.com/0xfe/vexflow/wiki/Coloring-%26-Styling-Notes
pitches.forEach((pn, i) => note.setKeyStyle(i, { fillStyle: colors[pn] }));
return note;
});
const voice = new Voice(FOUR_FOUR);
//voice.setMode(Voice.Mode.STRICT); // SOFT, FULL, STRICT ??
voice.addTickables(notes);
formatter.joinVoices([voice]).format([voice], W);
if (linearTime) {
const voiceW = W * 0.9;
notes.forEach((note, i) => {
note.getTickContext().setX(voiceW *noteXs[i]);
});
}
voice.draw(context, stave);
const applyBeams = true;
let beams;
if (applyBeams) {
beams = Beam.generateBeams( voice.getTickables() );
beams.forEach((beam) => beam.setContext(context).draw());
}
if (!linearTime) {
formatter.joinVoices([voice]).format([voice], W);
}
stave.context.clear();
stave.draw();
voice.draw(context, stave);
if (applyBeams) {
beams.forEach((beam) => beam.setContext(context).draw());
}
return {
dispose() {
document.body.removeChild(containerEl);
}
}
}