ugcinc-render 1.5.25 → 1.5.27

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/index.d.mts CHANGED
@@ -80,6 +80,74 @@ type Hyphenation = 'none' | 'auto';
80
80
  * Text overflow behavior
81
81
  */
82
82
  type TextOverflow = 'clip' | 'ellipsis';
83
+ /**
84
+ * Shared text styling properties used by both render and UI text segments.
85
+ * This ensures feature parity between image editor and video editor text elements.
86
+ */
87
+ interface TextStyleProperties {
88
+ /** Horizontal alignment (default: 'left') */
89
+ alignment?: TextAlignment;
90
+ /** Vertical alignment within bounds (default: 'top') */
91
+ verticalAlign?: VerticalAlignment;
92
+ /** Text direction (default: 'ltr') */
93
+ direction?: TextDirection;
94
+ /** Inner padding in pixels - uniform for all sides (default: 0) */
95
+ padding?: number;
96
+ /** Top padding in pixels */
97
+ paddingTop?: number;
98
+ /** Right padding in pixels */
99
+ paddingRight?: number;
100
+ /** Bottom padding in pixels */
101
+ paddingBottom?: number;
102
+ /** Left padding in pixels */
103
+ paddingLeft?: number;
104
+ /** Extra top padding added when text has 2+ lines */
105
+ multiLineExtraPaddingTop?: number;
106
+ /** Extra right padding added when text has 2+ lines */
107
+ multiLineExtraPaddingRight?: number;
108
+ /** Extra bottom padding added when text has 2+ lines */
109
+ multiLineExtraPaddingBottom?: number;
110
+ /** Extra left padding added when text has 2+ lines */
111
+ multiLineExtraPaddingLeft?: number;
112
+ /** Font family (default: 'arial') */
113
+ fontType?: FontType;
114
+ /** Font size in pixels (default: 40) */
115
+ fontSize?: number;
116
+ /** Font weight (default: 'normal') */
117
+ fontWeight?: FontWeight;
118
+ /** Line height multiplier (default: 1.2) */
119
+ lineHeight?: number;
120
+ /** Letter spacing in pixels (default: 0) */
121
+ letterSpacing?: number;
122
+ /** How text wraps to new lines (default: 'word') */
123
+ textWrap?: TextWrap;
124
+ /** How words break across lines (default: 'normal') */
125
+ wordBreak?: WordBreak;
126
+ /** Automatic hyphenation (default: 'none') */
127
+ hyphenation?: Hyphenation;
128
+ /** Maximum lines (0 = unlimited) (default: 0) */
129
+ maxLines?: number;
130
+ /** How overflow is handled (default: 'clip') */
131
+ textOverflow?: TextOverflow;
132
+ /** Ellipsis string for overflow (default: '...') */
133
+ ellipsis?: string;
134
+ /** Text color (default: '#000000') */
135
+ color?: string;
136
+ /** Background color in hex format #RRGGBB (default: transparent) */
137
+ backgroundColor?: string;
138
+ /** Background opacity 0-100 (default: 100) */
139
+ backgroundOpacity?: number;
140
+ /** Border radius for background box - individual corners (default: 0) */
141
+ backgroundBorderRadius?: BorderRadiusConfig;
142
+ /** Text outline color (default: none) */
143
+ strokeColor?: string;
144
+ /** Outline width in pixels (default: 0) */
145
+ strokeWidth?: number;
146
+ /** When true, box shrinks to fit content (width becomes max width) */
147
+ autoWidth?: boolean;
148
+ /** Which side the box anchors to when autoWidth is true (default: 'left') */
149
+ boxAlign?: 'left' | 'center' | 'right';
150
+ }
83
151
 
84
152
  /**
85
153
  * Position and anchor types for relative element positioning
@@ -437,32 +505,16 @@ interface VideoEditorImageSegment extends VideoEditorVisualSegment {
437
505
  }
438
506
  /**
439
507
  * Text segment (UI)
508
+ *
509
+ * Extends TextStyleProperties which contains all shared text styling options.
510
+ * This ensures feature parity between image editor and video editor text elements.
440
511
  */
441
- interface VideoEditorTextSegment extends VideoEditorVisualSegment {
512
+ interface VideoEditorTextSegment extends VideoEditorVisualSegment, TextStyleProperties {
442
513
  type: 'text';
443
514
  /** UI-only: reference to text input - resolved to text before rendering */
444
515
  textInputRef?: string;
445
516
  /** Actual text content (set after textInputRef is resolved) */
446
517
  text?: string;
447
- alignment?: 'left' | 'center' | 'right' | 'justify';
448
- verticalAlign?: 'top' | 'middle' | 'bottom';
449
- direction?: 'ltr' | 'rtl';
450
- padding?: number;
451
- fontType?: 'tiktok' | 'apple' | 'arial';
452
- fontSize?: number;
453
- fontWeight?: 'normal' | 'bold';
454
- lineHeight?: number;
455
- letterSpacing?: number;
456
- textWrap?: 'word' | 'char' | 'none';
457
- wordBreak?: 'normal' | 'break-all' | 'break-word';
458
- hyphenation?: 'none' | 'auto';
459
- maxLines?: number;
460
- textOverflow?: 'clip' | 'ellipsis';
461
- ellipsis?: string;
462
- color?: string;
463
- backgroundColor?: string;
464
- strokeColor?: string;
465
- strokeWidth?: number;
466
518
  }
467
519
  /**
468
520
  * Union of all video editor segment types
@@ -600,74 +652,15 @@ interface ImageSegment extends PictureSegment {
600
652
  }
601
653
  /**
602
654
  * Text segment - rich text overlays with full typography control
655
+ *
656
+ * Extends TextStyleProperties which contains all shared text styling options.
657
+ * This ensures feature parity between image editor and video editor text elements.
603
658
  */
604
- interface TextSegment extends VisualSegment {
659
+ interface TextSegment extends VisualSegment, TextStyleProperties {
605
660
  type: 'text';
606
661
  source: '';
607
662
  /** The text content (supports emojis) */
608
663
  text: string;
609
- /** Horizontal alignment (default: 'left') */
610
- alignment?: TextAlignment;
611
- /** Vertical alignment within bounds (default: 'top') */
612
- verticalAlign?: VerticalAlignment;
613
- /** Text direction (default: 'ltr') */
614
- direction?: TextDirection;
615
- /** Inner padding in pixels - uniform for all sides (default: 0). Overridden by individual padding values if set. */
616
- padding?: number;
617
- /** Top padding in pixels (overrides uniform padding) */
618
- paddingTop?: number;
619
- /** Right padding in pixels (overrides uniform padding) */
620
- paddingRight?: number;
621
- /** Bottom padding in pixels (overrides uniform padding) */
622
- paddingBottom?: number;
623
- /** Left padding in pixels (overrides uniform padding) */
624
- paddingLeft?: number;
625
- /** Extra top padding added when text has 2+ lines */
626
- multiLineExtraPaddingTop?: number;
627
- /** Extra right padding added when text has 2+ lines */
628
- multiLineExtraPaddingRight?: number;
629
- /** Extra bottom padding added when text has 2+ lines */
630
- multiLineExtraPaddingBottom?: number;
631
- /** Extra left padding added when text has 2+ lines */
632
- multiLineExtraPaddingLeft?: number;
633
- /** Font family (default: 'arial') */
634
- fontType?: FontType;
635
- /** Font size in pixels (default: 40) */
636
- fontSize?: number;
637
- /** Font weight (default: 'normal') */
638
- fontWeight?: FontWeight;
639
- /** Line height multiplier (default: 1.2) */
640
- lineHeight?: number;
641
- /** Letter spacing in pixels (default: 0) */
642
- letterSpacing?: number;
643
- /** How text wraps to new lines (default: 'word') */
644
- textWrap?: TextWrap;
645
- /** How words break across lines (default: 'normal') */
646
- wordBreak?: WordBreak;
647
- /** Automatic hyphenation (default: 'none') */
648
- hyphenation?: Hyphenation;
649
- /** Maximum lines (0 = unlimited) (default: 0) */
650
- maxLines?: number;
651
- /** How overflow is handled (default: 'clip') */
652
- textOverflow?: TextOverflow;
653
- /** Ellipsis string for overflow (default: '...') */
654
- ellipsis?: string;
655
- /** Text color (default: '#000000') */
656
- color?: string;
657
- /** Background color in hex format #RRGGBB (default: transparent) */
658
- backgroundColor?: string;
659
- /** Background opacity 0-100 (default: 100) */
660
- backgroundOpacity?: number;
661
- /** Border radius for background box - individual corners (default: 0) */
662
- backgroundBorderRadius?: BorderRadiusConfig;
663
- /** Text outline color (default: none) */
664
- strokeColor?: string;
665
- /** Outline width in pixels (default: 0) */
666
- strokeWidth?: number;
667
- /** When true, box shrinks to fit content (width becomes max width) */
668
- autoWidth?: boolean;
669
- /** Which side the box anchors to when autoWidth is true (default: 'left') */
670
- boxAlign?: 'left' | 'center' | 'right';
671
664
  }
672
665
  /**
673
666
  * Audio segment - background audio or music
@@ -1365,8 +1358,11 @@ declare function useResolvedPositions(elements: ImageEditorElement[], textValues
1365
1358
  *
1366
1359
  * This file registers all available compositions with the renderer.
1367
1360
  * It serves as the entry point for the renderer bundler.
1361
+ *
1362
+ * Uses calculateMetadata for ImageEditorComposition to determine
1363
+ * dynamic crop dimensions in the browser environment (with DOM access).
1368
1364
  */
1369
1365
 
1370
1366
  declare const RenderRoot: React.FC;
1371
1367
 
1372
- export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, debugFontStatus, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
1368
+ export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextStyleProperties, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, debugFontStatus, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
package/dist/index.d.ts CHANGED
@@ -80,6 +80,74 @@ type Hyphenation = 'none' | 'auto';
80
80
  * Text overflow behavior
81
81
  */
82
82
  type TextOverflow = 'clip' | 'ellipsis';
83
+ /**
84
+ * Shared text styling properties used by both render and UI text segments.
85
+ * This ensures feature parity between image editor and video editor text elements.
86
+ */
87
+ interface TextStyleProperties {
88
+ /** Horizontal alignment (default: 'left') */
89
+ alignment?: TextAlignment;
90
+ /** Vertical alignment within bounds (default: 'top') */
91
+ verticalAlign?: VerticalAlignment;
92
+ /** Text direction (default: 'ltr') */
93
+ direction?: TextDirection;
94
+ /** Inner padding in pixels - uniform for all sides (default: 0) */
95
+ padding?: number;
96
+ /** Top padding in pixels */
97
+ paddingTop?: number;
98
+ /** Right padding in pixels */
99
+ paddingRight?: number;
100
+ /** Bottom padding in pixels */
101
+ paddingBottom?: number;
102
+ /** Left padding in pixels */
103
+ paddingLeft?: number;
104
+ /** Extra top padding added when text has 2+ lines */
105
+ multiLineExtraPaddingTop?: number;
106
+ /** Extra right padding added when text has 2+ lines */
107
+ multiLineExtraPaddingRight?: number;
108
+ /** Extra bottom padding added when text has 2+ lines */
109
+ multiLineExtraPaddingBottom?: number;
110
+ /** Extra left padding added when text has 2+ lines */
111
+ multiLineExtraPaddingLeft?: number;
112
+ /** Font family (default: 'arial') */
113
+ fontType?: FontType;
114
+ /** Font size in pixels (default: 40) */
115
+ fontSize?: number;
116
+ /** Font weight (default: 'normal') */
117
+ fontWeight?: FontWeight;
118
+ /** Line height multiplier (default: 1.2) */
119
+ lineHeight?: number;
120
+ /** Letter spacing in pixels (default: 0) */
121
+ letterSpacing?: number;
122
+ /** How text wraps to new lines (default: 'word') */
123
+ textWrap?: TextWrap;
124
+ /** How words break across lines (default: 'normal') */
125
+ wordBreak?: WordBreak;
126
+ /** Automatic hyphenation (default: 'none') */
127
+ hyphenation?: Hyphenation;
128
+ /** Maximum lines (0 = unlimited) (default: 0) */
129
+ maxLines?: number;
130
+ /** How overflow is handled (default: 'clip') */
131
+ textOverflow?: TextOverflow;
132
+ /** Ellipsis string for overflow (default: '...') */
133
+ ellipsis?: string;
134
+ /** Text color (default: '#000000') */
135
+ color?: string;
136
+ /** Background color in hex format #RRGGBB (default: transparent) */
137
+ backgroundColor?: string;
138
+ /** Background opacity 0-100 (default: 100) */
139
+ backgroundOpacity?: number;
140
+ /** Border radius for background box - individual corners (default: 0) */
141
+ backgroundBorderRadius?: BorderRadiusConfig;
142
+ /** Text outline color (default: none) */
143
+ strokeColor?: string;
144
+ /** Outline width in pixels (default: 0) */
145
+ strokeWidth?: number;
146
+ /** When true, box shrinks to fit content (width becomes max width) */
147
+ autoWidth?: boolean;
148
+ /** Which side the box anchors to when autoWidth is true (default: 'left') */
149
+ boxAlign?: 'left' | 'center' | 'right';
150
+ }
83
151
 
84
152
  /**
85
153
  * Position and anchor types for relative element positioning
@@ -437,32 +505,16 @@ interface VideoEditorImageSegment extends VideoEditorVisualSegment {
437
505
  }
438
506
  /**
439
507
  * Text segment (UI)
508
+ *
509
+ * Extends TextStyleProperties which contains all shared text styling options.
510
+ * This ensures feature parity between image editor and video editor text elements.
440
511
  */
441
- interface VideoEditorTextSegment extends VideoEditorVisualSegment {
512
+ interface VideoEditorTextSegment extends VideoEditorVisualSegment, TextStyleProperties {
442
513
  type: 'text';
443
514
  /** UI-only: reference to text input - resolved to text before rendering */
444
515
  textInputRef?: string;
445
516
  /** Actual text content (set after textInputRef is resolved) */
446
517
  text?: string;
447
- alignment?: 'left' | 'center' | 'right' | 'justify';
448
- verticalAlign?: 'top' | 'middle' | 'bottom';
449
- direction?: 'ltr' | 'rtl';
450
- padding?: number;
451
- fontType?: 'tiktok' | 'apple' | 'arial';
452
- fontSize?: number;
453
- fontWeight?: 'normal' | 'bold';
454
- lineHeight?: number;
455
- letterSpacing?: number;
456
- textWrap?: 'word' | 'char' | 'none';
457
- wordBreak?: 'normal' | 'break-all' | 'break-word';
458
- hyphenation?: 'none' | 'auto';
459
- maxLines?: number;
460
- textOverflow?: 'clip' | 'ellipsis';
461
- ellipsis?: string;
462
- color?: string;
463
- backgroundColor?: string;
464
- strokeColor?: string;
465
- strokeWidth?: number;
466
518
  }
467
519
  /**
468
520
  * Union of all video editor segment types
@@ -600,74 +652,15 @@ interface ImageSegment extends PictureSegment {
600
652
  }
601
653
  /**
602
654
  * Text segment - rich text overlays with full typography control
655
+ *
656
+ * Extends TextStyleProperties which contains all shared text styling options.
657
+ * This ensures feature parity between image editor and video editor text elements.
603
658
  */
604
- interface TextSegment extends VisualSegment {
659
+ interface TextSegment extends VisualSegment, TextStyleProperties {
605
660
  type: 'text';
606
661
  source: '';
607
662
  /** The text content (supports emojis) */
608
663
  text: string;
609
- /** Horizontal alignment (default: 'left') */
610
- alignment?: TextAlignment;
611
- /** Vertical alignment within bounds (default: 'top') */
612
- verticalAlign?: VerticalAlignment;
613
- /** Text direction (default: 'ltr') */
614
- direction?: TextDirection;
615
- /** Inner padding in pixels - uniform for all sides (default: 0). Overridden by individual padding values if set. */
616
- padding?: number;
617
- /** Top padding in pixels (overrides uniform padding) */
618
- paddingTop?: number;
619
- /** Right padding in pixels (overrides uniform padding) */
620
- paddingRight?: number;
621
- /** Bottom padding in pixels (overrides uniform padding) */
622
- paddingBottom?: number;
623
- /** Left padding in pixels (overrides uniform padding) */
624
- paddingLeft?: number;
625
- /** Extra top padding added when text has 2+ lines */
626
- multiLineExtraPaddingTop?: number;
627
- /** Extra right padding added when text has 2+ lines */
628
- multiLineExtraPaddingRight?: number;
629
- /** Extra bottom padding added when text has 2+ lines */
630
- multiLineExtraPaddingBottom?: number;
631
- /** Extra left padding added when text has 2+ lines */
632
- multiLineExtraPaddingLeft?: number;
633
- /** Font family (default: 'arial') */
634
- fontType?: FontType;
635
- /** Font size in pixels (default: 40) */
636
- fontSize?: number;
637
- /** Font weight (default: 'normal') */
638
- fontWeight?: FontWeight;
639
- /** Line height multiplier (default: 1.2) */
640
- lineHeight?: number;
641
- /** Letter spacing in pixels (default: 0) */
642
- letterSpacing?: number;
643
- /** How text wraps to new lines (default: 'word') */
644
- textWrap?: TextWrap;
645
- /** How words break across lines (default: 'normal') */
646
- wordBreak?: WordBreak;
647
- /** Automatic hyphenation (default: 'none') */
648
- hyphenation?: Hyphenation;
649
- /** Maximum lines (0 = unlimited) (default: 0) */
650
- maxLines?: number;
651
- /** How overflow is handled (default: 'clip') */
652
- textOverflow?: TextOverflow;
653
- /** Ellipsis string for overflow (default: '...') */
654
- ellipsis?: string;
655
- /** Text color (default: '#000000') */
656
- color?: string;
657
- /** Background color in hex format #RRGGBB (default: transparent) */
658
- backgroundColor?: string;
659
- /** Background opacity 0-100 (default: 100) */
660
- backgroundOpacity?: number;
661
- /** Border radius for background box - individual corners (default: 0) */
662
- backgroundBorderRadius?: BorderRadiusConfig;
663
- /** Text outline color (default: none) */
664
- strokeColor?: string;
665
- /** Outline width in pixels (default: 0) */
666
- strokeWidth?: number;
667
- /** When true, box shrinks to fit content (width becomes max width) */
668
- autoWidth?: boolean;
669
- /** Which side the box anchors to when autoWidth is true (default: 'left') */
670
- boxAlign?: 'left' | 'center' | 'right';
671
664
  }
672
665
  /**
673
666
  * Audio segment - background audio or music
@@ -1365,8 +1358,11 @@ declare function useResolvedPositions(elements: ImageEditorElement[], textValues
1365
1358
  *
1366
1359
  * This file registers all available compositions with the renderer.
1367
1360
  * It serves as the entry point for the renderer bundler.
1361
+ *
1362
+ * Uses calculateMetadata for ImageEditorComposition to determine
1363
+ * dynamic crop dimensions in the browser environment (with DOM access).
1368
1364
  */
1369
1365
 
1370
1366
  declare const RenderRoot: React.FC;
1371
1367
 
1372
- export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, debugFontStatus, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
1368
+ export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextStyleProperties, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, debugFontStatus, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
package/dist/index.js CHANGED
@@ -2126,6 +2126,55 @@ var defaultVideoProps = {
2126
2126
  };
2127
2127
  var ImageComp = ImageEditorComposition;
2128
2128
  var VideoComp = VideoEditorComposition;
2129
+ var calculateImageMetadata = async ({ props }) => {
2130
+ console.log("[calculateMetadata] Starting metadata calculation...");
2131
+ const canvasWidth = props.width ?? props.config?.width ?? 1080;
2132
+ const canvasHeight = props.height ?? props.config?.height ?? 1920;
2133
+ const defaultResult = {
2134
+ width: canvasWidth,
2135
+ height: canvasHeight,
2136
+ fps: 30,
2137
+ durationInFrames: 1
2138
+ };
2139
+ if (!props.elements || !props.dynamicCrop) {
2140
+ console.log("[calculateMetadata] No elements or dynamicCrop, using default dimensions:", canvasWidth, "x", canvasHeight);
2141
+ return defaultResult;
2142
+ }
2143
+ if (!isDynamicCropEnabled(props.dynamicCrop)) {
2144
+ console.log("[calculateMetadata] Dynamic crop not enabled, using default dimensions:", canvasWidth, "x", canvasHeight);
2145
+ return defaultResult;
2146
+ }
2147
+ console.log("[calculateMetadata] Dynamic crop enabled, loading fonts for accurate measurement...");
2148
+ try {
2149
+ await preloadFonts();
2150
+ console.log("[calculateMetadata] Fonts loaded successfully");
2151
+ } catch (err) {
2152
+ console.error("[calculateMetadata] Font loading failed:", err);
2153
+ }
2154
+ await new Promise((resolve) => setTimeout(resolve, 50));
2155
+ console.log("[calculateMetadata] Resolving element positions with DOM measurement...");
2156
+ const { elements: resolvedElements } = resolveElementPositions(
2157
+ props.elements,
2158
+ props.textValues ?? {}
2159
+ );
2160
+ console.log("[calculateMetadata] Element positions resolved");
2161
+ const cropBounds = calculateCropBounds(
2162
+ resolvedElements,
2163
+ props.dynamicCrop,
2164
+ canvasWidth,
2165
+ canvasHeight,
2166
+ props.textValues
2167
+ );
2168
+ const outputWidth = Math.round(cropBounds.width);
2169
+ const outputHeight = Math.round(cropBounds.height);
2170
+ console.log(`[calculateMetadata] Crop bounds calculated: ${canvasWidth}x${canvasHeight} -> ${outputWidth}x${outputHeight} (offset: ${cropBounds.x}, ${cropBounds.y})`);
2171
+ return {
2172
+ width: outputWidth,
2173
+ height: outputHeight,
2174
+ fps: 30,
2175
+ durationInFrames: 1
2176
+ };
2177
+ };
2129
2178
  var RenderRoot = () => {
2130
2179
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2131
2180
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
@@ -2133,8 +2182,9 @@ var RenderRoot = () => {
2133
2182
  {
2134
2183
  id: "ImageEditorComposition",
2135
2184
  component: ImageComp,
2185
+ calculateMetadata: calculateImageMetadata,
2136
2186
  durationInFrames: 1,
2137
- fps: 1,
2187
+ fps: 30,
2138
2188
  width: 1080,
2139
2189
  height: 1920,
2140
2190
  defaultProps: defaultImageProps
package/dist/index.mjs CHANGED
@@ -2040,6 +2040,55 @@ var defaultVideoProps = {
2040
2040
  };
2041
2041
  var ImageComp = ImageEditorComposition;
2042
2042
  var VideoComp = VideoEditorComposition;
2043
+ var calculateImageMetadata = async ({ props }) => {
2044
+ console.log("[calculateMetadata] Starting metadata calculation...");
2045
+ const canvasWidth = props.width ?? props.config?.width ?? 1080;
2046
+ const canvasHeight = props.height ?? props.config?.height ?? 1920;
2047
+ const defaultResult = {
2048
+ width: canvasWidth,
2049
+ height: canvasHeight,
2050
+ fps: 30,
2051
+ durationInFrames: 1
2052
+ };
2053
+ if (!props.elements || !props.dynamicCrop) {
2054
+ console.log("[calculateMetadata] No elements or dynamicCrop, using default dimensions:", canvasWidth, "x", canvasHeight);
2055
+ return defaultResult;
2056
+ }
2057
+ if (!isDynamicCropEnabled(props.dynamicCrop)) {
2058
+ console.log("[calculateMetadata] Dynamic crop not enabled, using default dimensions:", canvasWidth, "x", canvasHeight);
2059
+ return defaultResult;
2060
+ }
2061
+ console.log("[calculateMetadata] Dynamic crop enabled, loading fonts for accurate measurement...");
2062
+ try {
2063
+ await preloadFonts();
2064
+ console.log("[calculateMetadata] Fonts loaded successfully");
2065
+ } catch (err) {
2066
+ console.error("[calculateMetadata] Font loading failed:", err);
2067
+ }
2068
+ await new Promise((resolve) => setTimeout(resolve, 50));
2069
+ console.log("[calculateMetadata] Resolving element positions with DOM measurement...");
2070
+ const { elements: resolvedElements } = resolveElementPositions(
2071
+ props.elements,
2072
+ props.textValues ?? {}
2073
+ );
2074
+ console.log("[calculateMetadata] Element positions resolved");
2075
+ const cropBounds = calculateCropBounds(
2076
+ resolvedElements,
2077
+ props.dynamicCrop,
2078
+ canvasWidth,
2079
+ canvasHeight,
2080
+ props.textValues
2081
+ );
2082
+ const outputWidth = Math.round(cropBounds.width);
2083
+ const outputHeight = Math.round(cropBounds.height);
2084
+ console.log(`[calculateMetadata] Crop bounds calculated: ${canvasWidth}x${canvasHeight} -> ${outputWidth}x${outputHeight} (offset: ${cropBounds.x}, ${cropBounds.y})`);
2085
+ return {
2086
+ width: outputWidth,
2087
+ height: outputHeight,
2088
+ fps: 30,
2089
+ durationInFrames: 1
2090
+ };
2091
+ };
2043
2092
  var RenderRoot = () => {
2044
2093
  return /* @__PURE__ */ jsxs4(Fragment, { children: [
2045
2094
  /* @__PURE__ */ jsx6(
@@ -2047,8 +2096,9 @@ var RenderRoot = () => {
2047
2096
  {
2048
2097
  id: "ImageEditorComposition",
2049
2098
  component: ImageComp,
2099
+ calculateMetadata: calculateImageMetadata,
2050
2100
  durationInFrames: 1,
2051
- fps: 1,
2101
+ fps: 30,
2052
2102
  width: 1080,
2053
2103
  height: 1920,
2054
2104
  defaultProps: defaultImageProps
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc-render",
3
- "version": "1.5.25",
3
+ "version": "1.5.27",
4
4
  "description": "Unified rendering package for UGC Inc - shared types, components, and compositions for pixel-perfect client/server rendering",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",