@real-music-packages/web-core 0.45.2 → 0.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/dist/audio.js +7 -7
- package/dist/chunk-JCDNEJBT.js +176 -0
- package/dist/chunk-JCDNEJBT.js.map +1 -0
- package/dist/notationBeams.d.ts +26 -0
- package/dist/notationBeams.js +133 -0
- package/dist/notationBeams.js.map +1 -0
- package/dist/notationPlayerVerovio.d.ts +26 -57
- package/dist/notationPlayerVerovio.js +27 -136
- package/dist/notationPlayerVerovio.js.map +1 -1
- package/dist/notationXml.d.ts +175 -0
- package/dist/notationXml.js +19 -0
- package/dist/notationXml.js.map +1 -0
- package/dist/scene/index.d.ts +410 -2
- package/dist/scene/index.js +725 -21
- package/dist/scene/index.js.map +1 -1
- package/package.json +9 -1
|
@@ -10,138 +10,14 @@ import {
|
|
|
10
10
|
vstackAudioPlayheadLine
|
|
11
11
|
} from "./chunk-DBFGX6OK.js";
|
|
12
12
|
import "./chunk-PVZXLC23.js";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const number = measure.getAttribute("number") ?? "0";
|
|
22
|
-
const notes = Array.from(measure.children).filter((el) => el.tagName === "note");
|
|
23
|
-
notes.forEach((note, noteIdx) => {
|
|
24
|
-
note.setAttribute("id", `n-${partIdx}-${number}-${noteIdx}`);
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
return new XMLSerializer().serializeToString(doc);
|
|
29
|
-
}
|
|
30
|
-
function injectSystemBreaks(xml, breakBeforeBarIndexes) {
|
|
31
|
-
const doc = new DOMParser().parseFromString(xml, "application/xml");
|
|
32
|
-
if (doc.querySelector("parsererror")) return xml;
|
|
33
|
-
const root = doc.documentElement;
|
|
34
|
-
if (!root || root.tagName !== "score-partwise") return xml;
|
|
35
|
-
for (const part of childrenNamed(root, "part")) {
|
|
36
|
-
const measures = childrenNamed(part, "measure");
|
|
37
|
-
for (const pos of breakBeforeBarIndexes) {
|
|
38
|
-
if (!Number.isInteger(pos) || pos <= 0 || pos >= measures.length) continue;
|
|
39
|
-
const measure = measures[pos];
|
|
40
|
-
const existingPrint = firstChildNamed(measure, "print");
|
|
41
|
-
if (existingPrint) {
|
|
42
|
-
existingPrint.setAttribute("new-system", "yes");
|
|
43
|
-
} else {
|
|
44
|
-
const printEl = doc.createElement("print");
|
|
45
|
-
printEl.setAttribute("new-system", "yes");
|
|
46
|
-
measure.insertBefore(printEl, measure.firstChild);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return new XMLSerializer().serializeToString(doc);
|
|
51
|
-
}
|
|
52
|
-
function balancedSystemBreaks(totalMeasures, systems) {
|
|
53
|
-
if (systems <= 1 || totalMeasures <= 0) return [];
|
|
54
|
-
const per = Math.ceil(totalMeasures / systems);
|
|
55
|
-
if (per <= 0) return [];
|
|
56
|
-
const breaks = [];
|
|
57
|
-
for (let b = per; b < totalMeasures; b += per) breaks.push(b);
|
|
58
|
-
return breaks;
|
|
59
|
-
}
|
|
60
|
-
var STEP_SEMITONE = { C: 0, D: 2, E: 4, F: 5, G: 7, A: 9, B: 11 };
|
|
61
|
-
function firstChildNamed(el, tag) {
|
|
62
|
-
for (const c of Array.from(el.children)) if (c.tagName === tag) return c;
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
function childrenNamed(el, tag) {
|
|
66
|
-
return Array.from(el.children).filter((c) => c.tagName === tag);
|
|
67
|
-
}
|
|
68
|
-
function textOf(el) {
|
|
69
|
-
return el && el.textContent != null ? el.textContent.trim() : null;
|
|
70
|
-
}
|
|
71
|
-
function pitchMidiFromElement(pitchEl) {
|
|
72
|
-
const step = textOf(firstChildNamed(pitchEl, "step")) ?? "C";
|
|
73
|
-
const octave = Number(textOf(firstChildNamed(pitchEl, "octave")) ?? "4");
|
|
74
|
-
const alter = Number(textOf(firstChildNamed(pitchEl, "alter")) ?? "0");
|
|
75
|
-
return 12 * (octave + 1) + (STEP_SEMITONE[step] ?? 0) + Math.trunc(alter);
|
|
76
|
-
}
|
|
77
|
-
function partStaffCount(part) {
|
|
78
|
-
let maxDeclared = 0;
|
|
79
|
-
for (const attrs of childrenNamed(part, "measure").flatMap((m) => childrenNamed(m, "attributes"))) {
|
|
80
|
-
const staves = Number(textOf(firstChildNamed(attrs, "staves")) ?? "0");
|
|
81
|
-
if (staves > maxDeclared) maxDeclared = staves;
|
|
82
|
-
}
|
|
83
|
-
if (maxDeclared > 0) return maxDeclared;
|
|
84
|
-
let maxStaff = 0;
|
|
85
|
-
for (const measure of childrenNamed(part, "measure")) {
|
|
86
|
-
for (const note of childrenNamed(measure, "note")) {
|
|
87
|
-
const staff = Number(textOf(firstChildNamed(note, "staff")) ?? "0");
|
|
88
|
-
if (staff > maxStaff) maxStaff = staff;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return Math.max(1, maxStaff);
|
|
92
|
-
}
|
|
93
|
-
function noteModelFromXml(stampedXml) {
|
|
94
|
-
const model = /* @__PURE__ */ new Map();
|
|
95
|
-
let doc;
|
|
96
|
-
try {
|
|
97
|
-
doc = new DOMParser().parseFromString(stampedXml, "application/xml");
|
|
98
|
-
} catch {
|
|
99
|
-
return model;
|
|
100
|
-
}
|
|
101
|
-
if (doc.querySelector("parsererror")) return model;
|
|
102
|
-
const root = doc.documentElement;
|
|
103
|
-
if (!root || root.tagName !== "score-partwise") return model;
|
|
104
|
-
const parts = childrenNamed(root, "part");
|
|
105
|
-
let staffOffset = 0;
|
|
106
|
-
for (const part of parts) {
|
|
107
|
-
const staffCount = partStaffCount(part);
|
|
108
|
-
let divisions = 1;
|
|
109
|
-
const measureEls = childrenNamed(part, "measure");
|
|
110
|
-
measureEls.forEach((measureEl, measureIndex) => {
|
|
111
|
-
for (const child of Array.from(measureEl.children)) {
|
|
112
|
-
if (child.tagName === "attributes") {
|
|
113
|
-
const divText = textOf(firstChildNamed(child, "divisions"));
|
|
114
|
-
if (divText) divisions = Number(divText) || divisions;
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
if (child.tagName !== "note") continue;
|
|
118
|
-
const note = child;
|
|
119
|
-
const id = note.getAttribute("id");
|
|
120
|
-
if (!id) continue;
|
|
121
|
-
const isGrace = !!firstChildNamed(note, "grace");
|
|
122
|
-
const isRest = !!firstChildNamed(note, "rest");
|
|
123
|
-
const pitchEl = firstChildNamed(note, "pitch");
|
|
124
|
-
const staffNumber = Number(textOf(firstChildNamed(note, "staff")) ?? "1") || 1;
|
|
125
|
-
const durationText = textOf(firstChildNamed(note, "duration"));
|
|
126
|
-
const durationReal = isGrace || !durationText ? 0 : Number(durationText) / divisions / 4;
|
|
127
|
-
const tieStopDirect = childrenNamed(note, "tie").some((t) => t.getAttribute("type") === "stop");
|
|
128
|
-
const notationsEl = firstChildNamed(note, "notations");
|
|
129
|
-
const tieStopNotated = notationsEl ? childrenNamed(notationsEl, "tied").some((t) => t.getAttribute("type") === "stop") : false;
|
|
130
|
-
model.set(id, {
|
|
131
|
-
midi: pitchEl ? pitchMidiFromElement(pitchEl) : null,
|
|
132
|
-
isRest,
|
|
133
|
-
tieContinuation: tieStopDirect || tieStopNotated,
|
|
134
|
-
staffIndex: staffOffset + Math.max(0, staffNumber - 1),
|
|
135
|
-
durationReal,
|
|
136
|
-
measureIndex,
|
|
137
|
-
hidden: note.getAttribute("print-object") === "no"
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
staffOffset += staffCount;
|
|
142
|
-
}
|
|
143
|
-
return model;
|
|
144
|
-
}
|
|
13
|
+
import {
|
|
14
|
+
balancedSystemBreaks,
|
|
15
|
+
injectSystemBreaks,
|
|
16
|
+
measureCount,
|
|
17
|
+
noteModelFromXml,
|
|
18
|
+
sectionAwareBreaks,
|
|
19
|
+
stampNoteIds
|
|
20
|
+
} from "./chunk-JCDNEJBT.js";
|
|
145
21
|
|
|
146
22
|
// src/notationPlayerVerovio.ts
|
|
147
23
|
var MARKED_NOTE_CLASS = "rmp-note-marked";
|
|
@@ -396,7 +272,13 @@ var VEROVIO_LAYOUT_DEFAULTS = {
|
|
|
396
272
|
};
|
|
397
273
|
function verovioRenderOptions(hostWidthPx, zoom, layout) {
|
|
398
274
|
const { scale, pageWidth } = verovioZoomOptions(hostWidthPx, zoom);
|
|
399
|
-
const {
|
|
275
|
+
const {
|
|
276
|
+
avoidWidows: _avoidWidows,
|
|
277
|
+
minFitFactor: _minFitFactor,
|
|
278
|
+
barsPerLine: _barsPerLine,
|
|
279
|
+
sectionStarts: _sectionStarts,
|
|
280
|
+
...verovioLayout
|
|
281
|
+
} = layout ?? {};
|
|
400
282
|
return {
|
|
401
283
|
...VEROVIO_LAYOUT_DEFAULTS,
|
|
402
284
|
...verovioLayout,
|
|
@@ -470,6 +352,14 @@ function createVerovioNotationPlayer(opts) {
|
|
|
470
352
|
}
|
|
471
353
|
const stampedXml = opts.rendered ? musicXml : stampNoteIds(musicXml);
|
|
472
354
|
const noteModel = opts.rendered ? /* @__PURE__ */ new Map() : noteModelFromXml(stampedXml);
|
|
355
|
+
const breakPlan = (() => {
|
|
356
|
+
const layout = opts.verovioOptions;
|
|
357
|
+
const starts = layout?.sectionStarts ?? [];
|
|
358
|
+
const every = layout?.barsPerLine ?? 0;
|
|
359
|
+
if (!starts.length && !(every > 0)) return [];
|
|
360
|
+
return sectionAwareBreaks(measureCount(stampedXml), starts, every);
|
|
361
|
+
})();
|
|
362
|
+
const plannedXml = breakPlan.length ? injectSystemBreaks(stampedXml, breakPlan) : stampedXml;
|
|
473
363
|
const root = document.createElement("div");
|
|
474
364
|
root.style.position = "relative";
|
|
475
365
|
root.style.width = "100%";
|
|
@@ -581,11 +471,12 @@ function createVerovioNotationPlayer(opts) {
|
|
|
581
471
|
}
|
|
582
472
|
function engraveOnce(toolkit, widthPx, zoom) {
|
|
583
473
|
const layoutOpts = opts.verovioOptions;
|
|
584
|
-
const
|
|
474
|
+
const planLayoutOpts = breakPlan.length ? { ...layoutOpts, breaks: "line" } : layoutOpts;
|
|
475
|
+
const effectiveBreaks = planLayoutOpts?.breaks ?? VEROVIO_LAYOUT_DEFAULTS.breaks;
|
|
585
476
|
const minFitFactor = layoutOpts?.minFitFactor ?? DEFAULT_MIN_FIT_FACTOR;
|
|
586
477
|
const avoidWidows = layoutOpts?.avoidWidows !== false;
|
|
587
|
-
let xmlToRender =
|
|
588
|
-
let renderLayoutOpts =
|
|
478
|
+
let xmlToRender = plannedXml;
|
|
479
|
+
let renderLayoutOpts = planLayoutOpts;
|
|
589
480
|
toolkit.setOptions(verovioRenderOptions(widthPx, zoom, renderLayoutOpts));
|
|
590
481
|
const ok = !!toolkit.loadData(xmlToRender);
|
|
591
482
|
if (ok) renderAllPages(toolkit);
|