@braccato/core 1.16.10 → 1.16.12
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 +9 -0
- package/dist/engine.js +27 -9
- package/dist/view.js +2 -2
- package/package.json +1 -1
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
|
-
|
|
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);
|
|
@@ -2428,6 +2443,9 @@ export function tickView(engine, currentTime, options) {
|
|
|
2428
2443
|
if (isPlaying)
|
|
2429
2444
|
lineData.isAnimating = false; // reset the animation against current media time
|
|
2430
2445
|
}
|
|
2446
|
+
// Lead-in animations have no timing sample for the drift check, so a jump while playing must reset them.
|
|
2447
|
+
if (timeJumped && isPlaying && lineData.isAnimating)
|
|
2448
|
+
resetLineAnimationState(lineData);
|
|
2431
2449
|
updateWordStates(lineData, currentTime);
|
|
2432
2450
|
const nativeTimingSample = lineNativeTimingSample(lineData, currentTime);
|
|
2433
2451
|
let usedNativeTimingSampleForDrift = false;
|
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);
|