@braccato/core 1.16.10 → 1.16.11

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.d.ts CHANGED
@@ -65,6 +65,11 @@ export interface AnimationEngineInstance extends AnimEngineViewState {
65
65
  * from a tick, so it has no options object to read.
66
66
  */
67
67
  passiveScrollEnabled: boolean;
68
+ /**
69
+ * Last options the tick was given, kept before any early return. A click reads its offsets to seek
70
+ * to where a line plays rather than to its unshifted time.
71
+ */
72
+ lastTickOptions: ResolvedTickOptions | null;
68
73
  playbackRate: number;
69
74
  passiveRAFId: number | null;
70
75
  pendingLyricsUpdateFrame: number | null;
@@ -357,6 +362,10 @@ export type AnimationTickStatus = "ok" | "lyrics-missing";
357
362
  */
358
363
  export declare function resolveTickOptions(options: TickOptions): ResolvedTickOptions;
359
364
  export declare function measureStage(engine: AnimationEngineInstance): void;
365
+ /**
366
+ * The player time at which a lyric time plays, under the offsets of the last tick.
367
+ */
368
+ export declare function playerTimeForLyricTime(engine: AnimationEngineInstance, lyricTimeS: number): number;
360
369
  /**
361
370
  * Renders one view against a tick with nothing left out.
362
371
  */
package/dist/engine.js CHANGED
@@ -154,6 +154,7 @@ export function createAnimationEngineInstance(engineDocument, engineWindow, host
154
154
  cachedCSSValues: new Map(),
155
155
  cachedAnimationSettings: null,
156
156
  passiveScrollEnabled: false,
157
+ lastTickOptions: null,
157
158
  playbackRate: 1,
158
159
  passiveRAFId: null,
159
160
  pendingLyricsUpdateFrame: null,
@@ -2276,11 +2277,33 @@ function applyStage(engine, timeS, instant) {
2276
2277
  engine.host.onStageLayout?.(box);
2277
2278
  }
2278
2279
  }
2280
+ /**
2281
+ * Seconds to add to the player time to get the lyric time this view renders: the theme's offset
2282
+ * and the trim for its sync type, less the global and per-song offsets.
2283
+ */
2284
+ function lyricClockShiftS(engine, lyricsElement, options) {
2285
+ const syncTypeShiftS = engine.syncType === "richsync"
2286
+ ? getCSSDurationInMs(engine, lyricsElement, "--blyrics-richsync-timing-offset") / 1000 -
2287
+ options.richsyncOffsetTrim
2288
+ : getCSSDurationInMs(engine, lyricsElement, "--blyrics-timing-offset") / 1000 - options.lineOffsetTrim;
2289
+ return syncTypeShiftS - options.globalLyricOffset - options.lyricOffset;
2290
+ }
2291
+ /**
2292
+ * The player time at which a lyric time plays, under the offsets of the last tick.
2293
+ */
2294
+ export function playerTimeForLyricTime(engine, lyricTimeS) {
2295
+ const options = engine.lastTickOptions;
2296
+ const lyricsElement = engine.lyricsContainer;
2297
+ if (!options || !lyricsElement)
2298
+ return lyricTimeS;
2299
+ return Math.max(0, lyricTimeS - lyricClockShiftS(engine, lyricsElement, options));
2300
+ }
2279
2301
  /**
2280
2302
  * Renders one view against a tick with nothing left out.
2281
2303
  */
2282
2304
  export function tickView(engine, currentTime, options) {
2283
2305
  const { eventCreationTime, isPlaying, smoothScroll } = options;
2306
+ engine.lastTickOptions = options;
2284
2307
  engine.passiveScrollEnabled = options.passiveScrollEnabled;
2285
2308
  if (engine.playbackRate !== options.playbackRate) {
2286
2309
  engine.playbackRate = options.playbackRate;
@@ -2341,15 +2364,7 @@ export function tickView(engine, currentTime, options) {
2341
2364
  return "lyrics-missing";
2342
2365
  }
2343
2366
  const lines = engine.lines;
2344
- if (engine.syncType === "richsync") {
2345
- currentTime += getCSSDurationInMs(engine, lyricsElement, "--blyrics-richsync-timing-offset") / 1000;
2346
- currentTime -= options.richsyncOffsetTrim;
2347
- }
2348
- else {
2349
- currentTime += getCSSDurationInMs(engine, lyricsElement, "--blyrics-timing-offset") / 1000;
2350
- currentTime -= options.lineOffsetTrim;
2351
- }
2352
- currentTime -= options.globalLyricOffset + options.lyricOffset;
2367
+ currentTime += lyricClockShiftS(engine, lyricsElement, options);
2353
2368
  const lyricScrollTime = correctedScrollTimeS(engine, currentTime) +
2354
2369
  getCSSDurationInMs(engine, lyricsElement, "--blyrics-scroll-timing-offset") / 1000;
2355
2370
  const { config: animationConfig, scrollTiming } = getAnimationSettings(engine, lyricsElement);
package/dist/view.js CHANGED
@@ -10,7 +10,7 @@
10
10
  // lines is where those values are first knowable: the container, the records, the sync type, the
11
11
  // size they were measured at, and the scrolls to swallow before the view has settled.
12
12
  import { CREDITS_CLASS, CREDITS_NAMES_CLASS, CREDITS_TEXT_CLASS, LINE_CLASS, LYRICS_CLASS, RTL_CLASS, } from "./constants.js";
13
- import { setupLineCullObserver } from "./engine.js";
13
+ import { playerTimeForLyricTime, setupLineCullObserver } from "./engine.js";
14
14
  import { addSeekHandler, applyDirection, buildLineSyncedParts, createLyricsLine, deriveSyncType, disableRichsync, findNearestAgent, hideCredits, isNearestLyricRtl, newLineData, } from "./inject.js";
15
15
  import { refreshInstrumentalImages } from "./imageHighlights.js";
16
16
  import { createInstrumentalElement } from "./instrumental.js";
@@ -78,7 +78,7 @@ export function setLyrics(engine, mount, lyrics, options) {
78
78
  container.dataset.browserEngine = "gecko";
79
79
  mount.replaceChildren(container);
80
80
  const allZero = lyrics.every(item => item.startTimeMs === 0);
81
- const seek = (timeS) => engine.host.seek(timeS);
81
+ const seek = (timeS) => engine.host.seek(playerTimeForLyricTime(engine, timeS));
82
82
  const lines = [];
83
83
  const syncType = deriveSyncType(lyrics);
84
84
  const languages = resolveLyricLanguages(lyrics, options.language);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@braccato/core",
3
- "version": "1.16.10",
3
+ "version": "1.16.11",
4
4
  "description": "Synchronized lyrics renderer with word-by-word animations",
5
5
  "type": "module",
6
6
  "license": "MIT",