@braccato/core 1.19.1 → 1.20.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/inject.js +39 -21
- package/dist/view.js +1 -0
- package/package.json +2 -2
package/dist/inject.js
CHANGED
|
@@ -140,6 +140,7 @@ function splitPartIntoTokens(part) {
|
|
|
140
140
|
part: {
|
|
141
141
|
words: chunk,
|
|
142
142
|
isBackground: part.isBackground,
|
|
143
|
+
backgroundGroup: part.backgroundGroup,
|
|
143
144
|
explicit: part.explicit,
|
|
144
145
|
},
|
|
145
146
|
});
|
|
@@ -166,7 +167,7 @@ function splitPartIntoTokens(part) {
|
|
|
166
167
|
function normalizeParts(parts) {
|
|
167
168
|
return parts.flatMap(splitPartIntoTokens);
|
|
168
169
|
}
|
|
169
|
-
function groupTokensByWord(tokens) {
|
|
170
|
+
function groupTokensByWord(tokens, splitBackgroundGroups) {
|
|
170
171
|
const groups = [];
|
|
171
172
|
let current = null;
|
|
172
173
|
const flush = () => {
|
|
@@ -182,9 +183,10 @@ function groupTokensByWord(tokens) {
|
|
|
182
183
|
continue;
|
|
183
184
|
}
|
|
184
185
|
const isBackground = token.part?.isBackground === true;
|
|
185
|
-
|
|
186
|
+
const backgroundGroup = splitBackgroundGroups ? token.part?.backgroundGroup : undefined;
|
|
187
|
+
if (!current || current.isBackground !== isBackground || current.backgroundGroup !== backgroundGroup) {
|
|
186
188
|
flush();
|
|
187
|
-
current = { text: "", isBackground, tokens: [] };
|
|
189
|
+
current = { text: "", isBackground, backgroundGroup, tokens: [] };
|
|
188
190
|
}
|
|
189
191
|
current.text += token.text;
|
|
190
192
|
current.tokens.push(token);
|
|
@@ -331,24 +333,36 @@ export function createLyricsLine(doc, parts, line, lyricElement, options = { spl
|
|
|
331
333
|
.map(part => part.words)
|
|
332
334
|
.join("")
|
|
333
335
|
: lineText;
|
|
334
|
-
const
|
|
335
|
-
.filter(part => part.isBackground === true)
|
|
336
|
+
const backgroundTextOf = (group) => parts
|
|
337
|
+
.filter(part => part.isBackground === true && (part.backgroundGroup ?? 0) === group)
|
|
336
338
|
.map(part => part.words)
|
|
337
339
|
.join("");
|
|
338
340
|
const main = createContentLine(doc, LINE_MAIN_CLASS, mainText);
|
|
339
341
|
const mainRun = createBidiRun(doc, mainText);
|
|
340
342
|
const mainHighlightRun = createHighlightRun(doc, mainText);
|
|
341
|
-
const groupedTokens = groupTokensByWord(normalizeParts(parts));
|
|
342
|
-
const
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
343
|
+
const groupedTokens = groupTokensByWord(normalizeParts(parts), options.splitBackgroundLine);
|
|
344
|
+
const backgroundRows = new Map();
|
|
345
|
+
const backgroundRowOf = (group) => {
|
|
346
|
+
let row = backgroundRows.get(group);
|
|
347
|
+
if (!row) {
|
|
348
|
+
const text = backgroundTextOf(group);
|
|
349
|
+
row = {
|
|
350
|
+
line: createContentLine(doc, BACKGROUND_LINE_CLASS, text),
|
|
351
|
+
run: createBidiRun(doc, text),
|
|
352
|
+
highlightRun: createHighlightRun(doc, text),
|
|
353
|
+
used: false,
|
|
354
|
+
};
|
|
355
|
+
row.line.appendChild(row.highlightRun);
|
|
356
|
+
row.line.appendChild(row.run);
|
|
357
|
+
backgroundRows.set(group, row);
|
|
358
|
+
}
|
|
359
|
+
return row;
|
|
360
|
+
};
|
|
361
|
+
backgroundRowOf(0);
|
|
346
362
|
let pendingForegroundSpace = "";
|
|
347
363
|
let pendingBackgroundSpace = "";
|
|
348
364
|
main.appendChild(mainHighlightRun);
|
|
349
365
|
main.appendChild(mainRun);
|
|
350
|
-
backgroundLine.appendChild(backgroundHighlightRun);
|
|
351
|
-
backgroundLine.appendChild(backgroundRun);
|
|
352
366
|
for (const item of groupedTokens) {
|
|
353
367
|
if ("kind" in item) {
|
|
354
368
|
// Is a RenderToken, not a WordGroup, only whitespace should enter this path
|
|
@@ -357,8 +371,9 @@ export function createLyricsLine(doc, parts, line, lyricElement, options = { spl
|
|
|
357
371
|
}
|
|
358
372
|
else {
|
|
359
373
|
const shouldUseBackgroundLine = options.splitBackgroundLine && item.isBackground;
|
|
360
|
-
const
|
|
361
|
-
const
|
|
374
|
+
const backgroundRow = shouldUseBackgroundLine ? backgroundRowOf(item.backgroundGroup ?? 0) : null;
|
|
375
|
+
const target = backgroundRow ? backgroundRow.run : mainRun;
|
|
376
|
+
const highlightRun = backgroundRow ? backgroundRow.highlightRun : mainHighlightRun;
|
|
362
377
|
const pendingSpace = shouldUseBackgroundLine ? pendingBackgroundSpace : pendingForegroundSpace;
|
|
363
378
|
if (target.childNodes.length > 0 && pendingSpace.length > 0) {
|
|
364
379
|
target.appendChild(createSpaceNode(doc, pendingSpace, shouldUseBackgroundLine));
|
|
@@ -367,8 +382,8 @@ export function createLyricsLine(doc, parts, line, lyricElement, options = { spl
|
|
|
367
382
|
const { lyricGroup, highlightGroup } = createWordGroup(doc, item, line);
|
|
368
383
|
target.appendChild(lyricGroup);
|
|
369
384
|
highlightRun.appendChild(highlightGroup);
|
|
370
|
-
if (
|
|
371
|
-
|
|
385
|
+
if (backgroundRow) {
|
|
386
|
+
backgroundRow.used = true;
|
|
372
387
|
pendingBackgroundSpace = "";
|
|
373
388
|
}
|
|
374
389
|
else {
|
|
@@ -376,13 +391,16 @@ export function createLyricsLine(doc, parts, line, lyricElement, options = { spl
|
|
|
376
391
|
}
|
|
377
392
|
}
|
|
378
393
|
}
|
|
394
|
+
const usedBackgroundRows = [...backgroundRows]
|
|
395
|
+
.filter(([, row]) => row.used)
|
|
396
|
+
.sort(([a], [b]) => a - b)
|
|
397
|
+
.map(([, row]) => row);
|
|
379
398
|
alignImageGlowRun(mainHighlightRun, line.parts);
|
|
380
|
-
|
|
381
|
-
alignImageGlowRun(
|
|
399
|
+
for (const row of usedBackgroundRows)
|
|
400
|
+
alignImageGlowRun(row.highlightRun, line.parts);
|
|
382
401
|
lyricElement.appendChild(main);
|
|
383
|
-
|
|
384
|
-
lyricElement.appendChild(
|
|
385
|
-
}
|
|
402
|
+
for (const row of usedBackgroundRows)
|
|
403
|
+
lyricElement.appendChild(row.line);
|
|
386
404
|
return main;
|
|
387
405
|
}
|
|
388
406
|
export function buildLineSyncedParts(item) {
|
package/dist/view.js
CHANGED
|
@@ -114,6 +114,7 @@ function lineSignature(lyrics, lineIndex) {
|
|
|
114
114
|
part.durationMs,
|
|
115
115
|
part.words,
|
|
116
116
|
part.isBackground === true,
|
|
117
|
+
part.backgroundGroup ?? null,
|
|
117
118
|
part.explicit === true,
|
|
118
119
|
]);
|
|
119
120
|
// An instrumental line takes its side and direction from the lines around it.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@braccato/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.0",
|
|
4
4
|
"description": "Synchronized lyrics renderer with word-by-word animations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"access": "public"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@braccato/types": "^1.
|
|
60
|
+
"@braccato/types": "^1.1.0"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"build": "tsx ../../tooling/build-package.ts",
|