@shotstack/shotstack-canvas 2.1.5 → 2.1.6

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.
@@ -18,8 +18,7 @@ import {
18
18
  svgShadowSchema,
19
19
  svgTransformSchema,
20
20
  svgGradientStopSchema,
21
- richCaptionActiveSchema as baseCaptionActiveSchema,
22
- richCaptionWordAnimationSchema as baseCaptionWordAnimationSchema
21
+ richCaptionActiveSchema as baseCaptionActiveSchema
23
22
  } from "@shotstack/schemas/zod";
24
23
 
25
24
  // src/config/canvas-constants.ts
@@ -198,23 +197,28 @@ var richCaptionActiveSchema = baseCaptionActiveSchema.extend({
198
197
  opacity: z.number().min(0).max(1).optional(),
199
198
  textDecoration: z.enum(["none", "underline", "line-through"]).optional()
200
199
  }).optional(),
201
- stroke: z.object({
202
- width: z.number().min(0).optional(),
203
- color: z.string().regex(HEX6).optional(),
204
- opacity: z.number().min(0).max(1).optional()
205
- }).optional(),
206
- shadow: z.object({
207
- offsetX: z.number().optional(),
208
- offsetY: z.number().optional(),
209
- blur: z.number().min(0).optional(),
210
- color: z.string().regex(HEX6).optional(),
211
- opacity: z.number().min(0).max(1).optional()
212
- }).optional(),
200
+ stroke: z.union([
201
+ z.object({
202
+ width: z.number().min(0).optional(),
203
+ color: z.string().regex(HEX6).optional(),
204
+ opacity: z.number().min(0).max(1).optional()
205
+ }),
206
+ z.literal("none")
207
+ ]).optional(),
208
+ shadow: z.union([
209
+ z.object({
210
+ offsetX: z.number().optional(),
211
+ offsetY: z.number().optional(),
212
+ blur: z.number().min(0).optional(),
213
+ color: z.string().regex(HEX6).optional(),
214
+ opacity: z.number().min(0).max(1).optional()
215
+ }),
216
+ z.literal("none")
217
+ ]).optional(),
213
218
  scale: z.number().min(0.5).max(2).default(1)
214
219
  });
215
- var richCaptionWordAnimationSchema = baseCaptionWordAnimationSchema.extend({
220
+ var richCaptionWordAnimationSchema = z.object({
216
221
  style: z.enum(["karaoke", "highlight", "pop", "fade", "slide", "bounce", "typewriter", "none"]).default("highlight"),
217
- speed: z.number().min(0.5).max(2).default(1),
218
222
  direction: z.enum(["left", "right", "up", "down"]).default("up")
219
223
  });
220
224
  var richCaptionAssetSchema = z.object({
@@ -2642,12 +2646,8 @@ function calculateWordProgress(ctx) {
2642
2646
  function isWordActive(ctx) {
2643
2647
  return ctx.currentTime >= ctx.wordStart && ctx.currentTime < ctx.wordEnd;
2644
2648
  }
2645
- function calculateKaraokeState(ctx, speed) {
2649
+ function calculateKaraokeState(ctx) {
2646
2650
  const isActive = isWordActive(ctx);
2647
- const wordDuration = ctx.wordEnd - ctx.wordStart;
2648
- const adjustedDuration = wordDuration / speed;
2649
- const adjustedEnd = ctx.wordStart + adjustedDuration;
2650
- const adjustedCtx = { ...ctx, wordEnd: adjustedEnd };
2651
2651
  if (ctx.currentTime < ctx.wordStart) {
2652
2652
  return {
2653
2653
  fillProgress: 0,
@@ -2655,7 +2655,7 @@ function calculateKaraokeState(ctx, speed) {
2655
2655
  opacity: 1
2656
2656
  };
2657
2657
  }
2658
- if (ctx.currentTime >= adjustedEnd) {
2658
+ if (ctx.currentTime >= ctx.wordEnd) {
2659
2659
  return {
2660
2660
  fillProgress: 1,
2661
2661
  isActive: false,
@@ -2663,7 +2663,7 @@ function calculateKaraokeState(ctx, speed) {
2663
2663
  };
2664
2664
  }
2665
2665
  return {
2666
- fillProgress: calculateWordProgress(adjustedCtx),
2666
+ fillProgress: calculateWordProgress(ctx),
2667
2667
  isActive,
2668
2668
  opacity: 1
2669
2669
  };
@@ -2676,7 +2676,7 @@ function calculateHighlightState(ctx) {
2676
2676
  opacity: 1
2677
2677
  };
2678
2678
  }
2679
- function calculatePopState(ctx, activeScale, speed) {
2679
+ function calculatePopState(ctx, activeScale) {
2680
2680
  if (ctx.currentTime < ctx.wordStart) {
2681
2681
  return {
2682
2682
  scale: 0.5,
@@ -2685,9 +2685,7 @@ function calculatePopState(ctx, activeScale, speed) {
2685
2685
  fillProgress: 0
2686
2686
  };
2687
2687
  }
2688
- const adjustedDuration = ctx.animationDuration / speed;
2689
- const adjustedCtx = { ...ctx, animationDuration: adjustedDuration };
2690
- const progress = calculateAnimationProgress(adjustedCtx);
2688
+ const progress = calculateAnimationProgress(ctx);
2691
2689
  const easedProgress = easeOutBack(progress);
2692
2690
  const startScale = 0.5;
2693
2691
  const isActive = isWordActive(ctx);
@@ -2700,7 +2698,7 @@ function calculatePopState(ctx, activeScale, speed) {
2700
2698
  fillProgress: isActive ? 1 : 0
2701
2699
  };
2702
2700
  }
2703
- function calculateFadeState(ctx, speed) {
2701
+ function calculateFadeState(ctx) {
2704
2702
  if (ctx.currentTime < ctx.wordStart) {
2705
2703
  return {
2706
2704
  opacity: 0,
@@ -2708,9 +2706,7 @@ function calculateFadeState(ctx, speed) {
2708
2706
  fillProgress: 0
2709
2707
  };
2710
2708
  }
2711
- const adjustedDuration = ctx.animationDuration / speed;
2712
- const adjustedCtx = { ...ctx, animationDuration: adjustedDuration };
2713
- const progress = calculateAnimationProgress(adjustedCtx);
2709
+ const progress = calculateAnimationProgress(ctx);
2714
2710
  const easedProgress = easeInOutQuad(progress);
2715
2711
  const isActive = isWordActive(ctx);
2716
2712
  return {
@@ -2719,7 +2715,7 @@ function calculateFadeState(ctx, speed) {
2719
2715
  fillProgress: isActive ? 1 : 0
2720
2716
  };
2721
2717
  }
2722
- function calculateSlideState(ctx, direction, speed, fontSize) {
2718
+ function calculateSlideState(ctx, direction, fontSize) {
2723
2719
  const slideDistance = fontSize * 1.5;
2724
2720
  if (ctx.currentTime < ctx.wordStart) {
2725
2721
  const offset2 = getDirectionOffset(direction, slideDistance);
@@ -2731,9 +2727,7 @@ function calculateSlideState(ctx, direction, speed, fontSize) {
2731
2727
  fillProgress: 0
2732
2728
  };
2733
2729
  }
2734
- const adjustedDuration = ctx.animationDuration / speed;
2735
- const adjustedCtx = { ...ctx, animationDuration: adjustedDuration };
2736
- const progress = calculateAnimationProgress(adjustedCtx);
2730
+ const progress = calculateAnimationProgress(ctx);
2737
2731
  const easedProgress = easeOutCirc(progress);
2738
2732
  const offset = getDirectionOffset(direction, slideDistance);
2739
2733
  const translateX = offset.x * (1 - easedProgress);
@@ -2759,7 +2753,7 @@ function getDirectionOffset(direction, distance) {
2759
2753
  return { x: 0, y: -distance };
2760
2754
  }
2761
2755
  }
2762
- function calculateBounceState(ctx, speed, fontSize) {
2756
+ function calculateBounceState(ctx, fontSize) {
2763
2757
  const bounceDistance = fontSize * 0.8;
2764
2758
  if (ctx.currentTime < ctx.wordStart) {
2765
2759
  return {
@@ -2769,9 +2763,7 @@ function calculateBounceState(ctx, speed, fontSize) {
2769
2763
  fillProgress: 0
2770
2764
  };
2771
2765
  }
2772
- const adjustedDuration = ctx.animationDuration / speed;
2773
- const adjustedCtx = { ...ctx, animationDuration: adjustedDuration };
2774
- const progress = calculateAnimationProgress(adjustedCtx);
2766
+ const progress = calculateAnimationProgress(ctx);
2775
2767
  const easedProgress = easeOutBounce(progress);
2776
2768
  const isActive = isWordActive(ctx);
2777
2769
  return {
@@ -2781,11 +2773,7 @@ function calculateBounceState(ctx, speed, fontSize) {
2781
2773
  fillProgress: isActive ? 1 : 0
2782
2774
  };
2783
2775
  }
2784
- function calculateTypewriterState(ctx, charCount, speed) {
2785
- const wordDuration = ctx.wordEnd - ctx.wordStart;
2786
- const adjustedDuration = wordDuration / speed;
2787
- const adjustedEnd = ctx.wordStart + adjustedDuration;
2788
- const adjustedCtx = { ...ctx, wordEnd: adjustedEnd };
2776
+ function calculateTypewriterState(ctx, charCount) {
2789
2777
  if (ctx.currentTime < ctx.wordStart) {
2790
2778
  return {
2791
2779
  visibleCharacters: 0,
@@ -2794,7 +2782,7 @@ function calculateTypewriterState(ctx, charCount, speed) {
2794
2782
  fillProgress: 0
2795
2783
  };
2796
2784
  }
2797
- if (ctx.currentTime >= adjustedEnd) {
2785
+ if (ctx.currentTime >= ctx.wordEnd) {
2798
2786
  return {
2799
2787
  visibleCharacters: charCount,
2800
2788
  opacity: 1,
@@ -2802,7 +2790,7 @@ function calculateTypewriterState(ctx, charCount, speed) {
2802
2790
  fillProgress: 0
2803
2791
  };
2804
2792
  }
2805
- const progress = calculateWordProgress(adjustedCtx);
2793
+ const progress = calculateWordProgress(ctx);
2806
2794
  const visibleCharacters = Math.ceil(progress * charCount);
2807
2795
  const isActive = isWordActive(ctx);
2808
2796
  return {
@@ -2820,7 +2808,6 @@ function calculateNoneState(_ctx) {
2820
2808
  };
2821
2809
  }
2822
2810
  function calculateWordAnimationState(wordStart, wordEnd, currentTime, config, activeScale = 1, charCount = 0, fontSize = 48, isRTL = false) {
2823
- const safeSpeed = config.speed > 0 ? config.speed : 1;
2824
2811
  const ctx = {
2825
2812
  wordStart,
2826
2813
  wordEnd,
@@ -2831,27 +2818,27 @@ function calculateWordAnimationState(wordStart, wordEnd, currentTime, config, ac
2831
2818
  let partialState;
2832
2819
  switch (config.style) {
2833
2820
  case "karaoke":
2834
- partialState = calculateKaraokeState(ctx, safeSpeed);
2821
+ partialState = calculateKaraokeState(ctx);
2835
2822
  break;
2836
2823
  case "highlight":
2837
2824
  partialState = calculateHighlightState(ctx);
2838
2825
  break;
2839
2826
  case "pop":
2840
- partialState = calculatePopState(ctx, activeScale, safeSpeed);
2827
+ partialState = calculatePopState(ctx, activeScale);
2841
2828
  break;
2842
2829
  case "fade":
2843
- partialState = calculateFadeState(ctx, safeSpeed);
2830
+ partialState = calculateFadeState(ctx);
2844
2831
  break;
2845
2832
  case "slide": {
2846
2833
  const slideDir = mirrorAnimationDirection(config.direction, isRTL);
2847
- partialState = calculateSlideState(ctx, slideDir, config.speed, fontSize);
2834
+ partialState = calculateSlideState(ctx, slideDir, fontSize);
2848
2835
  break;
2849
2836
  }
2850
2837
  case "bounce":
2851
- partialState = calculateBounceState(ctx, safeSpeed, fontSize);
2838
+ partialState = calculateBounceState(ctx, fontSize);
2852
2839
  break;
2853
2840
  case "typewriter":
2854
- partialState = calculateTypewriterState(ctx, charCount, safeSpeed);
2841
+ partialState = calculateTypewriterState(ctx, charCount);
2855
2842
  break;
2856
2843
  case "none":
2857
2844
  default:
@@ -2884,7 +2871,6 @@ function calculateAnimationStatesForGroup(words, currentTime, config, activeScal
2884
2871
  function getDefaultAnimationConfig() {
2885
2872
  return {
2886
2873
  style: "highlight",
2887
- speed: 1,
2888
2874
  direction: "up"
2889
2875
  };
2890
2876
  }
@@ -2925,18 +2911,17 @@ function extractFontConfig(asset) {
2925
2911
  function extractStrokeConfig(asset, isActive) {
2926
2912
  const baseStroke = asset.stroke;
2927
2913
  const activeStroke = asset.active?.stroke;
2928
- if (!baseStroke && !activeStroke) {
2929
- return void 0;
2930
- }
2931
2914
  if (isActive) {
2932
- if (!activeStroke) {
2915
+ if (activeStroke === "none") {
2933
2916
  return void 0;
2934
2917
  }
2935
- return {
2936
- width: activeStroke.width ?? baseStroke?.width ?? 0,
2937
- color: activeStroke.color ?? baseStroke?.color ?? "#000000",
2938
- opacity: activeStroke.opacity ?? baseStroke?.opacity ?? 1
2939
- };
2918
+ if (activeStroke && typeof activeStroke === "object") {
2919
+ return {
2920
+ width: activeStroke.width ?? baseStroke?.width ?? 0,
2921
+ color: activeStroke.color ?? baseStroke?.color ?? "#000000",
2922
+ opacity: activeStroke.opacity ?? baseStroke?.opacity ?? 1
2923
+ };
2924
+ }
2940
2925
  }
2941
2926
  if (baseStroke) {
2942
2927
  return {
@@ -2950,20 +2935,19 @@ function extractStrokeConfig(asset, isActive) {
2950
2935
  function extractShadowConfig(asset, isActive) {
2951
2936
  const baseShadow = asset.shadow;
2952
2937
  const activeShadow = asset.active?.shadow;
2953
- if (!baseShadow && !activeShadow) {
2954
- return void 0;
2955
- }
2956
2938
  if (isActive) {
2957
- if (!activeShadow) {
2939
+ if (activeShadow === "none") {
2958
2940
  return void 0;
2959
2941
  }
2960
- return {
2961
- offsetX: activeShadow.offsetX ?? baseShadow?.offsetX ?? 0,
2962
- offsetY: activeShadow.offsetY ?? baseShadow?.offsetY ?? 0,
2963
- blur: activeShadow.blur ?? baseShadow?.blur ?? 0,
2964
- color: activeShadow.color ?? baseShadow?.color ?? "#000000",
2965
- opacity: activeShadow.opacity ?? baseShadow?.opacity ?? 0.5
2966
- };
2942
+ if (activeShadow && typeof activeShadow === "object") {
2943
+ return {
2944
+ offsetX: activeShadow.offsetX ?? baseShadow?.offsetX ?? 0,
2945
+ offsetY: activeShadow.offsetY ?? baseShadow?.offsetY ?? 0,
2946
+ blur: activeShadow.blur ?? baseShadow?.blur ?? 0,
2947
+ color: activeShadow.color ?? baseShadow?.color ?? "#000000",
2948
+ opacity: activeShadow.opacity ?? baseShadow?.opacity ?? 0.5
2949
+ };
2950
+ }
2967
2951
  }
2968
2952
  if (baseShadow) {
2969
2953
  return {
@@ -2979,7 +2963,12 @@ function extractShadowConfig(asset, isActive) {
2979
2963
  function extractBackgroundConfig(asset, isActive, fontSize) {
2980
2964
  const fontBackground = asset.font?.background;
2981
2965
  const activeBackground = asset.active?.font?.background;
2982
- const bgColor = isActive && activeBackground ? activeBackground : fontBackground;
2966
+ let bgColor;
2967
+ if (isActive) {
2968
+ bgColor = activeBackground ?? fontBackground;
2969
+ } else {
2970
+ bgColor = fontBackground;
2971
+ }
2983
2972
  if (!bgColor) {
2984
2973
  return void 0;
2985
2974
  }
@@ -3047,7 +3036,6 @@ function extractAnimationConfig(asset) {
3047
3036
  }
3048
3037
  return {
3049
3038
  style: wordAnim.style ?? "highlight",
3050
- speed: wordAnim.speed ?? 1,
3051
3039
  direction: wordAnim.direction ?? "up"
3052
3040
  };
3053
3041
  }
@@ -5467,7 +5455,7 @@ function findActiveWordIndex(store, groupWordIndices, timeMs) {
5467
5455
  }
5468
5456
  return -1;
5469
5457
  }
5470
- function getAnimationPhase(store, groupWordIndices, timeMs, animationStyle, speed) {
5458
+ function getAnimationPhase(store, groupWordIndices, timeMs, animationStyle) {
5471
5459
  if (groupWordIndices.length === 0) {
5472
5460
  return "idle";
5473
5461
  }
@@ -5484,7 +5472,7 @@ function getAnimationPhase(store, groupWordIndices, timeMs, animationStyle, spee
5484
5472
  return "after";
5485
5473
  }
5486
5474
  if (TRANSITION_ANIMATION_STYLES.has(animationStyle)) {
5487
- const transitionDurationMs = (ANIMATION_DURATION_MS[animationStyle] ?? 200) / speed;
5475
+ const transitionDurationMs = ANIMATION_DURATION_MS[animationStyle] ?? 200;
5488
5476
  for (const idx of groupWordIndices) {
5489
5477
  const wordStart = store.startTimes[idx];
5490
5478
  if (timeMs >= wordStart && timeMs < wordStart + transitionDurationMs) {
@@ -5506,7 +5494,7 @@ function getAnimationPhase(store, groupWordIndices, timeMs, animationStyle, spee
5506
5494
  }
5507
5495
  return "before";
5508
5496
  }
5509
- function computeStateSignature(layout, timeMs, animationStyle, speed) {
5497
+ function computeStateSignature(layout, timeMs, animationStyle) {
5510
5498
  const groupIndex = findGroupIndexAtTime(layout.groups, timeMs);
5511
5499
  if (groupIndex === -1) {
5512
5500
  return { groupIndex: -1, activeWordIndex: -1, animationPhase: "idle" };
@@ -5517,21 +5505,20 @@ function computeStateSignature(layout, timeMs, animationStyle, speed) {
5517
5505
  layout.store,
5518
5506
  group.wordIndices,
5519
5507
  timeMs,
5520
- animationStyle,
5521
- speed
5508
+ animationStyle
5522
5509
  );
5523
5510
  return { groupIndex, activeWordIndex, animationPhase };
5524
5511
  }
5525
5512
  function signaturesMatch(a, b) {
5526
5513
  return a.groupIndex === b.groupIndex && a.activeWordIndex === b.activeWordIndex && a.animationPhase === b.animationPhase;
5527
5514
  }
5528
- function createFrameSchedule(layout, durationMs, fps, animationStyle = "highlight", speed = 1) {
5515
+ function createFrameSchedule(layout, durationMs, fps, animationStyle = "highlight") {
5529
5516
  const totalFrames = Math.max(2, Math.round(durationMs / 1e3 * fps) + 1);
5530
5517
  const renderFrames = [];
5531
5518
  let previousSignature = null;
5532
5519
  for (let frame = 0; frame < totalFrames; frame++) {
5533
5520
  const timeMs = frame / (totalFrames - 1) * durationMs;
5534
- const signature = computeStateSignature(layout, timeMs, animationStyle, speed);
5521
+ const signature = computeStateSignature(layout, timeMs, animationStyle);
5535
5522
  const isAnimating = signature.animationPhase === "animating";
5536
5523
  if (isAnimating || previousSignature === null || !signaturesMatch(signature, previousSignature)) {
5537
5524
  renderFrames.push({
@@ -5933,14 +5920,12 @@ var RichCaptionRenderer = class {
5933
5920
  throw new Error("No asset loaded. Call loadAsset() first.");
5934
5921
  }
5935
5922
  const animationStyle = this.extractAnimationStyle();
5936
- const animationSpeed = this.extractAnimationSpeed();
5937
5923
  const durationMs = duration * 1e3;
5938
5924
  const schedule = createFrameSchedule(
5939
5925
  this.currentLayout,
5940
5926
  durationMs,
5941
5927
  this.fps,
5942
- animationStyle,
5943
- animationSpeed
5928
+ animationStyle
5944
5929
  );
5945
5930
  const bgColor = options?.bgColor;
5946
5931
  const hasAlpha = !bgColor;
@@ -6101,13 +6086,11 @@ var RichCaptionRenderer = class {
6101
6086
  throw new Error("No asset loaded. Call loadAsset() first.");
6102
6087
  }
6103
6088
  const animationStyle = this.extractAnimationStyle();
6104
- const animationSpeed = this.extractAnimationSpeed();
6105
6089
  return createFrameSchedule(
6106
6090
  this.currentLayout,
6107
6091
  duration * 1e3,
6108
6092
  this.fps,
6109
- animationStyle,
6110
- animationSpeed
6093
+ animationStyle
6111
6094
  );
6112
6095
  }
6113
6096
  getStats() {
@@ -6145,10 +6128,6 @@ var RichCaptionRenderer = class {
6145
6128
  const wordAnim = this.currentAsset?.wordAnimation;
6146
6129
  return wordAnim?.style ?? "highlight";
6147
6130
  }
6148
- extractAnimationSpeed() {
6149
- const wordAnim = this.currentAsset?.wordAnimation;
6150
- return wordAnim?.speed ?? 1;
6151
- }
6152
6131
  logProgress(pct, framesProcessed, totalFrames, uniqueProcessed, uniqueTotal, fps, eta) {
6153
6132
  if (typeof process !== "undefined" && process.stderr) {
6154
6133
  process.stderr.write(
@@ -356,39 +356,38 @@ declare const richCaptionAssetSchema: z.ZodObject<{
356
356
  "line-through": "line-through";
357
357
  }>>;
358
358
  }, z.core.$strip>>;
359
- stroke: z.ZodOptional<z.ZodObject<{
359
+ stroke: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
360
360
  width: z.ZodOptional<z.ZodNumber>;
361
361
  color: z.ZodOptional<z.ZodString>;
362
362
  opacity: z.ZodOptional<z.ZodNumber>;
363
- }, z.core.$strip>>;
364
- shadow: z.ZodOptional<z.ZodObject<{
363
+ }, z.core.$strip>, z.ZodLiteral<"none">]>>;
364
+ shadow: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
365
365
  offsetX: z.ZodOptional<z.ZodNumber>;
366
366
  offsetY: z.ZodOptional<z.ZodNumber>;
367
367
  blur: z.ZodOptional<z.ZodNumber>;
368
368
  color: z.ZodOptional<z.ZodString>;
369
369
  opacity: z.ZodOptional<z.ZodNumber>;
370
- }, z.core.$strip>>;
370
+ }, z.core.$strip>, z.ZodLiteral<"none">]>>;
371
371
  scale: z.ZodDefault<z.ZodNumber>;
372
372
  }, z.core.$strict>>;
373
373
  wordAnimation: z.ZodOptional<z.ZodObject<{
374
374
  style: z.ZodDefault<z.ZodEnum<{
375
375
  typewriter: "typewriter";
376
376
  none: "none";
377
+ pop: "pop";
377
378
  karaoke: "karaoke";
378
379
  highlight: "highlight";
379
- pop: "pop";
380
380
  fade: "fade";
381
381
  slide: "slide";
382
382
  bounce: "bounce";
383
383
  }>>;
384
- speed: z.ZodDefault<z.ZodNumber>;
385
384
  direction: z.ZodDefault<z.ZodEnum<{
386
385
  right: "right";
387
386
  left: "left";
388
387
  up: "up";
389
388
  down: "down";
390
389
  }>>;
391
- }, z.core.$strict>>;
390
+ }, z.core.$strip>>;
392
391
  pauseThreshold: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
393
392
  customFonts: z.ZodOptional<z.ZodArray<z.ZodObject<{
394
393
  src: z.ZodString;
@@ -499,39 +498,38 @@ declare const CanvasRichCaptionAssetSchema: z.ZodObject<{
499
498
  "line-through": "line-through";
500
499
  }>>;
501
500
  }, z.core.$strip>>;
502
- stroke: z.ZodOptional<z.ZodObject<{
501
+ stroke: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
503
502
  width: z.ZodOptional<z.ZodNumber>;
504
503
  color: z.ZodOptional<z.ZodString>;
505
504
  opacity: z.ZodOptional<z.ZodNumber>;
506
- }, z.core.$strip>>;
507
- shadow: z.ZodOptional<z.ZodObject<{
505
+ }, z.core.$strip>, z.ZodLiteral<"none">]>>;
506
+ shadow: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
508
507
  offsetX: z.ZodOptional<z.ZodNumber>;
509
508
  offsetY: z.ZodOptional<z.ZodNumber>;
510
509
  blur: z.ZodOptional<z.ZodNumber>;
511
510
  color: z.ZodOptional<z.ZodString>;
512
511
  opacity: z.ZodOptional<z.ZodNumber>;
513
- }, z.core.$strip>>;
512
+ }, z.core.$strip>, z.ZodLiteral<"none">]>>;
514
513
  scale: z.ZodDefault<z.ZodNumber>;
515
514
  }, z.core.$strict>>;
516
515
  wordAnimation: z.ZodOptional<z.ZodObject<{
517
516
  style: z.ZodDefault<z.ZodEnum<{
518
517
  typewriter: "typewriter";
519
518
  none: "none";
519
+ pop: "pop";
520
520
  karaoke: "karaoke";
521
521
  highlight: "highlight";
522
- pop: "pop";
523
522
  fade: "fade";
524
523
  slide: "slide";
525
524
  bounce: "bounce";
526
525
  }>>;
527
- speed: z.ZodDefault<z.ZodNumber>;
528
526
  direction: z.ZodDefault<z.ZodEnum<{
529
527
  right: "right";
530
528
  left: "left";
531
529
  up: "up";
532
530
  down: "down";
533
531
  }>>;
534
- }, z.core.$strict>>;
532
+ }, z.core.$strip>>;
535
533
  pauseThreshold: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
536
534
  customFonts: z.ZodOptional<z.ZodArray<z.ZodObject<{
537
535
  src: z.ZodString;
@@ -745,7 +743,6 @@ type AnimationStyle = "karaoke" | "highlight" | "pop" | "fade" | "slide" | "boun
745
743
  type AnimationDirection = "left" | "right" | "up" | "down";
746
744
  interface WordAnimationConfig {
747
745
  style: AnimationStyle;
748
- speed: number;
749
746
  direction: AnimationDirection;
750
747
  }
751
748
  interface WordAnimationState {
@@ -1163,7 +1160,7 @@ interface FrameSchedule {
1163
1160
  uniqueFrameCount: number;
1164
1161
  skipRatio: number;
1165
1162
  }
1166
- declare function createFrameSchedule(layout: CaptionLayout, durationMs: number, fps: number, animationStyle?: AnimationStyle, speed?: number): FrameSchedule;
1163
+ declare function createFrameSchedule(layout: CaptionLayout, durationMs: number, fps: number, animationStyle?: AnimationStyle): FrameSchedule;
1167
1164
 
1168
1165
  interface RichCaptionRendererOptions {
1169
1166
  width: number;