@braccato/core 1.18.0 → 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
  /**
@@ -2236,6 +2233,7 @@ export function resolveTickOptions(options) {
2236
2233
  passiveScrollEnabled: options.passiveScrollEnabled ?? false,
2237
2234
  playbackRate: resolvePlaybackRate(options.playbackRate),
2238
2235
  followPausedSeeks: options.followPausedSeeks ?? false,
2236
+ countEveryUserScroll: options.countEveryUserScroll ?? false,
2239
2237
  };
2240
2238
  }
2241
2239
  // A rate of zero or less would freeze every animation that follows the song, which is a second
@@ -2885,9 +2883,12 @@ export function tickView(engine, currentTime, options) {
2885
2883
  }
2886
2884
  scrollTop = scrollPos;
2887
2885
  engine.scrollPos = scrollTop;
2886
+ const scrollTopBeforeWrite = tabRenderer.scrollTop;
2888
2887
  tabRenderer.scrollTop = scrollTop;
2889
- engine.skipScrolls += 1;
2890
- engine.skipScrollsDecayTimes.push(Date.now() + 2000);
2888
+ if (tabRenderer.scrollTop !== scrollTopBeforeWrite) {
2889
+ engine.skipScrolls += 1;
2890
+ engine.skipScrollsDecayTimes.push(Date.now() + 2000);
2891
+ }
2891
2892
  }
2892
2893
  }
2893
2894
  if (engine.wasUserScrolling && engine.scrollResumeTime < Date.now()) {
@@ -2895,7 +2896,7 @@ export function tickView(engine, currentTime, options) {
2895
2896
  lyricsElement.classList.remove(USER_SCROLLING_CLASS);
2896
2897
  engine.wasUserScrolling = false;
2897
2898
  }
2898
- decaySkipScrolls(engine, now);
2899
+ decaySkipScrolls(engine, now, !options.countEveryUserScroll);
2899
2900
  }
2900
2901
  catch (err) {
2901
2902
  if (!err.message?.includes("undefined")) {
package/dist/types.d.ts CHANGED
@@ -41,6 +41,13 @@ export interface TickOptions {
41
41
  * new time, as an editor scrubbing a paused song needs. Defaults to false.
42
42
  */
43
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;
44
51
  }
45
52
  /**
46
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.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "Synchronized lyrics renderer with word-by-word animations",
5
5
  "type": "module",
6
6
  "license": "MIT",