@phont-ai/subtitles-core 0.1.10 → 0.2.2
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/README.md +51 -0
- package/dist/browser.d.mts +140 -0
- package/dist/browser.d.ts +140 -0
- package/dist/browser.js +1 -0
- package/dist/browser.mjs +1 -0
- package/dist/index.d.mts +523 -403
- package/dist/index.d.ts +1463 -7
- package/dist/index.js +3 -5414
- package/dist/index.mjs +3 -5347
- package/dist/phont-subtitles.global.js +2 -0
- package/package.json +37 -14
- package/dist/client/PhontClient.d.ts +0 -16
- package/dist/types/registration.d.ts +0 -46
- package/dist/utils/video-handling.d.ts +0 -33
- package/dist/validation/registration.d.ts +0 -64
package/dist/index.d.mts
CHANGED
|
@@ -45,6 +45,128 @@ interface PhontClientOptions {
|
|
|
45
45
|
apiBaseUrl?: string;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Animation Types
|
|
50
|
+
*
|
|
51
|
+
* Type definitions for animation parameter states, curves, and animation state
|
|
52
|
+
*/
|
|
53
|
+
interface CurvePoint {
|
|
54
|
+
time: number;
|
|
55
|
+
value: number | string;
|
|
56
|
+
}
|
|
57
|
+
interface ParameterState {
|
|
58
|
+
points: CurvePoint[];
|
|
59
|
+
currentValue?: number | string;
|
|
60
|
+
}
|
|
61
|
+
interface ParameterStates {
|
|
62
|
+
[key: string]: ParameterState;
|
|
63
|
+
}
|
|
64
|
+
interface AnimationParameterStates {
|
|
65
|
+
parameterStates: ParameterStates;
|
|
66
|
+
duration?: number;
|
|
67
|
+
format?: 'normalized' | 'absolute';
|
|
68
|
+
fontData?: {
|
|
69
|
+
style?: {
|
|
70
|
+
fontFamily?: string;
|
|
71
|
+
[key: string]: unknown;
|
|
72
|
+
};
|
|
73
|
+
config?: unknown;
|
|
74
|
+
fontId?: string | null;
|
|
75
|
+
fontName?: string | null;
|
|
76
|
+
};
|
|
77
|
+
text?: string;
|
|
78
|
+
name?: string;
|
|
79
|
+
}
|
|
80
|
+
interface AnimationState {
|
|
81
|
+
fontSize: number;
|
|
82
|
+
scale: number;
|
|
83
|
+
opacity: number;
|
|
84
|
+
slant: number;
|
|
85
|
+
weight: number;
|
|
86
|
+
width: number;
|
|
87
|
+
textColor: string;
|
|
88
|
+
translateX: number;
|
|
89
|
+
translateY: number;
|
|
90
|
+
stretchY: number;
|
|
91
|
+
rotation?: number;
|
|
92
|
+
skewX?: number;
|
|
93
|
+
fontVariationAxes?: Record<string, number>;
|
|
94
|
+
letterShake?: number;
|
|
95
|
+
shadowColor?: string;
|
|
96
|
+
}
|
|
97
|
+
interface SentenceAnimationState extends AnimationState {
|
|
98
|
+
text: string;
|
|
99
|
+
emotion: string;
|
|
100
|
+
emotionIntensity: number;
|
|
101
|
+
fontFamily: string;
|
|
102
|
+
startTime: number;
|
|
103
|
+
endTime: number;
|
|
104
|
+
duration: number;
|
|
105
|
+
isActive: boolean;
|
|
106
|
+
}
|
|
107
|
+
interface WordAnimationState {
|
|
108
|
+
text: string;
|
|
109
|
+
words: Array<{
|
|
110
|
+
word: string;
|
|
111
|
+
start: number;
|
|
112
|
+
end: number;
|
|
113
|
+
animationEnd: number;
|
|
114
|
+
isActive: boolean;
|
|
115
|
+
emotion: string;
|
|
116
|
+
emotionIntensity: number;
|
|
117
|
+
originalEmotionIntensity?: number;
|
|
118
|
+
fontFamily: string;
|
|
119
|
+
emphasis: number;
|
|
120
|
+
emphasisEffect?: any;
|
|
121
|
+
strongEmphasis?: any;
|
|
122
|
+
animationParameters: AnimationState;
|
|
123
|
+
joyAnimationMode?: 'letter' | 'letter-bulge' | 'word' | null;
|
|
124
|
+
joyProgress?: number | null;
|
|
125
|
+
}>;
|
|
126
|
+
currentWordIndex: number;
|
|
127
|
+
emotion: string;
|
|
128
|
+
emotionIntensity: number;
|
|
129
|
+
fontFamily: string;
|
|
130
|
+
startTime: number;
|
|
131
|
+
endTime: number;
|
|
132
|
+
isActive: boolean;
|
|
133
|
+
}
|
|
134
|
+
interface SubtitleSegment {
|
|
135
|
+
start_time: number;
|
|
136
|
+
end_time: number;
|
|
137
|
+
text?: string;
|
|
138
|
+
subtitle?: string;
|
|
139
|
+
emotion?: string;
|
|
140
|
+
emotion_intensity?: number;
|
|
141
|
+
animation_url?: string;
|
|
142
|
+
/** Per-cue expressiveness (0–1); combined with global GTS slider at playback. */
|
|
143
|
+
gts?: number;
|
|
144
|
+
words?: Array<{
|
|
145
|
+
word: string;
|
|
146
|
+
start: number;
|
|
147
|
+
end: number;
|
|
148
|
+
emphasis?: number;
|
|
149
|
+
emotion?: string;
|
|
150
|
+
emotion_intensity?: number;
|
|
151
|
+
animation_url?: string;
|
|
152
|
+
animations?: Record<string, number>;
|
|
153
|
+
gts?: number;
|
|
154
|
+
}>;
|
|
155
|
+
animations?: Record<string, number>;
|
|
156
|
+
volume?: number;
|
|
157
|
+
speech_rate?: number;
|
|
158
|
+
merged_subtitles?: SubtitleSegment[];
|
|
159
|
+
}
|
|
160
|
+
interface AnimationOptions {
|
|
161
|
+
maxExpression?: number;
|
|
162
|
+
threshold?: number;
|
|
163
|
+
isRTL?: boolean;
|
|
164
|
+
volume?: number;
|
|
165
|
+
speechRate?: number;
|
|
166
|
+
nextSegmentStartTime?: number;
|
|
167
|
+
extendedEndTime?: number;
|
|
168
|
+
}
|
|
169
|
+
|
|
48
170
|
/**
|
|
49
171
|
* ============================================
|
|
50
172
|
* SUBTITLE STATE MANAGER
|
|
@@ -164,12 +286,12 @@ declare class SubtitleStateManager {
|
|
|
164
286
|
*
|
|
165
287
|
* STATUS: Phase 2 Complete - All 8 classes extracted, clean architecture, no duplication
|
|
166
288
|
*/
|
|
167
|
-
type AnimationMode = "Sentence" | "Word" | string;
|
|
289
|
+
type AnimationMode$1 = "Sentence" | "Word" | string;
|
|
168
290
|
interface SubtitleState {
|
|
169
291
|
isVisible: boolean;
|
|
170
292
|
isKaraokeMode: boolean;
|
|
171
293
|
isSpeaker: boolean;
|
|
172
|
-
animationMode: AnimationMode;
|
|
294
|
+
animationMode: AnimationMode$1;
|
|
173
295
|
currentSubtitle: string;
|
|
174
296
|
currentSequence: number | null;
|
|
175
297
|
subtitles: any[];
|
|
@@ -242,7 +364,7 @@ declare class SubtitleManager {
|
|
|
242
364
|
toggleSoundbiteAnimations(isVisible: boolean): void;
|
|
243
365
|
mapEventLabelToAnimation(eventLabel: string): string | null;
|
|
244
366
|
processSoundbiteAnimations(soundbites: any[]): any[];
|
|
245
|
-
setAnimationMode(mode: AnimationMode): void;
|
|
367
|
+
setAnimationMode(mode: AnimationMode$1): void;
|
|
246
368
|
toggleTransition(enabled: boolean): void;
|
|
247
369
|
updateSubtitle(text: string): void;
|
|
248
370
|
updateLiveTime(videoTime?: number | null): number;
|
|
@@ -262,7 +384,7 @@ declare class SubtitleManager {
|
|
|
262
384
|
getInitialLiveSequenceNumber(): Promise<number>;
|
|
263
385
|
fetchSubtitles(sequenceNumber: number): Promise<any | null>;
|
|
264
386
|
loadVodSubtitles(urlOrVodId: string, languageCode?: string | null): Promise<void>;
|
|
265
|
-
_processVodData(data: any, url: string, languageCode: string | null): void;
|
|
387
|
+
_processVodData(data: any, url: string, languageCode: string | null, originalSubtitles?: any[]): void;
|
|
266
388
|
getSubtitleForTime(time: number): any;
|
|
267
389
|
getLiveSubtitleForTime(): any;
|
|
268
390
|
getCurrentSubtitleData(): any | null;
|
|
@@ -293,106 +415,191 @@ declare class SubtitleManager {
|
|
|
293
415
|
declare const subtitleManager: SubtitleManager;
|
|
294
416
|
|
|
295
417
|
/**
|
|
296
|
-
* Animation
|
|
418
|
+
* URL Decoder for Animation Parameters
|
|
297
419
|
*
|
|
298
|
-
*
|
|
420
|
+
* Extracted from app/playground/utils/urlEncoding.js
|
|
421
|
+
* Decodes animation URLs into parameter states
|
|
422
|
+
*
|
|
423
|
+
* Supports both full URLs and query strings:
|
|
424
|
+
* - Full URL: https://stage-dev.phont.ai/playground/shared?name=...&scale=0,1|1,1.2
|
|
425
|
+
* - Query string: ?name=...&scale=0,1|1,1.2
|
|
299
426
|
*/
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Decode animation data from URL or query string
|
|
430
|
+
* @param urlOrQuery - Full URL (https://...) or query string (?name=... or name=...)
|
|
431
|
+
* @returns Decoded animation data object with parameterStates
|
|
432
|
+
*/
|
|
433
|
+
declare function decodeAnimationUrl(urlOrQuery: string): AnimationParameterStates;
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Animation parameter calculation -- the unified rendering pipeline.
|
|
437
|
+
* TypeScript port of app/utils/animation/animationParameters.js.
|
|
438
|
+
*
|
|
439
|
+
* Samples authored URL curves with linear interpolation, then scales deviations
|
|
440
|
+
* proportionally from a reference point (REFERENCE_INTENSITY × REFERENCE_GTS).
|
|
441
|
+
* At the reference point the authored curve is rendered 1:1.
|
|
442
|
+
*/
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Exponential variance curve (hockey stick)
|
|
446
|
+
*
|
|
447
|
+
* Creates an exponential curve that accelerates dramatically after 0.7 intensity.
|
|
448
|
+
* Low intensities (0.0-0.7): Subtle effects (gradual rise)
|
|
449
|
+
* High intensities (0.7-1.0): Dramatic effects (exponential acceleration)
|
|
450
|
+
*
|
|
451
|
+
* @param i - Input intensity (0-1)
|
|
452
|
+
* @returns Transformed intensity (0-1) with exponential variance
|
|
453
|
+
*/
|
|
454
|
+
declare function hockeyStickIntensity(i: number): number;
|
|
455
|
+
/**
|
|
456
|
+
* Sample a parameter curve at a given time
|
|
457
|
+
*
|
|
458
|
+
* Interpolates between keyframe points to get the value at a specific time.
|
|
459
|
+
* Supports both normalized (0-1) and absolute time formats.
|
|
460
|
+
* For color parameters, uses RGB interpolation for smooth color transitions.
|
|
461
|
+
*
|
|
462
|
+
* @param points - Array of {time, value} points or [time, value] arrays
|
|
463
|
+
* @param t - Normalized time (0-1)
|
|
464
|
+
* @param duration - Animation duration in seconds
|
|
465
|
+
* @param isNormalized - Whether points are in normalized (0-1) or absolute time
|
|
466
|
+
* @param parameterName - Name of the parameter (e.g., 'color', 'shadowColor', 'outlineColor') for color interpolation
|
|
467
|
+
* @returns Sampled value or null if no points
|
|
468
|
+
*/
|
|
469
|
+
declare function sampleParameterCurve(points: Array<{
|
|
470
|
+
time?: number;
|
|
471
|
+
value?: number | string;
|
|
472
|
+
} | [number, number | string]> | undefined | null, t: number, duration: number, isNormalized?: boolean, parameterName?: string | null): number | string | null;
|
|
473
|
+
interface AnimationParameterState {
|
|
474
|
+
rawIntensity: number;
|
|
475
|
+
scaleFactor: number;
|
|
318
476
|
scale: number;
|
|
319
|
-
opacity: number;
|
|
320
477
|
slant: number;
|
|
478
|
+
stretchY: number;
|
|
479
|
+
translateX: number;
|
|
480
|
+
translateY: number;
|
|
321
481
|
weight: number;
|
|
322
482
|
width: number;
|
|
483
|
+
fontFamily: string;
|
|
323
484
|
textColor: string;
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
485
|
+
opacity: number;
|
|
486
|
+
textShadow: string;
|
|
487
|
+
blur: number;
|
|
488
|
+
outlineWidth: number;
|
|
489
|
+
outlineColor: string;
|
|
490
|
+
outline2Width?: number;
|
|
491
|
+
outline2Color?: string;
|
|
492
|
+
outline3Width?: number;
|
|
493
|
+
outline3Color?: string;
|
|
494
|
+
outlineShadowWidth?: number;
|
|
495
|
+
outlineShadowColor?: string;
|
|
496
|
+
outlineShadowBlur?: number;
|
|
497
|
+
glowIntensity?: number;
|
|
498
|
+
glowColor?: string;
|
|
499
|
+
snakeWave?: number;
|
|
500
|
+
karaoke?: number;
|
|
501
|
+
stretchX?: number;
|
|
502
|
+
letterSpacing: string;
|
|
503
|
+
fontVariationAxes: Record<string, number>;
|
|
335
504
|
text: string;
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
duration: number;
|
|
342
|
-
isActive: boolean;
|
|
505
|
+
joy: number;
|
|
506
|
+
fear: number;
|
|
507
|
+
standardEmphasis: number;
|
|
508
|
+
strongEmphasis: number;
|
|
509
|
+
joyWaveProgress: number;
|
|
343
510
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
511
|
+
declare const REFERENCE_INTENSITY = 0.7;
|
|
512
|
+
declare const REFERENCE_GTS = 0.7;
|
|
513
|
+
/** Play authored URL curves 1:1 — matches main playground preview (no intensity/GTS scaling). */
|
|
514
|
+
/** Playground / converter preview only — bypasses GTS scaling (1:1 at reference). */
|
|
515
|
+
declare const AUTHORED_PLAYBACK_OPTIONS: {
|
|
516
|
+
rawMode: boolean;
|
|
517
|
+
};
|
|
518
|
+
/**
|
|
519
|
+
* Sample all animation parameters at time `t` with proportional intensity scaling.
|
|
520
|
+
*
|
|
521
|
+
* The authored curve represents the animation at REFERENCE_INTENSITY × REFERENCE_GTS.
|
|
522
|
+
* At those values you see exactly what was authored. Other intensity × GTS values
|
|
523
|
+
* scale linearly from there.
|
|
524
|
+
*/
|
|
525
|
+
declare function calculateAnimationParameters(animationData: AnimationParameterStates | null, rawIntensity: number, t: number, gts: number, subtitleDuration?: number | null, { rawMode }?: {
|
|
526
|
+
rawMode?: boolean;
|
|
527
|
+
}): AnimationParameterState | null;
|
|
528
|
+
|
|
529
|
+
type AnimationMode = 'sentence' | 'word';
|
|
530
|
+
type AnimationStateOptions = AnimationOptions & {
|
|
531
|
+
transparentUntilSpoken?: boolean;
|
|
532
|
+
};
|
|
533
|
+
declare function calculateAnimationState(segment: SubtitleSegment | null, currentTime: number, modeOrOptions?: AnimationMode | AnimationStateOptions, maybeOptions?: AnimationStateOptions): SentenceAnimationState | WordAnimationState;
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Emotion Animation URLs
|
|
537
|
+
*
|
|
538
|
+
* Config mapping emotion → animation URL
|
|
539
|
+
* Uses full playground URLs from app/gallery/config/animations.js
|
|
540
|
+
*
|
|
541
|
+
* SYNCED FROM: app/gallery/config/emotionMapping.js
|
|
542
|
+
*
|
|
543
|
+
* To update these URLs:
|
|
544
|
+
* 1. Update app/gallery/config/animations.js with new URLs
|
|
545
|
+
* 2. Update app/gallery/config/emotionMapping.js to map emotions to indices
|
|
546
|
+
* 3. Run: node scripts/sync-animation-urls.js
|
|
547
|
+
* OR manually copy the URLs based on the mapping
|
|
548
|
+
*
|
|
549
|
+
* The decodeAnimationUrl() function now supports both full URLs and query strings.
|
|
550
|
+
*/
|
|
551
|
+
declare const ANIMATION_URLS: string[];
|
|
552
|
+
/**
|
|
553
|
+
* Emotion to Animation URL mapping
|
|
554
|
+
* Based on app/gallery/config/emotionMapping.js
|
|
555
|
+
*
|
|
556
|
+
* Maps each emotion to an index in ANIMATION_URLS array
|
|
557
|
+
*/
|
|
558
|
+
declare const EMOTION_ANIMATION_URLS: Record<string, string>;
|
|
559
|
+
/**
|
|
560
|
+
* Get animation URL for an emotion
|
|
561
|
+
* @param emotion - Emotion name (case-insensitive)
|
|
562
|
+
* @returns Full animation URL or query string fallback
|
|
563
|
+
*/
|
|
564
|
+
declare function getAnimationUrlForEmotion(emotion: string): string;
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Published Animation Resolver (framework-agnostic)
|
|
568
|
+
*
|
|
569
|
+
* Fetches the active published animation URL for each emotion from the backend,
|
|
570
|
+
* caches the results, and provides sync/async accessors.
|
|
571
|
+
*
|
|
572
|
+
* Any consumer (app, SDK, extension) creates an instance by supplying a fetcher
|
|
573
|
+
* that returns an array of animation objects for a given stylesheet.
|
|
574
|
+
*
|
|
575
|
+
* USAGE:
|
|
576
|
+
* import { createPublishedAnimationResolver } from '@phont-ai/subtitles-core';
|
|
577
|
+
*
|
|
578
|
+
* const resolver = createPublishedAnimationResolver(
|
|
579
|
+
* async (stylesheet) => fetch(`/animations?stylesheet_name=${stylesheet}&is_active=true`).then(r => r.json())
|
|
580
|
+
* );
|
|
581
|
+
*
|
|
582
|
+
* await resolver.prefetch('default'); // warm the cache
|
|
583
|
+
* const url = resolver.getSync('lust'); // sync (returns null if not cached)
|
|
584
|
+
* const url = await resolver.get('lust'); // async (fetches if needed)
|
|
585
|
+
* resolver.invalidate(); // bust after publishing
|
|
586
|
+
*/
|
|
587
|
+
interface AnimationRecord {
|
|
364
588
|
emotion: string;
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
endTime: number;
|
|
369
|
-
isActive: boolean;
|
|
370
|
-
}
|
|
371
|
-
interface SubtitleSegment {
|
|
372
|
-
start_time: number;
|
|
373
|
-
end_time: number;
|
|
374
|
-
text?: string;
|
|
375
|
-
subtitle?: string;
|
|
376
|
-
words?: Array<{
|
|
377
|
-
word: string;
|
|
378
|
-
start: number;
|
|
379
|
-
end: number;
|
|
380
|
-
emphasis?: number;
|
|
381
|
-
}>;
|
|
382
|
-
animations?: Record<string, number>;
|
|
383
|
-
volume?: number;
|
|
384
|
-
speech_rate?: number;
|
|
385
|
-
merged_subtitles?: SubtitleSegment[];
|
|
589
|
+
url: string;
|
|
590
|
+
is_active: boolean;
|
|
591
|
+
[key: string]: unknown;
|
|
386
592
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
nextSegmentStartTime?: number;
|
|
394
|
-
extendedEndTime?: number;
|
|
593
|
+
type AnimationFetcher = (stylesheetName: string) => Promise<AnimationRecord[]>;
|
|
594
|
+
interface PublishedAnimationResolver {
|
|
595
|
+
prefetch: (stylesheetName?: string) => Promise<Map<string, string>>;
|
|
596
|
+
get: (emotion: string, stylesheetName?: string) => Promise<string | null>;
|
|
597
|
+
getSync: (emotion: string, stylesheetName?: string) => string | null;
|
|
598
|
+
invalidate: () => void;
|
|
395
599
|
}
|
|
600
|
+
declare function createPublishedAnimationResolver(fetcher: AnimationFetcher, { ttlMs }?: {
|
|
601
|
+
ttlMs?: number;
|
|
602
|
+
}): PublishedAnimationResolver;
|
|
396
603
|
|
|
397
604
|
/**
|
|
398
605
|
* Emotion Selector
|
|
@@ -421,86 +628,24 @@ interface EmotionSelectionResult {
|
|
|
421
628
|
declare function selectEmotion(animationsObject: Record<string, number> | null | undefined, threshold?: number): EmotionSelectionResult;
|
|
422
629
|
|
|
423
630
|
/**
|
|
424
|
-
*
|
|
631
|
+
* Timing Utilities
|
|
425
632
|
*
|
|
426
|
-
* Pure functions
|
|
427
|
-
* Uses function-based EMOTION_ANIMATIONS (identical to monorepo)
|
|
633
|
+
* Pure functions for calculating subtitle timing
|
|
428
634
|
*/
|
|
429
635
|
|
|
430
636
|
/**
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
* Pure function version of useSentenceAnimation - uses function-based EMOTION_ANIMATIONS (identical to monorepo)
|
|
637
|
+
* Get subtitle timing information
|
|
434
638
|
*/
|
|
435
|
-
declare function
|
|
639
|
+
declare function getSubtitleTiming(subtitle: SubtitleSegment | null): {
|
|
640
|
+
startTime: number;
|
|
641
|
+
endTime: number;
|
|
642
|
+
duration: number;
|
|
643
|
+
};
|
|
436
644
|
/**
|
|
437
|
-
* Calculate
|
|
438
|
-
*
|
|
439
|
-
* Pure function version of useWordAnimation - uses function-based EMOTION_ANIMATIONS (identical to monorepo)
|
|
440
|
-
*/
|
|
441
|
-
declare function calculateWordAnimation(segment: SubtitleSegment | null, currentTime: number, options?: AnimationOptions): WordAnimationState;
|
|
442
|
-
/**
|
|
443
|
-
* Main function: Calculate animation state from segment and emotion
|
|
444
|
-
*
|
|
445
|
-
* This is the main entry point that uses function-based EMOTION_ANIMATIONS (identical to monorepo)
|
|
446
|
-
*/
|
|
447
|
-
declare function calculateAnimationState(segment: SubtitleSegment | null, currentTime: number, mode: 'sentence' | 'word', options?: AnimationOptions): SentenceAnimationState | WordAnimationState;
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* Timing Utilities
|
|
451
|
-
*
|
|
452
|
-
* Pure functions for calculating subtitle timing
|
|
453
|
-
*/
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
* Get subtitle timing information
|
|
457
|
-
*/
|
|
458
|
-
declare function getSubtitleTiming(subtitle: SubtitleSegment | null): {
|
|
459
|
-
startTime: number;
|
|
460
|
-
endTime: number;
|
|
461
|
-
duration: number;
|
|
462
|
-
};
|
|
463
|
-
/**
|
|
464
|
-
* Get subtitle text content
|
|
465
|
-
*/
|
|
466
|
-
declare function getSubtitleText(subtitle: SubtitleSegment | null): string;
|
|
467
|
-
/**
|
|
468
|
-
* Calculate normalized time (t: 0→1) through subtitle duration
|
|
645
|
+
* Calculate normalized time (t: 0→1) through subtitle duration
|
|
469
646
|
*/
|
|
470
647
|
declare function calculateNormalizedTime(currentTime: number, startTime: number, duration: number): number;
|
|
471
648
|
|
|
472
|
-
/**
|
|
473
|
-
* **EMOTION_CURVES_DEFINITION** - Animation DNA
|
|
474
|
-
*
|
|
475
|
-
* Emotion Curves - Animation Parameter Definitions
|
|
476
|
-
*
|
|
477
|
-
* These curves define how subtitle text animates over time based on emotion.
|
|
478
|
-
* Each emotion has time-based functions that return values for visual parameters.
|
|
479
|
-
*
|
|
480
|
-
* PARAMETERS:
|
|
481
|
-
* - fontSize: Always constant (ANIMATION_STYLING.fontSize) for layout stability
|
|
482
|
-
* - scale: Size multiplier applied via CSS transform (prevents text wrapping)
|
|
483
|
-
* - slant: Italic/skew effect in degrees (applied as CSS skewX)
|
|
484
|
-
* - weight: Font weight (100-900) - overridden by VariableFontContext in practice
|
|
485
|
-
* - translateX/Y: Movement in pixels (direct CSS values)
|
|
486
|
-
* - textColor: Text color (rgba)
|
|
487
|
-
* - stretchY: Vertical stretch multiplier (CSS scaleY)
|
|
488
|
-
* - letterShakeIntensity: Per-letter shake amount in pixels (fear)
|
|
489
|
-
*
|
|
490
|
-
* WHY SCALE INSTEAD OF FONTSIZE:
|
|
491
|
-
* Using transform: scale() instead of fontSize changes allows the layout engine
|
|
492
|
-
* to calculate word positions ONCE at the base fontSize, preventing words from
|
|
493
|
-
* wrapping to new lines mid-animation. Scale is GPU-accelerated and doesn't trigger reflow.
|
|
494
|
-
*
|
|
495
|
-
* ⚠️ Parameters NOT included (handled elsewhere):
|
|
496
|
-
* - opacity: Always 1.0 (fade in/out handled by controllers)
|
|
497
|
-
* - shadows: Handled by styling.js ANIMATION_STYLING.shadow (emotion-specific for disgust/angry)
|
|
498
|
-
* - font family: Handled by fontSelection.js based on emotion + intensity
|
|
499
|
-
* - transitions: Handled by styling.js ANIMATION_STYLING.transition
|
|
500
|
-
* - marginRight: Handled by calculateDynamicWordSpacing() based on current scale
|
|
501
|
-
*/
|
|
502
|
-
declare const EMOTION_ANIMATIONS: Record<string, any>;
|
|
503
|
-
|
|
504
649
|
/**
|
|
505
650
|
* Animation Defaults - Visual Styling Layer
|
|
506
651
|
*
|
|
@@ -572,6 +717,11 @@ declare const ANIMATION_STYLING: {
|
|
|
572
717
|
wordSpacingMultiplier: number;
|
|
573
718
|
fontSizeOffset: number;
|
|
574
719
|
};
|
|
720
|
+
'Bricolage Grotesque': {
|
|
721
|
+
letterSpacing: string;
|
|
722
|
+
wordSpacingMultiplier: number;
|
|
723
|
+
fontSizeOffset: number;
|
|
724
|
+
};
|
|
575
725
|
Rakkas: {
|
|
576
726
|
letterSpacing: string;
|
|
577
727
|
wordSpacingMultiplier: number;
|
|
@@ -607,6 +757,9 @@ declare const RENDERING_CONTROL: {
|
|
|
607
757
|
breathingRoomDuration: number;
|
|
608
758
|
breathingRoomMinGap: number;
|
|
609
759
|
breathingRoomLargeGap: number;
|
|
760
|
+
breathingRoomSafetyBuffer: number;
|
|
761
|
+
breathingRoomNoNextHold: number;
|
|
762
|
+
fadeOutDuration: number;
|
|
610
763
|
timeRangeTolerance: number;
|
|
611
764
|
};
|
|
612
765
|
emotion: {
|
|
@@ -703,81 +856,22 @@ declare const RENDERING_CONTROL: {
|
|
|
703
856
|
};
|
|
704
857
|
};
|
|
705
858
|
|
|
706
|
-
/**
|
|
707
|
-
* Shared Animation Parameter Calculation Utility
|
|
708
|
-
*
|
|
709
|
-
* Calculates animation parameters from emotion curves.
|
|
710
|
-
* Shared by calculateWordAnimation and calculateSentenceAnimation to eliminate duplication.
|
|
711
|
-
*
|
|
712
|
-
* This utility extracts all animation parameters defined in EMOTION_ANIMATIONS
|
|
713
|
-
* including variation axes (YOPQ, YTAS) that are separate from voice axes (wght, wdth).
|
|
714
|
-
*
|
|
715
|
-
* TERMINOLOGY:
|
|
716
|
-
* - **Voice Axes**: Font axes driven by audio analysis (volume→wght, speech_rate→wdth)
|
|
717
|
-
* - **Variation Axes**: Font axes driven by emotion animations (YOPQ, YTAS from emotion curves)
|
|
718
|
-
*/
|
|
719
|
-
interface VariableFontStyle {
|
|
720
|
-
fontWeight?: number;
|
|
721
|
-
fontStretch?: string;
|
|
722
|
-
}
|
|
723
|
-
interface AnimationParameters {
|
|
724
|
-
fontSize: number;
|
|
725
|
-
scale: number;
|
|
726
|
-
opacity: number;
|
|
727
|
-
slant: number;
|
|
728
|
-
weight: number;
|
|
729
|
-
width: number;
|
|
730
|
-
textColor: string;
|
|
731
|
-
translateX: number;
|
|
732
|
-
translateY: number;
|
|
733
|
-
stretchY: number;
|
|
734
|
-
letterShake?: number;
|
|
735
|
-
fontVariationAxes?: Record<string, number>;
|
|
736
|
-
shadowColor?: string | ((t: number, intensity: number) => string);
|
|
737
|
-
}
|
|
738
|
-
interface EmotionCurve {
|
|
739
|
-
fontSize?: number | ((t: number, intensity: number) => number);
|
|
740
|
-
scale?: number | ((t: number, intensity: number) => number);
|
|
741
|
-
opacity?: number | ((t: number, intensity: number) => number);
|
|
742
|
-
slant?: number | ((t: number, intensity?: number) => number);
|
|
743
|
-
weight?: number | ((t: number, intensity?: number) => number);
|
|
744
|
-
translateX?: number | ((t: number, intensity: number) => number);
|
|
745
|
-
translateY?: number | ((t: number, intensity: number) => number);
|
|
746
|
-
stretchY?: number | ((t: number, intensity: number) => number);
|
|
747
|
-
textColor?: string | ((t: number, intensity: number) => string);
|
|
748
|
-
shadowColor?: string | ((t: number, intensity: number) => string);
|
|
749
|
-
thinStroke?: (t: number, intensity: number, gtsValue: number) => number;
|
|
750
|
-
ascenderHeight?: (t: number, intensity: number, gtsValue: number) => number;
|
|
751
|
-
letterShake?: (t: number, intensity: number, gtsValue: number) => number;
|
|
752
|
-
}
|
|
753
|
-
/**
|
|
754
|
-
* Calculate animation parameters from emotion curve
|
|
755
|
-
*
|
|
756
|
-
* @param emotionCurve - Emotion curve from EMOTION_ANIMATIONS
|
|
757
|
-
* @param t - Normalized time (0-1) through animation
|
|
758
|
-
* @param intensity - Emotion intensity (0-1), capped by GTS (maxExpression)
|
|
759
|
-
* @param variableFontStyle - Font style from variable font calculations
|
|
760
|
-
* @param gtsValue - GTS maxExpression value (0.2-1.0) for scaling ranges
|
|
761
|
-
* @param selectedFontFamily - The selected font family (e.g., 'Cormorant', 'Roboto Flex')
|
|
762
|
-
* @returns Complete animation parameters including fontVariationAxes (variation axes, not voice axes)
|
|
763
|
-
*/
|
|
764
|
-
declare function calculateAnimationParameters(emotionCurve: EmotionCurve, t: number, intensity: number, variableFontStyle?: VariableFontStyle | null, gtsValue?: number, selectedFontFamily?: string): AnimationParameters;
|
|
765
|
-
|
|
766
859
|
/**
|
|
767
860
|
* Shadow Generator
|
|
768
861
|
*
|
|
769
|
-
* Generates CSS text-shadow strings from shadow colors
|
|
862
|
+
* Generates CSS text-shadow strings from shadow colors
|
|
863
|
+
* All emotion-specific shadows are now controlled by URL animations
|
|
770
864
|
*/
|
|
771
865
|
/**
|
|
772
866
|
* Generate CSS text-shadow string from shadow color
|
|
773
867
|
*
|
|
774
868
|
* @param shadowColor - Shadow color in hex format (e.g., '#ff3232')
|
|
775
|
-
* @param
|
|
776
|
-
* @param
|
|
777
|
-
* @param
|
|
778
|
-
* @returns CSS text-shadow value
|
|
869
|
+
* @param _fontFamily - Unused (kept for API compatibility)
|
|
870
|
+
* @param _emotion - Unused (kept for API compatibility)
|
|
871
|
+
* @param _intensity - Unused (kept for API compatibility)
|
|
872
|
+
* @returns CSS text-shadow value or empty string if no shadow
|
|
779
873
|
*/
|
|
780
|
-
declare function generateTextShadow(shadowColor: string | undefined,
|
|
874
|
+
declare function generateTextShadow(shadowColor: string | undefined, _fontFamily?: string, _emotion?: string, _intensity?: number): string;
|
|
781
875
|
|
|
782
876
|
/**
|
|
783
877
|
* Dynamic Word Spacing Calculator
|
|
@@ -796,6 +890,27 @@ declare function generateTextShadow(shadowColor: string | undefined, fontFamily?
|
|
|
796
890
|
*/
|
|
797
891
|
declare function calculateDynamicWordSpacing(currentScale?: number, fontFamily?: string, gtsIntensity?: number, emotion?: string): string;
|
|
798
892
|
|
|
893
|
+
/**
|
|
894
|
+
* Prosody Weight — Natural Voice Intonation for Animations
|
|
895
|
+
*
|
|
896
|
+
* Only ~20% of words get motion animation, mimicking how natural speech
|
|
897
|
+
* stresses only a few key words per phrase. Font styling (color, weight,
|
|
898
|
+
* slant) is unaffected — this only gates movement.
|
|
899
|
+
*
|
|
900
|
+
* Selection criteria:
|
|
901
|
+
* 1. Function words (the, a, is, and…) → always quiet
|
|
902
|
+
* 2. Content words are scored by length + deterministic hash
|
|
903
|
+
* 3. Only the top ~35% of content words animate
|
|
904
|
+
* (since function/short words are ~55% of text,
|
|
905
|
+
* 35% of remaining 45% ≈ 16-20% of all words)
|
|
906
|
+
*/
|
|
907
|
+
/**
|
|
908
|
+
* Compute a prosody importance weight for a single word.
|
|
909
|
+
*
|
|
910
|
+
* @returns 0 (no motion) or 1 (full motion).
|
|
911
|
+
*/
|
|
912
|
+
declare function computeProsodyWeight(word: any, _emotionIntensity: number, _gts: number): number;
|
|
913
|
+
|
|
799
914
|
/**
|
|
800
915
|
* Joy Animation Effects
|
|
801
916
|
*
|
|
@@ -841,11 +956,140 @@ declare function getJoyTransform(joyEffect: JoyEffect | null): string;
|
|
|
841
956
|
*/
|
|
842
957
|
declare function getJoyFilter(joyEffect: JoyEffect | null): string;
|
|
843
958
|
|
|
959
|
+
/**
|
|
960
|
+
* Word Emphasis Effects
|
|
961
|
+
*
|
|
962
|
+
* Calculates emphasis effects (standard and strong) for words based on confidence levels.
|
|
963
|
+
*
|
|
964
|
+
* USED BY:
|
|
965
|
+
* - calculateWordAnimation: Main word animation orchestrator
|
|
966
|
+
*
|
|
967
|
+
* HOW IT WORKS:
|
|
968
|
+
* 1. Standard Emphasis (50-70%): Quick "pop" effect at word start
|
|
969
|
+
* 2. Strong Emphasis (70%+): Per-letter dramatic effects throughout word
|
|
970
|
+
* 3. Both scale with GTS (expressiveness level) and word confidence
|
|
971
|
+
*
|
|
972
|
+
* KEY FEATURES:
|
|
973
|
+
* - Confidence-based thresholds (50-70% vs 70%+)
|
|
974
|
+
* - GTS-scaled intensity
|
|
975
|
+
* - Emotion slant inheritance
|
|
976
|
+
* - Smooth transitions
|
|
977
|
+
*/
|
|
978
|
+
interface Word {
|
|
979
|
+
emphasis?: number;
|
|
980
|
+
start: number;
|
|
981
|
+
end: number;
|
|
982
|
+
animationEnd?: number;
|
|
983
|
+
}
|
|
984
|
+
interface EmphasisEffect {
|
|
985
|
+
scaleMultiplier: number;
|
|
986
|
+
slantAdditive: number;
|
|
987
|
+
weightBoost: number;
|
|
988
|
+
scaleProgress: number;
|
|
989
|
+
gtsMultiplier: number;
|
|
990
|
+
emphasis: number;
|
|
991
|
+
emphasisMultiplier: number;
|
|
992
|
+
elapsed: number;
|
|
993
|
+
scaleActive: boolean;
|
|
994
|
+
}
|
|
995
|
+
interface StrongEmphasisData {
|
|
996
|
+
emphasis: number;
|
|
997
|
+
rawEmphasis: number;
|
|
998
|
+
scale: number;
|
|
999
|
+
rotation: number;
|
|
1000
|
+
translateX: number;
|
|
1001
|
+
translateY: number;
|
|
1002
|
+
skewX: number;
|
|
1003
|
+
stretchY: number;
|
|
1004
|
+
brightness: number;
|
|
1005
|
+
contrast: number;
|
|
1006
|
+
shadowBlur: number;
|
|
1007
|
+
shadowOpacity: number;
|
|
1008
|
+
zIndex: number;
|
|
1009
|
+
weightBoost: number;
|
|
1010
|
+
shadowOffsetX: number;
|
|
1011
|
+
shadowOffsetY: number;
|
|
1012
|
+
gtsMultiplier: number;
|
|
1013
|
+
emphasisMultiplier: number;
|
|
1014
|
+
fadeFactor: number;
|
|
1015
|
+
isInTail: boolean;
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Calculate emphasis effects for a word
|
|
1019
|
+
*
|
|
1020
|
+
* @param params - Emphasis calculation parameters
|
|
1021
|
+
* @returns Emphasis effects { emphasisEffect, strongEmphasisData }
|
|
1022
|
+
*/
|
|
1023
|
+
declare function calculateWordEmphasisEffects({ word, currentTime, maxExpression, emotionAnimationDuration, wordBaseSlant, isActive, wordEmotion, }: {
|
|
1024
|
+
word: Word;
|
|
1025
|
+
currentTime: number;
|
|
1026
|
+
maxExpression: number;
|
|
1027
|
+
emotionAnimationDuration: number;
|
|
1028
|
+
wordBaseSlant: number;
|
|
1029
|
+
isActive: boolean;
|
|
1030
|
+
wordEmotion?: string;
|
|
1031
|
+
}): {
|
|
1032
|
+
emphasisEffect: EmphasisEffect | null;
|
|
1033
|
+
strongEmphasisData: StrongEmphasisData | null;
|
|
1034
|
+
};
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* ============================================
|
|
1038
|
+
* WORD LETTER SPACING
|
|
1039
|
+
* ============================================
|
|
1040
|
+
*
|
|
1041
|
+
* PURPOSE:
|
|
1042
|
+
* Calculates per-letter translateX offsets for GPU-accelerated spacing (no layout reflow).
|
|
1043
|
+
* Extracted from animationEngine for better maintainability.
|
|
1044
|
+
*
|
|
1045
|
+
* USED BY:
|
|
1046
|
+
* - animationEngine: Main word animation orchestrator
|
|
1047
|
+
*
|
|
1048
|
+
* HOW IT WORKS:
|
|
1049
|
+
* 1. Detects active effects (fear shake only - emphasis spacing is disabled)
|
|
1050
|
+
* 2. Calculates per-letter translateX offsets to create spacing between letters
|
|
1051
|
+
* 3. Returns array of translateX values in pixels (one per letter)
|
|
1052
|
+
*
|
|
1053
|
+
* KEY FEATURES:
|
|
1054
|
+
* - Transform-based spacing (GPU-accelerated, no layout reflow)
|
|
1055
|
+
* - Letter spacing disabled for emphasis effects (standard and strong)
|
|
1056
|
+
* - Only fear shake effects get letter spacing (if needed)
|
|
1057
|
+
* - Zero baseline for clean transitions
|
|
1058
|
+
*
|
|
1059
|
+
* PERFORMANCE BENEFITS:
|
|
1060
|
+
* - Uses translateX (compositor property) instead of letter-spacing (layout property)
|
|
1061
|
+
* - Smooth CSS transitions without triggering layout reflow
|
|
1062
|
+
* - All spacing animations run on GPU compositor layer
|
|
1063
|
+
*/
|
|
1064
|
+
interface WordLetterSpacingParams {
|
|
1065
|
+
strongEmphasisData?: any;
|
|
1066
|
+
emphasisEffect?: any;
|
|
1067
|
+
wordLetterShakeIntensity: number | null;
|
|
1068
|
+
wordFontFamily: string;
|
|
1069
|
+
currentTime: number;
|
|
1070
|
+
word: any;
|
|
1071
|
+
emotionAnimationDuration: number;
|
|
1072
|
+
wordEmotion?: string;
|
|
1073
|
+
totalLetters: number;
|
|
1074
|
+
fontSize: number;
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Calculate per-letter translateX offsets for GPU-accelerated spacing
|
|
1078
|
+
*
|
|
1079
|
+
* @param params - Spacing calculation parameters
|
|
1080
|
+
* @returns Array of translateX offsets in pixels (one per letter)
|
|
1081
|
+
*/
|
|
1082
|
+
declare function calculateWordLetterSpacing({ strongEmphasisData, emphasisEffect, wordLetterShakeIntensity, wordFontFamily, currentTime, word, emotionAnimationDuration, wordEmotion, totalLetters, fontSize, }: WordLetterSpacingParams): number[];
|
|
1083
|
+
|
|
844
1084
|
/**
|
|
845
1085
|
* GTS (Global Text Style) Calculations
|
|
846
1086
|
*
|
|
847
1087
|
* Centralized logic for GTS-derived values and emotion threshold calculations
|
|
848
1088
|
*/
|
|
1089
|
+
/**
|
|
1090
|
+
* Combine global GTS slider with optional per-segment / per-word authored gts.
|
|
1091
|
+
*/
|
|
1092
|
+
declare function resolveEffectiveGts(sliderGts: number, segmentGts?: number, wordGts?: number): number;
|
|
849
1093
|
/**
|
|
850
1094
|
* Calculate all GTS-derived values from slider position
|
|
851
1095
|
*
|
|
@@ -871,11 +1115,16 @@ declare function calculateGTSValues(gts: number): {
|
|
|
871
1115
|
*/
|
|
872
1116
|
declare function meetsEmotionThreshold(intensity: number, threshold: number): boolean;
|
|
873
1117
|
/**
|
|
874
|
-
* Calculate
|
|
1118
|
+
* Calculate scaled emotion intensity based on GTS maxExpression
|
|
1119
|
+
*
|
|
1120
|
+
* GTS acts as a scaling multiplier (final layer) to preserve variance in emotion values
|
|
1121
|
+
* while controlling overall expressiveness.
|
|
1122
|
+
*
|
|
1123
|
+
* When GTS=0.0 (maxExpression=0.2), animations are completely disabled.
|
|
875
1124
|
*
|
|
876
1125
|
* @param rawIntensity - Raw emotion intensity from backend (0-1)
|
|
877
|
-
* @param maxExpression - GTS-derived max expression
|
|
878
|
-
* @returns
|
|
1126
|
+
* @param maxExpression - GTS-derived max expression multiplier (0.2-1.0)
|
|
1127
|
+
* @returns Scaled emotion intensity (0-1), or 0 if GTS=0.0
|
|
879
1128
|
*/
|
|
880
1129
|
declare function capEmotionIntensity(rawIntensity: number, maxExpression: number): number;
|
|
881
1130
|
/**
|
|
@@ -903,14 +1152,6 @@ declare function isInEmphasisRange(emphasis: number): boolean;
|
|
|
903
1152
|
*/
|
|
904
1153
|
declare function isInStrongEmphasisRange(emphasis: number): boolean;
|
|
905
1154
|
|
|
906
|
-
/**
|
|
907
|
-
* Emotion Animation URLs
|
|
908
|
-
*
|
|
909
|
-
* Config mapping emotion → animation URL
|
|
910
|
-
* Replaces hardcoded EMOTION_ANIMATIONS config with URL-based parameters
|
|
911
|
-
*/
|
|
912
|
-
declare const EMOTION_ANIMATION_URLS: Record<string, string>;
|
|
913
|
-
|
|
914
1155
|
/**
|
|
915
1156
|
* Font Selection Utilities
|
|
916
1157
|
*
|
|
@@ -985,129 +1226,33 @@ interface Letter {
|
|
|
985
1226
|
declare function splitTextIntoLetters(text: string): Letter[];
|
|
986
1227
|
|
|
987
1228
|
/**
|
|
988
|
-
*
|
|
989
|
-
*
|
|
990
|
-
* Calculates emphasis effects (standard and strong) for words based on confidence levels.
|
|
991
|
-
*
|
|
992
|
-
* USED BY:
|
|
993
|
-
* - calculateWordAnimation: Main word animation orchestrator
|
|
994
|
-
*
|
|
995
|
-
* HOW IT WORKS:
|
|
996
|
-
* 1. Standard Emphasis (50-70%): Quick "pop" effect at word start
|
|
997
|
-
* 2. Strong Emphasis (70%+): Per-letter dramatic effects throughout word
|
|
998
|
-
* 3. Both scale with GTS (expressiveness level) and word confidence
|
|
999
|
-
*
|
|
1000
|
-
* KEY FEATURES:
|
|
1001
|
-
* - Confidence-based thresholds (50-70% vs 70%+)
|
|
1002
|
-
* - GTS-scaled intensity
|
|
1003
|
-
* - Emotion slant inheritance
|
|
1004
|
-
* - Smooth transitions
|
|
1005
|
-
*/
|
|
1006
|
-
interface Word {
|
|
1007
|
-
emphasis?: number;
|
|
1008
|
-
start: number;
|
|
1009
|
-
end: number;
|
|
1010
|
-
animationEnd?: number;
|
|
1011
|
-
}
|
|
1012
|
-
interface EmphasisEffect {
|
|
1013
|
-
scaleMultiplier: number;
|
|
1014
|
-
slantAdditive: number;
|
|
1015
|
-
weightBoost: number;
|
|
1016
|
-
scaleProgress: number;
|
|
1017
|
-
gtsMultiplier: number;
|
|
1018
|
-
emphasis: number;
|
|
1019
|
-
emphasisMultiplier: number;
|
|
1020
|
-
elapsed: number;
|
|
1021
|
-
scaleActive: boolean;
|
|
1022
|
-
}
|
|
1023
|
-
interface StrongEmphasisData {
|
|
1024
|
-
emphasis: number;
|
|
1025
|
-
rawEmphasis: number;
|
|
1026
|
-
scale: number;
|
|
1027
|
-
rotation: number;
|
|
1028
|
-
translateX: number;
|
|
1029
|
-
translateY: number;
|
|
1030
|
-
skewX: number;
|
|
1031
|
-
stretchY: number;
|
|
1032
|
-
brightness: number;
|
|
1033
|
-
contrast: number;
|
|
1034
|
-
shadowBlur: number;
|
|
1035
|
-
shadowOpacity: number;
|
|
1036
|
-
zIndex: number;
|
|
1037
|
-
weightBoost: number;
|
|
1038
|
-
shadowOffsetX: number;
|
|
1039
|
-
shadowOffsetY: number;
|
|
1040
|
-
gtsMultiplier: number;
|
|
1041
|
-
emphasisMultiplier: number;
|
|
1042
|
-
fadeFactor: number;
|
|
1043
|
-
isInTail: boolean;
|
|
1044
|
-
}
|
|
1045
|
-
/**
|
|
1046
|
-
* Calculate emphasis effects for a word
|
|
1047
|
-
*
|
|
1048
|
-
* @param params - Emphasis calculation parameters
|
|
1049
|
-
* @returns Emphasis effects { emphasisEffect, strongEmphasisData }
|
|
1229
|
+
* Motion blur from scale deviation — matches main app WordRenderer during movement.
|
|
1230
|
+
* Authored `blur` from animation curves is separate.
|
|
1050
1231
|
*/
|
|
1051
|
-
declare function
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
isActive: boolean;
|
|
1058
|
-
wordEmotion?: string;
|
|
1059
|
-
}): {
|
|
1060
|
-
emphasisEffect: EmphasisEffect | null;
|
|
1061
|
-
strongEmphasisData: StrongEmphasisData | null;
|
|
1062
|
-
};
|
|
1232
|
+
declare function getMotionBlurAmount(scale: number, { minDeviation, maxBlur, multiplier }?: {
|
|
1233
|
+
minDeviation?: number | undefined;
|
|
1234
|
+
maxBlur?: number | undefined;
|
|
1235
|
+
multiplier?: number | undefined;
|
|
1236
|
+
}): number;
|
|
1237
|
+
declare function getCombinedBlurAmount(authoredBlur?: number, scale?: number, gts?: number): number;
|
|
1063
1238
|
|
|
1064
1239
|
/**
|
|
1065
|
-
*
|
|
1066
|
-
* WORD LETTER SPACING
|
|
1067
|
-
* ============================================
|
|
1068
|
-
*
|
|
1069
|
-
* PURPOSE:
|
|
1070
|
-
* Calculates per-letter translateX offsets for GPU-accelerated spacing (no layout reflow).
|
|
1071
|
-
* Extracted from animationEngine for better maintainability.
|
|
1072
|
-
*
|
|
1073
|
-
* USED BY:
|
|
1074
|
-
* - animationEngine: Main word animation orchestrator
|
|
1075
|
-
*
|
|
1076
|
-
* HOW IT WORKS:
|
|
1077
|
-
* 1. Detects active effects (fear shake only - emphasis spacing is disabled)
|
|
1078
|
-
* 2. Calculates per-letter translateX offsets to create spacing between letters
|
|
1079
|
-
* 3. Returns array of translateX values in pixels (one per letter)
|
|
1080
|
-
*
|
|
1081
|
-
* KEY FEATURES:
|
|
1082
|
-
* - Transform-based spacing (GPU-accelerated, no layout reflow)
|
|
1083
|
-
* - Letter spacing disabled for emphasis effects (standard and strong)
|
|
1084
|
-
* - Only fear shake effects get letter spacing (if needed)
|
|
1085
|
-
* - Zero baseline for clean transitions
|
|
1240
|
+
* Emotion Importance Processing
|
|
1086
1241
|
*
|
|
1087
|
-
*
|
|
1088
|
-
*
|
|
1089
|
-
*
|
|
1090
|
-
* - All spacing animations run on GPU compositor layer
|
|
1242
|
+
* Core emotions (anger, fear, sadness, joy) are prioritized over secondary emotions
|
|
1243
|
+
* by multiplying their intensity by 1.5 before selection.
|
|
1244
|
+
* Identical to monorepo app/utils/data/emotionImportance.js
|
|
1091
1245
|
*/
|
|
1092
|
-
interface WordLetterSpacingParams {
|
|
1093
|
-
strongEmphasisData?: any;
|
|
1094
|
-
emphasisEffect?: any;
|
|
1095
|
-
wordLetterShakeIntensity: number | null;
|
|
1096
|
-
wordFontFamily: string;
|
|
1097
|
-
currentTime: number;
|
|
1098
|
-
word: any;
|
|
1099
|
-
emotionAnimationDuration: number;
|
|
1100
|
-
wordEmotion?: string;
|
|
1101
|
-
totalLetters: number;
|
|
1102
|
-
fontSize: number;
|
|
1103
|
-
}
|
|
1104
1246
|
/**
|
|
1105
|
-
*
|
|
1247
|
+
* Process emotions with importance factors
|
|
1106
1248
|
*
|
|
1107
|
-
*
|
|
1108
|
-
*
|
|
1249
|
+
* Core emotions (anger, fear, sadness, joy) get ×1.5 multiplier
|
|
1250
|
+
* Secondary emotions get ×1.0 multiplier
|
|
1251
|
+
*
|
|
1252
|
+
* @param emotions - Array of [emotion, intensity] tuples
|
|
1253
|
+
* @returns Array of [emotion, originalIntensity, adjustedIntensity, importanceFactor, isCore] tuples
|
|
1109
1254
|
*/
|
|
1110
|
-
declare function
|
|
1255
|
+
declare function processEmotionsWithImportance(emotions: Array<[string, number]>): Array<[string, number, number, number, boolean]>;
|
|
1111
1256
|
|
|
1112
1257
|
/**
|
|
1113
1258
|
* Backend Data Accessors
|
|
@@ -1117,6 +1262,21 @@ declare function calculateWordLetterSpacing({ strongEmphasisData, emphasisEffect
|
|
|
1117
1262
|
* Identical to monorepo app/utils/data/backendDataAccessors.js
|
|
1118
1263
|
*/
|
|
1119
1264
|
|
|
1265
|
+
/**
|
|
1266
|
+
* Get word emphasis data
|
|
1267
|
+
*/
|
|
1268
|
+
declare function getWordEmphasis(word: any): {
|
|
1269
|
+
confidence: any;
|
|
1270
|
+
emphasis: any;
|
|
1271
|
+
hasEmphasis: boolean;
|
|
1272
|
+
hasStrongEmphasis: boolean;
|
|
1273
|
+
};
|
|
1274
|
+
/**
|
|
1275
|
+
* Get subtitle text content
|
|
1276
|
+
*
|
|
1277
|
+
* Handles both 'subtitle' and 'text' properties
|
|
1278
|
+
*/
|
|
1279
|
+
declare function getSubtitleText(subtitle: SubtitleSegment | null): string;
|
|
1120
1280
|
/**
|
|
1121
1281
|
* Get subtitle words array
|
|
1122
1282
|
*/
|
|
@@ -1140,24 +1300,6 @@ declare function getMergedSubtitles(subtitle: SubtitleSegment | null): SubtitleS
|
|
|
1140
1300
|
*/
|
|
1141
1301
|
declare function findSubtitleForWord(subtitles: SubtitleSegment[], word: any): SubtitleSegment | null;
|
|
1142
1302
|
|
|
1143
|
-
/**
|
|
1144
|
-
* Emotion Importance Processing
|
|
1145
|
-
*
|
|
1146
|
-
* Core emotions (anger, fear, sadness, joy) are prioritized over secondary emotions
|
|
1147
|
-
* by multiplying their intensity by 1.5 before selection.
|
|
1148
|
-
* Identical to monorepo app/utils/data/emotionImportance.js
|
|
1149
|
-
*/
|
|
1150
|
-
/**
|
|
1151
|
-
* Process emotions with importance factors
|
|
1152
|
-
*
|
|
1153
|
-
* Core emotions (anger, fear, sadness, joy) get ×1.5 multiplier
|
|
1154
|
-
* Secondary emotions get ×1.0 multiplier
|
|
1155
|
-
*
|
|
1156
|
-
* @param emotions - Array of [emotion, intensity] tuples
|
|
1157
|
-
* @returns Array of [emotion, originalIntensity, adjustedIntensity, importanceFactor, isCore] tuples
|
|
1158
|
-
*/
|
|
1159
|
-
declare function processEmotionsWithImportance(emotions: Array<[string, number]>): Array<[string, number, number, number, boolean]>;
|
|
1160
|
-
|
|
1161
1303
|
/**
|
|
1162
1304
|
* Variable Font Calculations
|
|
1163
1305
|
*
|
|
@@ -1204,34 +1346,8 @@ declare function calculateWeightFromVolume(volume: number | undefined, weightAxi
|
|
|
1204
1346
|
*/
|
|
1205
1347
|
declare function calculateWidthFromSpeechRate(speechRate: number | undefined, widthAxis: FontAxisConfig | undefined, baseWidth?: number): number;
|
|
1206
1348
|
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
*
|
|
1210
|
-
* TODO: Extract from app/hooks/subtitle/useSentenceAnimation.js and useWordAnimation.js
|
|
1211
|
-
*
|
|
1212
|
-
* This module should provide:
|
|
1213
|
-
* - createSubtitleEngine(track) - creates engine instance
|
|
1214
|
-
* - engine.at(time) - returns SubtitleEngineState for given time
|
|
1215
|
-
* - Handle karaoke mode (word-by-word) and sentence mode
|
|
1216
|
-
* - Handle edge cases: gaps, overlaps, end-of-video
|
|
1217
|
-
*/
|
|
1218
|
-
|
|
1219
|
-
declare function createSubtitleEngine(track: SubtitleTrack): {
|
|
1220
|
-
at(time: number): SubtitleEngineState;
|
|
1221
|
-
};
|
|
1222
|
-
|
|
1223
|
-
/**
|
|
1224
|
-
* Emotion → Style Mapper
|
|
1225
|
-
*
|
|
1226
|
-
* TODO: Extract from app/config/animation/ directory
|
|
1227
|
-
*
|
|
1228
|
-
* This module should provide:
|
|
1229
|
-
* - getEmotionStyle(emotion, intensity) - maps emotion to CSS styles
|
|
1230
|
-
* - Handle all 6 emotions: joy, anger, sadness, fear, disgust, surprise
|
|
1231
|
-
* - Support intensity scaling (0-1)
|
|
1232
|
-
*/
|
|
1233
|
-
|
|
1234
|
-
declare function getEmotionStyle(emotion: Emotion, intensity: number): EmotionStyle;
|
|
1349
|
+
declare function ensureFont(fontFamily: string | undefined | null): void;
|
|
1350
|
+
declare function preloadAnimationFonts(): void;
|
|
1235
1351
|
|
|
1236
1352
|
/**
|
|
1237
1353
|
* PHONT API Client
|
|
@@ -1287,7 +1403,11 @@ declare class PhontClient {
|
|
|
1287
1403
|
/**
|
|
1288
1404
|
* Register a new user
|
|
1289
1405
|
*/
|
|
1290
|
-
register(username: string, email: string, password: string
|
|
1406
|
+
register(username: string, email: string, password: string, profile: {
|
|
1407
|
+
company: string;
|
|
1408
|
+
first_name: string;
|
|
1409
|
+
last_name: string;
|
|
1410
|
+
}): Promise<RegisterResponse>;
|
|
1291
1411
|
/**
|
|
1292
1412
|
* Get subtitle track for a VOD
|
|
1293
1413
|
* Requires: Session token authentication
|
|
@@ -1343,4 +1463,4 @@ declare class PhontClient {
|
|
|
1343
1463
|
clearCredentials(): void;
|
|
1344
1464
|
}
|
|
1345
1465
|
|
|
1346
|
-
export { ANIMATION_STYLING, type AnimationOptions, type AnimationParameterStates, type
|
|
1466
|
+
export { ANIMATION_STYLING, ANIMATION_URLS, AUTHORED_PLAYBACK_OPTIONS, type AnimationFetcher, type AnimationOptions, type AnimationParameterState, type AnimationParameterStates, type AnimationRecord, type AnimationState, type CurvePoint, EMOTION_ANIMATION_URLS, type Emotion, type EmotionSelectionResult, type EmotionStyle, type EmphasisEffect, type FontAxisConfig, type FontConfig, type JoyEffect, type Letter, type LoginResponse, type ParameterState, type ParameterStates, PhontClient, type PhontClientOptions, type PublishedAnimationResolver, REFERENCE_GTS, REFERENCE_INTENSITY, RENDERING_CONTROL, type RegisterResponse, type SentenceAnimationState, type StateCallback, type StrongEmphasisData, type Stylesheet, type SubtitleEngineState, type SubtitleLine, SubtitleManager, type SubtitleSegment, type SubtitleState$1 as SubtitleState, SubtitleStateManager, type SubtitleTrack, type SubtitleWord, type VodMetadata, type VodState$1 as VodState, type Word, type WordAnimationState, type WordLetterSpacingParams, calculateAnimationParameters, calculateAnimationState, calculateDynamicWordSpacing, calculateEmphasisMultiplier, calculateGTSValues, calculateJoy, calculateJoyBulge, calculateNormalizedTime, calculateWeightFromVolume, calculateWidthFromSpeechRate, calculateWordEmphasisEffects, calculateWordLetterSpacing, capEmotionIntensity, computeProsodyWeight, createPublishedAnimationResolver, decodeAnimationUrl, ensureFont, findSubtitleForWord, generateTextShadow, getAnimationUrlForEmotion, getCombinedBlurAmount, getFontFamilyCSS, getJoyAnimationMode, getJoyFilter, getJoyTransform, getMergedSubtitles, getMotionBlurAmount, getSubtitleAnimations, getSubtitleText, getSubtitleTiming, getSubtitleWords, getWordEmphasis, hasMergedSubtitles, hockeyStickIntensity, isInEmphasisRange, isInStrongEmphasisRange, meetsEmotionThreshold, preloadAnimationFonts, processEmotionsWithImportance, resolveEffectiveGts, sampleParameterCurve, selectEmotion, selectFontFamily, shouldUseAngryFont, shouldUseJoyFont, shouldUseSadnessFont, splitTextIntoLetters, subtitleManager };
|