@braccato/core 1.17.1 → 1.19.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/engine.js CHANGED
@@ -2024,7 +2024,7 @@ function prepareUpcomingLineScroll(engine, lines, activeLine, scrollDeltaPx, fro
2024
2024
  }
2025
2025
  }
2026
2026
  // -- Skip Scrolls Decay --------------------------
2027
- function decaySkipScrolls(engine, now) {
2027
+ function decaySkipScrolls(engine, now, keepsReserve) {
2028
2028
  let j = 0;
2029
2029
  for (; j < engine.skipScrollsDecayTimes.length; j++) {
2030
2030
  if (engine.skipScrollsDecayTimes[j] > now) {
@@ -2032,10 +2032,7 @@ function decaySkipScrolls(engine, now) {
2032
2032
  }
2033
2033
  }
2034
2034
  engine.skipScrollsDecayTimes = engine.skipScrollsDecayTimes.slice(j);
2035
- engine.skipScrolls -= j;
2036
- if (engine.skipScrolls < 1) {
2037
- engine.skipScrolls = 1;
2038
- }
2035
+ engine.skipScrolls = Math.max(keepsReserve ? 1 : 0, engine.skipScrolls - j);
2039
2036
  }
2040
2037
  // -- Passive Scroll Engine --------------------------
2041
2038
  /**
@@ -2235,6 +2232,8 @@ export function resolveTickOptions(options) {
2235
2232
  lineOffsetTrim: options.lineOffsetTrim ?? 0,
2236
2233
  passiveScrollEnabled: options.passiveScrollEnabled ?? false,
2237
2234
  playbackRate: resolvePlaybackRate(options.playbackRate),
2235
+ followPausedSeeks: options.followPausedSeeks ?? false,
2236
+ countEveryUserScroll: options.countEveryUserScroll ?? false,
2238
2237
  };
2239
2238
  }
2240
2239
  // A rate of zero or less would freeze every animation that follows the song, which is a second
@@ -2547,7 +2546,7 @@ export function tickView(engine, currentTime, options) {
2547
2546
  currentTime < playbackClock.lastTime - CLOCK_RESYNC_THRESHOLD_S;
2548
2547
  // A clock that was already paused only moves when the host seeks it, however small the step, as a
2549
2548
  // scrub does. The tick that pauses lands a moment past the last playing one and is not a seek.
2550
- const pausedSeek = !isPlaying && !playbackClock.lastPlayState && currentTime !== playbackClock.lastTime;
2549
+ const pausedSeek = options.followPausedSeeks && !isPlaying && !playbackClock.lastPlayState && currentTime !== playbackClock.lastTime;
2551
2550
  if (timeJumped)
2552
2551
  dropPendingLineScroll(engine);
2553
2552
  playbackClock.lastTime = currentTime;
@@ -2884,9 +2883,12 @@ export function tickView(engine, currentTime, options) {
2884
2883
  }
2885
2884
  scrollTop = scrollPos;
2886
2885
  engine.scrollPos = scrollTop;
2886
+ const scrollTopBeforeWrite = tabRenderer.scrollTop;
2887
2887
  tabRenderer.scrollTop = scrollTop;
2888
- engine.skipScrolls += 1;
2889
- engine.skipScrollsDecayTimes.push(Date.now() + 2000);
2888
+ if (tabRenderer.scrollTop !== scrollTopBeforeWrite) {
2889
+ engine.skipScrolls += 1;
2890
+ engine.skipScrollsDecayTimes.push(Date.now() + 2000);
2891
+ }
2890
2892
  }
2891
2893
  }
2892
2894
  if (engine.wasUserScrolling && engine.scrollResumeTime < Date.now()) {
@@ -2894,7 +2896,7 @@ export function tickView(engine, currentTime, options) {
2894
2896
  lyricsElement.classList.remove(USER_SCROLLING_CLASS);
2895
2897
  engine.wasUserScrolling = false;
2896
2898
  }
2897
- decaySkipScrolls(engine, now);
2899
+ decaySkipScrolls(engine, now, !options.countEveryUserScroll);
2898
2900
  }
2899
2901
  catch (err) {
2900
2902
  if (!err.message?.includes("undefined")) {
package/dist/types.d.ts CHANGED
@@ -36,6 +36,18 @@ export interface TickOptions {
36
36
  * interface's own gestures and keep the timing the theme asked for at every rate.
37
37
  */
38
38
  playbackRate?: number;
39
+ /**
40
+ * Whether a paused clock that moves by less than the jump threshold resets the highlight to the
41
+ * new time, as an editor scrubbing a paused song needs. Defaults to false.
42
+ */
43
+ followPausedSeeks?: boolean;
44
+ /**
45
+ * Whether every user scroll the host reports can pause autoscroll of synced lyrics. By default
46
+ * the view always holds one scroll back, for the one a refocused window fires, and a host that
47
+ * ticks every frame spends that reserve on each scroll the reader makes. Unsynced lyrics drifting
48
+ * on their own are not covered. Defaults to false.
49
+ */
50
+ countEveryUserScroll?: boolean;
39
51
  }
40
52
  /**
41
53
  * A tick with nothing left out. The engine reads every field unconditionally, so the defaults are
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@braccato/core",
3
- "version": "1.17.1",
3
+ "version": "1.19.0",
4
4
  "description": "Synchronized lyrics renderer with word-by-word animations",
5
5
  "type": "module",
6
6
  "license": "MIT",