@real-music-packages/web-core 0.21.0 → 0.22.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/dist/scene/index.d.ts +8 -9
- package/dist/scene/index.js +7 -24
- package/dist/scene/index.js.map +1 -1
- package/package.json +1 -1
package/dist/scene/index.d.ts
CHANGED
|
@@ -678,12 +678,11 @@ declare const notationFactory: LayerFactory<NotationProps>;
|
|
|
678
678
|
|
|
679
679
|
interface ScrollCursorProps {
|
|
680
680
|
/**
|
|
681
|
-
*
|
|
682
|
-
* note-by-note off the audio clock against each note's `onsetMs
|
|
683
|
-
*
|
|
684
|
-
*
|
|
685
|
-
*
|
|
686
|
-
* for back-compat; prefer leaving this unset.
|
|
681
|
+
* DEPRECATED / back-compat only. The cursor is ALWAYS audio-onset locked now —
|
|
682
|
+
* driven note-by-note off the audio clock against each note's `onsetMs` (see
|
|
683
|
+
* `ctx.score`). Both `'audio'` and `'linear'` resolve to that single onset path;
|
|
684
|
+
* `'linear'` no longer re-enables the legacy measure-linear sweep (removed —
|
|
685
|
+
* that was the drift footgun). Prefer leaving this unset.
|
|
687
686
|
*/
|
|
688
687
|
mode?: 'audio' | 'linear';
|
|
689
688
|
/**
|
|
@@ -704,9 +703,9 @@ interface ScrollCursorProps {
|
|
|
704
703
|
/** Opening-zoom duration in ms before the music/cursor start (RSR INTRO_MS=900).
|
|
705
704
|
* During this lead-in the follow window is held at the start. Default 900. */
|
|
706
705
|
openingZoomMs?: number;
|
|
707
|
-
/** Total music length in ms (RSR musicMs).
|
|
708
|
-
*
|
|
709
|
-
* and
|
|
706
|
+
/** DEPRECATED. Total music length in ms (RSR musicMs). No longer used to
|
|
707
|
+
* position the cursor (the onset clock drives all pacing); accepted for
|
|
708
|
+
* back-compat and ignored. */
|
|
710
709
|
musicMs?: number;
|
|
711
710
|
/** Cursor stroke colour. Defaults to theme.accent. */
|
|
712
711
|
color?: string;
|
package/dist/scene/index.js
CHANGED
|
@@ -818,25 +818,18 @@ var notationFactory = {
|
|
|
818
818
|
};
|
|
819
819
|
|
|
820
820
|
// src/scene/layers/scrollCursor.ts
|
|
821
|
-
function followLayoutFor(ctx,
|
|
821
|
+
function followLayoutFor(ctx, progress012, scrollMode) {
|
|
822
822
|
const eng = getNotationEngraving(ctx);
|
|
823
823
|
if (!eng) return null;
|
|
824
824
|
const nBars = measureCount(eng.rendered);
|
|
825
825
|
if (nBars <= 0) return eng.base;
|
|
826
|
-
const focusBox = scrollMode === "vstack" ? vstackFollowBox(eng.rendered,
|
|
826
|
+
const focusBox = scrollMode === "vstack" ? vstackFollowBox(eng.rendered, progress012) : followBoxAt(eng.rendered, followWindowStart(eng.rendered, progress012));
|
|
827
827
|
return notationLayout(eng.rendered, ctx.W, ctx.H, eng.bandTop, eng.bandHeight, { focusBox });
|
|
828
828
|
}
|
|
829
829
|
function scrollCursorLayer() {
|
|
830
|
-
let mode = "audio";
|
|
831
830
|
let scrollMode = "hstack";
|
|
832
|
-
let musicMs = 0;
|
|
833
831
|
let openingZoomMs = 900;
|
|
834
832
|
let color;
|
|
835
|
-
function camProgress(tMs) {
|
|
836
|
-
const phMs = tMs - openingZoomMs;
|
|
837
|
-
if (phMs < 0 || musicMs <= 0) return 0;
|
|
838
|
-
return Math.min(1, phMs / musicMs);
|
|
839
|
-
}
|
|
840
833
|
function onsetsFor(ctx) {
|
|
841
834
|
const notes = ctx.score?.notes;
|
|
842
835
|
return notes && notes.length ? distinctOnsets(notes) : [];
|
|
@@ -859,9 +852,7 @@ function scrollCursorLayer() {
|
|
|
859
852
|
return (lo + segFrac) / (n - 1);
|
|
860
853
|
}
|
|
861
854
|
function followProgress(ctx, tMs) {
|
|
862
|
-
|
|
863
|
-
const onsets = onsetsFor(ctx);
|
|
864
|
-
return onsets.length ? notesProgress(onsets, tMs) : camProgress(tMs);
|
|
855
|
+
return notesProgress(onsetsFor(ctx), tMs);
|
|
865
856
|
}
|
|
866
857
|
function layoutAt(ctx, tMs) {
|
|
867
858
|
const eng = getNotationEngraving(ctx);
|
|
@@ -870,9 +861,7 @@ function scrollCursorLayer() {
|
|
|
870
861
|
return {
|
|
871
862
|
key: "scroll-cursor",
|
|
872
863
|
init(ctx, props) {
|
|
873
|
-
mode = props.mode ?? "audio";
|
|
874
864
|
scrollMode = props.scrollMode ?? "hstack";
|
|
875
|
-
musicMs = props.musicMs ?? 0;
|
|
876
865
|
openingZoomMs = props.openingZoomMs ?? 900;
|
|
877
866
|
color = props.color;
|
|
878
867
|
setFollowLayoutProvider(ctx, layoutAt);
|
|
@@ -881,16 +870,12 @@ function scrollCursorLayer() {
|
|
|
881
870
|
const eng = getNotationEngraving(ctx);
|
|
882
871
|
if (!eng) return;
|
|
883
872
|
const layout = layoutAt(ctx, tMs);
|
|
873
|
+
const onsets = onsetsFor(ctx);
|
|
884
874
|
let line;
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
if (scrollMode === "vstack") {
|
|
888
|
-
line = vstackAudioPlayheadLine(layout, onsets, tMs, measureCount(eng.rendered));
|
|
889
|
-
} else {
|
|
890
|
-
line = audioPlayheadLine(layout, onsets, tMs);
|
|
891
|
-
}
|
|
875
|
+
if (scrollMode === "vstack") {
|
|
876
|
+
line = vstackAudioPlayheadLine(layout, onsets, tMs, measureCount(eng.rendered));
|
|
892
877
|
} else {
|
|
893
|
-
line =
|
|
878
|
+
line = audioPlayheadLine(layout, onsets, tMs);
|
|
894
879
|
}
|
|
895
880
|
if (!line) return;
|
|
896
881
|
const c = ctx.ctx2d;
|
|
@@ -917,8 +902,6 @@ var scrollCursorFactory = {
|
|
|
917
902
|
errs.push('scroll-cursor.mode must be "audio" | "linear"');
|
|
918
903
|
if (p.scrollMode != null && p.scrollMode !== "hstack" && p.scrollMode !== "vstack")
|
|
919
904
|
errs.push('scroll-cursor.scrollMode must be "hstack" | "vstack"');
|
|
920
|
-
if (p.mode === "linear" && (typeof p.musicMs !== "number" || !(p.musicMs > 0)))
|
|
921
|
-
errs.push('scroll-cursor.musicMs must be a positive number for mode:"linear"');
|
|
922
905
|
if (p.musicMs != null && (typeof p.musicMs !== "number" || !(p.musicMs > 0)))
|
|
923
906
|
errs.push("scroll-cursor.musicMs must be a positive number");
|
|
924
907
|
if (p.followBars != null && (typeof p.followBars !== "number" || p.followBars < 1))
|