@tongue-core/ui 0.1.0-rc.4 → 0.1.0-rc.5
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/timeline/index.d.ts
CHANGED
|
@@ -6,4 +6,5 @@ export { ruler, stepFor, minorFor, rulerLabel, timecode, LABEL_SPACING, MINOR_SP
|
|
|
6
6
|
export { reduceSelection, emptySelection, type Selection, type SelectionAction } from "./selection.js";
|
|
7
7
|
export { rowItems, rowTransitions, clipInRun, octaveOf, sameRowItems, MIN_CLIP_PX, type RowItem } from "./items.js";
|
|
8
8
|
export { filmstrip, PreviewCache, type PreviewSource, type StripFrame } from "./previews.js";
|
|
9
|
+
export { narration, wordAt, wordsIn, lastStartedBy, type NarrationWord } from "./narration.js";
|
|
9
10
|
export { BUDGETS, type Budgets } from "../budgets.js";
|
package/dist/timeline/index.js
CHANGED
|
@@ -10,4 +10,5 @@ export { ruler, stepFor, minorFor, rulerLabel, timecode, LABEL_SPACING, MINOR_SP
|
|
|
10
10
|
export { reduceSelection, emptySelection } from "./selection.js";
|
|
11
11
|
export { rowItems, rowTransitions, clipInRun, octaveOf, sameRowItems, MIN_CLIP_PX } from "./items.js";
|
|
12
12
|
export { filmstrip, PreviewCache } from "./previews.js";
|
|
13
|
+
export { narration, wordAt, wordsIn, lastStartedBy } from "./narration.js";
|
|
13
14
|
export { BUDGETS } from "../budgets.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FilmDoc } from "@tongue-core/project/doc";
|
|
2
|
+
export interface NarrationWord {
|
|
3
|
+
readonly text: string;
|
|
4
|
+
/** Film frames [start, end). */
|
|
5
|
+
readonly start: number;
|
|
6
|
+
readonly end: number;
|
|
7
|
+
/** The clip it is said in, and its row. */
|
|
8
|
+
readonly clip: string;
|
|
9
|
+
readonly row: string;
|
|
10
|
+
}
|
|
11
|
+
/** Every word of the film's narration on the film's clock, by start. Empty for a film with none. */
|
|
12
|
+
export declare function narration(doc: FilmDoc): ReadonlyArray<NarrationWord>;
|
|
13
|
+
/** The index of the last word that has started by `frame`; -1 before the first. */
|
|
14
|
+
export declare function lastStartedBy(words: ReadonlyArray<NarrationWord>, frame: number): number;
|
|
15
|
+
/** The word being said at `frame` (its start reached, its end not), or null between words. */
|
|
16
|
+
export declare function wordAt(words: ReadonlyArray<NarrationWord>, frame: number): NarrationWord | null;
|
|
17
|
+
/** The words said in `[from, to)`, in order. */
|
|
18
|
+
export declare const wordsIn: (words: ReadonlyArray<NarrationWord>, from: number, to: number) => ReadonlyArray<NarrationWord>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Every word of the film's narration on the film's clock, by start. Empty for a film with none. */
|
|
2
|
+
export function narration(doc) {
|
|
3
|
+
const out = [];
|
|
4
|
+
for (const track of doc.tracks) {
|
|
5
|
+
for (const clip of track.clips) {
|
|
6
|
+
if (clip.kind !== "audio" || clip.voice === undefined)
|
|
7
|
+
continue;
|
|
8
|
+
for (const word of clip.voice.words) {
|
|
9
|
+
const start = clip.start + word.start / clip.speed;
|
|
10
|
+
const end = clip.start + word.end / clip.speed;
|
|
11
|
+
if (start >= clip.end)
|
|
12
|
+
continue;
|
|
13
|
+
out.push({ text: word.text, start, end: Math.min(end, clip.end), clip: clip.id, row: track.id });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return out.sort((a, b) => a.start - b.start || a.end - b.end);
|
|
18
|
+
}
|
|
19
|
+
/** The index of the last word that has started by `frame`; -1 before the first. */
|
|
20
|
+
export function lastStartedBy(words, frame) {
|
|
21
|
+
let low = 0;
|
|
22
|
+
let high = words.length - 1;
|
|
23
|
+
let found = -1;
|
|
24
|
+
while (low <= high) {
|
|
25
|
+
const mid = (low + high) >>> 1;
|
|
26
|
+
if ((words[mid]?.start ?? Number.POSITIVE_INFINITY) <= frame) {
|
|
27
|
+
found = mid;
|
|
28
|
+
low = mid + 1;
|
|
29
|
+
}
|
|
30
|
+
else
|
|
31
|
+
high = mid - 1;
|
|
32
|
+
}
|
|
33
|
+
return found;
|
|
34
|
+
}
|
|
35
|
+
/** The word being said at `frame` (its start reached, its end not), or null between words. */
|
|
36
|
+
export function wordAt(words, frame) {
|
|
37
|
+
const index = lastStartedBy(words, frame);
|
|
38
|
+
const word = words[index];
|
|
39
|
+
return word !== undefined && frame < word.end ? word : null;
|
|
40
|
+
}
|
|
41
|
+
/** The words said in `[from, to)`, in order. */
|
|
42
|
+
export const wordsIn = (words, from, to) => words.filter((word) => word.end > from && word.start < to);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tongue-core/ui",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.5",
|
|
4
4
|
"description": "The pieces of a film's interface: the player, the timeline's state and geometry, and unstyled React primitives. Build your own studio from them.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"README.md"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@tongue-core/engine": "0.1.0-rc.
|
|
40
|
-
"@tongue-core/film": "0.1.0-rc.
|
|
41
|
-
"@tongue-core/project": "0.1.0-rc.
|
|
39
|
+
"@tongue-core/engine": "0.1.0-rc.5",
|
|
40
|
+
"@tongue-core/film": "0.1.0-rc.5",
|
|
41
|
+
"@tongue-core/project": "0.1.0-rc.5"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"@effect/atom-react": "^4.0.6",
|