ugcinc-render 1.5.21 → 1.5.23

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
@@ -916,6 +916,8 @@ interface ImageElementProps {
916
916
  segment: ImageSegment;
917
917
  /** The source URL of the image */
918
918
  src: string;
919
+ /** Start frame of this segment in the composition (needed for fade-in) */
920
+ startFrame?: number;
919
921
  /** Optional scale for high-DPI rendering */
920
922
  scale?: number;
921
923
  }
@@ -925,8 +927,9 @@ interface ImageElementProps {
925
927
  * - Opacity
926
928
  * - Rotation
927
929
  * - Border radius (uniform or per-corner)
930
+ * - Fade-in effect
928
931
  */
929
- declare function ImageElement({ segment, src, scale }: ImageElementProps): react_jsx_runtime.JSX.Element;
932
+ declare function ImageElement({ segment, src, startFrame, scale }: ImageElementProps): react_jsx_runtime.JSX.Element;
930
933
 
931
934
  interface VideoElementProps {
932
935
  segment: VideoSegment;
@@ -1169,12 +1172,16 @@ declare function hexToRgba(hex: string, opacity?: number): string;
1169
1172
  */
1170
1173
 
1171
1174
  /**
1172
- * Calculate the actual width of a text element when autoWidth is enabled
1173
- * Returns { actualWidth, actualX } where actualX is adjusted based on boxAlign
1175
+ * Calculate the actual dimensions of a text element when autoWidth is enabled
1176
+ * Returns { actualWidth, actualX, actualHeight } where:
1177
+ * - actualX is adjusted based on boxAlign
1178
+ * - actualHeight is calculated based on the number of wrapped lines
1174
1179
  */
1175
1180
  declare function calculateAutoWidthDimensions(elem: ImageEditorElement, textContent: string, ctx?: CanvasRenderingContext2D | null): {
1176
1181
  actualWidth: number;
1177
1182
  actualX: number;
1183
+ actualHeight: number;
1184
+ lineCount: number;
1178
1185
  } | null;
1179
1186
  interface PositionResolutionError {
1180
1187
  elementId: string;
package/dist/index.d.ts CHANGED
@@ -916,6 +916,8 @@ interface ImageElementProps {
916
916
  segment: ImageSegment;
917
917
  /** The source URL of the image */
918
918
  src: string;
919
+ /** Start frame of this segment in the composition (needed for fade-in) */
920
+ startFrame?: number;
919
921
  /** Optional scale for high-DPI rendering */
920
922
  scale?: number;
921
923
  }
@@ -925,8 +927,9 @@ interface ImageElementProps {
925
927
  * - Opacity
926
928
  * - Rotation
927
929
  * - Border radius (uniform or per-corner)
930
+ * - Fade-in effect
928
931
  */
929
- declare function ImageElement({ segment, src, scale }: ImageElementProps): react_jsx_runtime.JSX.Element;
932
+ declare function ImageElement({ segment, src, startFrame, scale }: ImageElementProps): react_jsx_runtime.JSX.Element;
930
933
 
931
934
  interface VideoElementProps {
932
935
  segment: VideoSegment;
@@ -1169,12 +1172,16 @@ declare function hexToRgba(hex: string, opacity?: number): string;
1169
1172
  */
1170
1173
 
1171
1174
  /**
1172
- * Calculate the actual width of a text element when autoWidth is enabled
1173
- * Returns { actualWidth, actualX } where actualX is adjusted based on boxAlign
1175
+ * Calculate the actual dimensions of a text element when autoWidth is enabled
1176
+ * Returns { actualWidth, actualX, actualHeight } where:
1177
+ * - actualX is adjusted based on boxAlign
1178
+ * - actualHeight is calculated based on the number of wrapped lines
1174
1179
  */
1175
1180
  declare function calculateAutoWidthDimensions(elem: ImageEditorElement, textContent: string, ctx?: CanvasRenderingContext2D | null): {
1176
1181
  actualWidth: number;
1177
1182
  actualX: number;
1183
+ actualHeight: number;
1184
+ lineCount: number;
1178
1185
  } | null;
1179
1186
  interface PositionResolutionError {
1180
1187
  elementId: string;
package/dist/index.js CHANGED
@@ -717,15 +717,26 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
717
717
  function fitModeToCss(fit) {
718
718
  return fit;
719
719
  }
720
- function ImageElement({ segment, src, scale = 1 }) {
720
+ function ImageElement({ segment, src, startFrame = 0, scale = 1 }) {
721
+ const frame = (0, import_remotion.useCurrentFrame)();
722
+ const { fps } = (0, import_remotion.useVideoConfig)();
721
723
  const fit = segment.fit ?? IMAGE_DEFAULTS.fit;
722
724
  const opacity = (segment.opacity ?? VISUAL_DEFAULTS.opacity) / 100;
723
725
  const rotation = segment.rotation ?? 0;
724
726
  const borderRadius = segment.borderRadius;
727
+ const fadeIn = segment.fadeIn ?? 0;
725
728
  const x = segment.xOffset * scale;
726
729
  const y = segment.yOffset * scale;
727
730
  const width = segment.width * scale;
728
731
  const height = segment.height * scale;
732
+ const fadeOpacity = (0, import_react2.useMemo)(() => {
733
+ if (fadeIn <= 0) return 1;
734
+ const framesFromStart = frame - startFrame;
735
+ const fadeInFrames = fadeIn / 1e3 * fps;
736
+ if (framesFromStart >= fadeInFrames) return 1;
737
+ if (framesFromStart <= 0) return 0;
738
+ return framesFromStart / fadeInFrames;
739
+ }, [frame, startFrame, fadeIn, fps]);
729
740
  const borderRadiusStyle = (0, import_react2.useMemo)(() => {
730
741
  if (!borderRadius) return void 0;
731
742
  if (typeof borderRadius === "number") {
@@ -744,14 +755,14 @@ function ImageElement({ segment, src, scale = 1 }) {
744
755
  transform: rotation !== 0 ? `rotate(${rotation}deg)` : void 0,
745
756
  transformOrigin: "center center",
746
757
  overflow: "hidden",
747
- borderRadius: borderRadiusStyle
748
- }), [x, y, width, height, rotation, borderRadiusStyle]);
758
+ borderRadius: borderRadiusStyle,
759
+ opacity: opacity * fadeOpacity
760
+ }), [x, y, width, height, rotation, borderRadiusStyle, opacity, fadeOpacity]);
749
761
  const imageStyle = (0, import_react2.useMemo)(() => ({
750
762
  width: "100%",
751
763
  height: "100%",
752
- objectFit: fitModeToCss(fit),
753
- opacity
754
- }), [fit, opacity]);
764
+ objectFit: fitModeToCss(fit)
765
+ }), [fit]);
755
766
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: containerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
756
767
  import_remotion.Img,
757
768
  {
@@ -768,7 +779,7 @@ var FONT_FAMILIES2 = {
768
779
  arial: "Arial, sans-serif"
769
780
  };
770
781
  function calculateAutoWidthDimensions(elem, textContent, ctx) {
771
- if (elem.type !== "text" || !elem.autoWidth) {
782
+ if (elem.type !== "text") {
772
783
  return null;
773
784
  }
774
785
  let measureCtx = ctx;
@@ -785,9 +796,13 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
785
796
  const fontType = elem.font ?? "tiktok";
786
797
  const paddingLeft = elem.paddingLeft ?? 0;
787
798
  const paddingRight = elem.paddingRight ?? 0;
799
+ const paddingTop = elem.paddingTop ?? 0;
800
+ const paddingBottom = elem.paddingBottom ?? 0;
788
801
  const letterSpacing = elem.letterSpacing ?? 0;
802
+ const lineHeight = elem.lineHeight ?? 1.2;
789
803
  const maxWidth = elem.width;
790
804
  const boxAlign = elem.boxAlign ?? "left";
805
+ const autoWidth = elem.autoWidth ?? false;
791
806
  const fontFamily = FONT_FAMILIES2[fontType] ?? FONT_FAMILIES2.tiktok;
792
807
  measureCtx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
793
808
  const availableWidth = maxWidth - paddingLeft - paddingRight;
@@ -808,6 +823,7 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
808
823
  }
809
824
  }
810
825
  if (currentLine) lines.push(currentLine);
826
+ if (lines.length === 0) lines.push("");
811
827
  let widestLineWidth = 0;
812
828
  for (const line of lines) {
813
829
  const chars = [...line];
@@ -818,21 +834,27 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
818
834
  if (chars.length > 0) lineWidth -= letterSpacing;
819
835
  widestLineWidth = Math.max(widestLineWidth, lineWidth);
820
836
  }
821
- const actualWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
837
+ const actualWidth = autoWidth ? Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth) : maxWidth;
838
+ const textHeight = lines.length * fontSize * lineHeight;
839
+ const actualHeight = textHeight + paddingTop + paddingBottom;
822
840
  let actualX;
823
- switch (boxAlign) {
824
- case "right":
825
- actualX = elem.x + maxWidth - actualWidth;
826
- break;
827
- case "center":
828
- actualX = elem.x + (maxWidth - actualWidth) / 2;
829
- break;
830
- case "left":
831
- default:
832
- actualX = elem.x;
833
- break;
841
+ if (autoWidth) {
842
+ switch (boxAlign) {
843
+ case "right":
844
+ actualX = elem.x + maxWidth - actualWidth;
845
+ break;
846
+ case "center":
847
+ actualX = elem.x + (maxWidth - actualWidth) / 2;
848
+ break;
849
+ case "left":
850
+ default:
851
+ actualX = elem.x;
852
+ break;
853
+ }
854
+ } else {
855
+ actualX = elem.x;
834
856
  }
835
- return { actualWidth, actualX };
857
+ return { actualWidth, actualX, actualHeight, lineCount: lines.length };
836
858
  }
837
859
  function detectCircularDependency(elements, startId, axis, visited = /* @__PURE__ */ new Set(), path = []) {
838
860
  if (visited.has(startId)) {
@@ -985,18 +1007,24 @@ function resolveElementPositions(elements, textValues) {
985
1007
  for (const elem of elements) {
986
1008
  resolvedX.set(elem.id, { x: elem.x, width: elem.width });
987
1009
  resolvedY.set(elem.id, { y: elem.y, height: elem.height });
988
- if (elem.type === "text" && elem.autoWidth) {
1010
+ if (elem.type === "text") {
989
1011
  const textContent = getTextContent(elem);
990
- const autoWidthResult = calculateAutoWidthDimensions(elem, textContent, measureCtx);
991
- if (autoWidthResult) {
992
- referenceX.set(elem.id, { x: autoWidthResult.actualX, width: autoWidthResult.actualWidth });
1012
+ const autoResult = calculateAutoWidthDimensions(elem, textContent, measureCtx);
1013
+ if (autoResult) {
1014
+ if (elem.autoWidth) {
1015
+ referenceX.set(elem.id, { x: autoResult.actualX, width: autoResult.actualWidth });
1016
+ } else {
1017
+ referenceX.set(elem.id, { x: elem.x, width: elem.width });
1018
+ }
1019
+ referenceY.set(elem.id, { y: elem.y, height: autoResult.actualHeight });
993
1020
  } else {
994
1021
  referenceX.set(elem.id, { x: elem.x, width: elem.width });
1022
+ referenceY.set(elem.id, { y: elem.y, height: elem.height });
995
1023
  }
996
1024
  } else {
997
1025
  referenceX.set(elem.id, { x: elem.x, width: elem.width });
1026
+ referenceY.set(elem.id, { y: elem.y, height: elem.height });
998
1027
  }
999
- referenceY.set(elem.id, { y: elem.y, height: elem.height });
1000
1028
  }
1001
1029
  for (const elem of sortedX) {
1002
1030
  if (elem.relativePositionX) {
@@ -1013,11 +1041,16 @@ function resolveElementPositions(elements, textValues) {
1013
1041
  elem.relativePositionX.offset
1014
1042
  );
1015
1043
  resolvedX.set(elem.id, { x: newX, width: elem.width });
1016
- if (elem.type === "text" && elem.autoWidth) {
1044
+ if (elem.type === "text") {
1017
1045
  const textContent = getTextContent(elem);
1018
- const autoWidthResult = calculateAutoWidthDimensions({ ...elem, x: newX }, textContent, measureCtx);
1019
- if (autoWidthResult) {
1020
- referenceX.set(elem.id, { x: autoWidthResult.actualX, width: autoWidthResult.actualWidth });
1046
+ const autoResult = calculateAutoWidthDimensions({ ...elem, x: newX }, textContent, measureCtx);
1047
+ if (autoResult) {
1048
+ if (elem.autoWidth) {
1049
+ referenceX.set(elem.id, { x: autoResult.actualX, width: autoResult.actualWidth });
1050
+ } else {
1051
+ referenceX.set(elem.id, { x: newX, width: elem.width });
1052
+ }
1053
+ referenceY.set(elem.id, { y: referenceY.get(elem.id)?.y ?? elem.y, height: autoResult.actualHeight });
1021
1054
  } else {
1022
1055
  referenceX.set(elem.id, { x: newX, width: elem.width });
1023
1056
  }
@@ -1042,7 +1075,17 @@ function resolveElementPositions(elements, textValues) {
1042
1075
  elem.relativePositionY.offset
1043
1076
  );
1044
1077
  resolvedY.set(elem.id, { y: newY, height: elem.height });
1045
- referenceY.set(elem.id, { y: newY, height: elem.height });
1078
+ if (elem.type === "text") {
1079
+ const textContent = getTextContent(elem);
1080
+ const autoResult = calculateAutoWidthDimensions({ ...elem, y: newY }, textContent, measureCtx);
1081
+ if (autoResult) {
1082
+ referenceY.set(elem.id, { y: newY, height: autoResult.actualHeight });
1083
+ } else {
1084
+ referenceY.set(elem.id, { y: newY, height: elem.height });
1085
+ }
1086
+ } else {
1087
+ referenceY.set(elem.id, { y: newY, height: elem.height });
1088
+ }
1046
1089
  }
1047
1090
  }
1048
1091
  }
@@ -1734,6 +1777,7 @@ function VideoEditorComposition({
1734
1777
  {
1735
1778
  segment,
1736
1779
  src,
1780
+ startFrame,
1737
1781
  scale: 1
1738
1782
  },
1739
1783
  segment.id
package/dist/index.mjs CHANGED
@@ -626,20 +626,31 @@ function TextElement({ segment, scale = 1 }) {
626
626
 
627
627
  // src/components/ImageElement.tsx
628
628
  import { useMemo as useMemo2 } from "react";
629
- import { Img } from "remotion";
629
+ import { Img, useCurrentFrame, useVideoConfig } from "remotion";
630
630
  import { jsx as jsx2 } from "react/jsx-runtime";
631
631
  function fitModeToCss(fit) {
632
632
  return fit;
633
633
  }
634
- function ImageElement({ segment, src, scale = 1 }) {
634
+ function ImageElement({ segment, src, startFrame = 0, scale = 1 }) {
635
+ const frame = useCurrentFrame();
636
+ const { fps } = useVideoConfig();
635
637
  const fit = segment.fit ?? IMAGE_DEFAULTS.fit;
636
638
  const opacity = (segment.opacity ?? VISUAL_DEFAULTS.opacity) / 100;
637
639
  const rotation = segment.rotation ?? 0;
638
640
  const borderRadius = segment.borderRadius;
641
+ const fadeIn = segment.fadeIn ?? 0;
639
642
  const x = segment.xOffset * scale;
640
643
  const y = segment.yOffset * scale;
641
644
  const width = segment.width * scale;
642
645
  const height = segment.height * scale;
646
+ const fadeOpacity = useMemo2(() => {
647
+ if (fadeIn <= 0) return 1;
648
+ const framesFromStart = frame - startFrame;
649
+ const fadeInFrames = fadeIn / 1e3 * fps;
650
+ if (framesFromStart >= fadeInFrames) return 1;
651
+ if (framesFromStart <= 0) return 0;
652
+ return framesFromStart / fadeInFrames;
653
+ }, [frame, startFrame, fadeIn, fps]);
643
654
  const borderRadiusStyle = useMemo2(() => {
644
655
  if (!borderRadius) return void 0;
645
656
  if (typeof borderRadius === "number") {
@@ -658,14 +669,14 @@ function ImageElement({ segment, src, scale = 1 }) {
658
669
  transform: rotation !== 0 ? `rotate(${rotation}deg)` : void 0,
659
670
  transformOrigin: "center center",
660
671
  overflow: "hidden",
661
- borderRadius: borderRadiusStyle
662
- }), [x, y, width, height, rotation, borderRadiusStyle]);
672
+ borderRadius: borderRadiusStyle,
673
+ opacity: opacity * fadeOpacity
674
+ }), [x, y, width, height, rotation, borderRadiusStyle, opacity, fadeOpacity]);
663
675
  const imageStyle = useMemo2(() => ({
664
676
  width: "100%",
665
677
  height: "100%",
666
- objectFit: fitModeToCss(fit),
667
- opacity
668
- }), [fit, opacity]);
678
+ objectFit: fitModeToCss(fit)
679
+ }), [fit]);
669
680
  return /* @__PURE__ */ jsx2("div", { style: containerStyle, children: /* @__PURE__ */ jsx2(
670
681
  Img,
671
682
  {
@@ -682,7 +693,7 @@ var FONT_FAMILIES2 = {
682
693
  arial: "Arial, sans-serif"
683
694
  };
684
695
  function calculateAutoWidthDimensions(elem, textContent, ctx) {
685
- if (elem.type !== "text" || !elem.autoWidth) {
696
+ if (elem.type !== "text") {
686
697
  return null;
687
698
  }
688
699
  let measureCtx = ctx;
@@ -699,9 +710,13 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
699
710
  const fontType = elem.font ?? "tiktok";
700
711
  const paddingLeft = elem.paddingLeft ?? 0;
701
712
  const paddingRight = elem.paddingRight ?? 0;
713
+ const paddingTop = elem.paddingTop ?? 0;
714
+ const paddingBottom = elem.paddingBottom ?? 0;
702
715
  const letterSpacing = elem.letterSpacing ?? 0;
716
+ const lineHeight = elem.lineHeight ?? 1.2;
703
717
  const maxWidth = elem.width;
704
718
  const boxAlign = elem.boxAlign ?? "left";
719
+ const autoWidth = elem.autoWidth ?? false;
705
720
  const fontFamily = FONT_FAMILIES2[fontType] ?? FONT_FAMILIES2.tiktok;
706
721
  measureCtx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
707
722
  const availableWidth = maxWidth - paddingLeft - paddingRight;
@@ -722,6 +737,7 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
722
737
  }
723
738
  }
724
739
  if (currentLine) lines.push(currentLine);
740
+ if (lines.length === 0) lines.push("");
725
741
  let widestLineWidth = 0;
726
742
  for (const line of lines) {
727
743
  const chars = [...line];
@@ -732,21 +748,27 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
732
748
  if (chars.length > 0) lineWidth -= letterSpacing;
733
749
  widestLineWidth = Math.max(widestLineWidth, lineWidth);
734
750
  }
735
- const actualWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
751
+ const actualWidth = autoWidth ? Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth) : maxWidth;
752
+ const textHeight = lines.length * fontSize * lineHeight;
753
+ const actualHeight = textHeight + paddingTop + paddingBottom;
736
754
  let actualX;
737
- switch (boxAlign) {
738
- case "right":
739
- actualX = elem.x + maxWidth - actualWidth;
740
- break;
741
- case "center":
742
- actualX = elem.x + (maxWidth - actualWidth) / 2;
743
- break;
744
- case "left":
745
- default:
746
- actualX = elem.x;
747
- break;
755
+ if (autoWidth) {
756
+ switch (boxAlign) {
757
+ case "right":
758
+ actualX = elem.x + maxWidth - actualWidth;
759
+ break;
760
+ case "center":
761
+ actualX = elem.x + (maxWidth - actualWidth) / 2;
762
+ break;
763
+ case "left":
764
+ default:
765
+ actualX = elem.x;
766
+ break;
767
+ }
768
+ } else {
769
+ actualX = elem.x;
748
770
  }
749
- return { actualWidth, actualX };
771
+ return { actualWidth, actualX, actualHeight, lineCount: lines.length };
750
772
  }
751
773
  function detectCircularDependency(elements, startId, axis, visited = /* @__PURE__ */ new Set(), path = []) {
752
774
  if (visited.has(startId)) {
@@ -899,18 +921,24 @@ function resolveElementPositions(elements, textValues) {
899
921
  for (const elem of elements) {
900
922
  resolvedX.set(elem.id, { x: elem.x, width: elem.width });
901
923
  resolvedY.set(elem.id, { y: elem.y, height: elem.height });
902
- if (elem.type === "text" && elem.autoWidth) {
924
+ if (elem.type === "text") {
903
925
  const textContent = getTextContent(elem);
904
- const autoWidthResult = calculateAutoWidthDimensions(elem, textContent, measureCtx);
905
- if (autoWidthResult) {
906
- referenceX.set(elem.id, { x: autoWidthResult.actualX, width: autoWidthResult.actualWidth });
926
+ const autoResult = calculateAutoWidthDimensions(elem, textContent, measureCtx);
927
+ if (autoResult) {
928
+ if (elem.autoWidth) {
929
+ referenceX.set(elem.id, { x: autoResult.actualX, width: autoResult.actualWidth });
930
+ } else {
931
+ referenceX.set(elem.id, { x: elem.x, width: elem.width });
932
+ }
933
+ referenceY.set(elem.id, { y: elem.y, height: autoResult.actualHeight });
907
934
  } else {
908
935
  referenceX.set(elem.id, { x: elem.x, width: elem.width });
936
+ referenceY.set(elem.id, { y: elem.y, height: elem.height });
909
937
  }
910
938
  } else {
911
939
  referenceX.set(elem.id, { x: elem.x, width: elem.width });
940
+ referenceY.set(elem.id, { y: elem.y, height: elem.height });
912
941
  }
913
- referenceY.set(elem.id, { y: elem.y, height: elem.height });
914
942
  }
915
943
  for (const elem of sortedX) {
916
944
  if (elem.relativePositionX) {
@@ -927,11 +955,16 @@ function resolveElementPositions(elements, textValues) {
927
955
  elem.relativePositionX.offset
928
956
  );
929
957
  resolvedX.set(elem.id, { x: newX, width: elem.width });
930
- if (elem.type === "text" && elem.autoWidth) {
958
+ if (elem.type === "text") {
931
959
  const textContent = getTextContent(elem);
932
- const autoWidthResult = calculateAutoWidthDimensions({ ...elem, x: newX }, textContent, measureCtx);
933
- if (autoWidthResult) {
934
- referenceX.set(elem.id, { x: autoWidthResult.actualX, width: autoWidthResult.actualWidth });
960
+ const autoResult = calculateAutoWidthDimensions({ ...elem, x: newX }, textContent, measureCtx);
961
+ if (autoResult) {
962
+ if (elem.autoWidth) {
963
+ referenceX.set(elem.id, { x: autoResult.actualX, width: autoResult.actualWidth });
964
+ } else {
965
+ referenceX.set(elem.id, { x: newX, width: elem.width });
966
+ }
967
+ referenceY.set(elem.id, { y: referenceY.get(elem.id)?.y ?? elem.y, height: autoResult.actualHeight });
935
968
  } else {
936
969
  referenceX.set(elem.id, { x: newX, width: elem.width });
937
970
  }
@@ -956,7 +989,17 @@ function resolveElementPositions(elements, textValues) {
956
989
  elem.relativePositionY.offset
957
990
  );
958
991
  resolvedY.set(elem.id, { y: newY, height: elem.height });
959
- referenceY.set(elem.id, { y: newY, height: elem.height });
992
+ if (elem.type === "text") {
993
+ const textContent = getTextContent(elem);
994
+ const autoResult = calculateAutoWidthDimensions({ ...elem, y: newY }, textContent, measureCtx);
995
+ if (autoResult) {
996
+ referenceY.set(elem.id, { y: newY, height: autoResult.actualHeight });
997
+ } else {
998
+ referenceY.set(elem.id, { y: newY, height: elem.height });
999
+ }
1000
+ } else {
1001
+ referenceY.set(elem.id, { y: newY, height: elem.height });
1002
+ }
960
1003
  }
961
1004
  }
962
1005
  }
@@ -1442,11 +1485,11 @@ function BackgroundImage({
1442
1485
 
1443
1486
  // src/compositions/VideoEditorComposition.tsx
1444
1487
  import { useMemo as useMemo5 } from "react";
1445
- import { AbsoluteFill as AbsoluteFill2, useCurrentFrame as useCurrentFrame2, useVideoConfig as useVideoConfig2, Sequence, Audio } from "remotion";
1488
+ import { AbsoluteFill as AbsoluteFill2, useCurrentFrame as useCurrentFrame3, useVideoConfig as useVideoConfig3, Sequence, Audio } from "remotion";
1446
1489
 
1447
1490
  // src/components/VideoElement.tsx
1448
1491
  import { useMemo as useMemo4 } from "react";
1449
- import { Video, useCurrentFrame, useVideoConfig } from "remotion";
1492
+ import { Video, useCurrentFrame as useCurrentFrame2, useVideoConfig as useVideoConfig2 } from "remotion";
1450
1493
  import { jsx as jsx4 } from "react/jsx-runtime";
1451
1494
  function fitModeToCss2(fit) {
1452
1495
  return fit;
@@ -1458,8 +1501,8 @@ function VideoElement({
1458
1501
  durationInFrames,
1459
1502
  scale = 1
1460
1503
  }) {
1461
- const frame = useCurrentFrame();
1462
- const { fps } = useVideoConfig();
1504
+ const frame = useCurrentFrame2();
1505
+ const { fps } = useVideoConfig2();
1463
1506
  const fit = segment.fit ?? VIDEO_DEFAULTS.fit;
1464
1507
  const speed = segment.speed ?? VIDEO_DEFAULTS.speed;
1465
1508
  const volume = (segment.volume ?? VIDEO_DEFAULTS.volume) / 100;
@@ -1579,8 +1622,8 @@ function VideoEditorComposition({
1579
1622
  sources = {},
1580
1623
  textContent = {}
1581
1624
  }) {
1582
- const frame = useCurrentFrame2();
1583
- const { fps, durationInFrames } = useVideoConfig2();
1625
+ const frame = useCurrentFrame3();
1626
+ const { fps, durationInFrames } = useVideoConfig3();
1584
1627
  const segmentTimings = useMemo5(
1585
1628
  () => calculateSegmentTimings(config, fps),
1586
1629
  [config, fps]
@@ -1648,6 +1691,7 @@ function VideoEditorComposition({
1648
1691
  {
1649
1692
  segment,
1650
1693
  src,
1694
+ startFrame,
1651
1695
  scale: 1
1652
1696
  },
1653
1697
  segment.id
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc-render",
3
- "version": "1.5.21",
3
+ "version": "1.5.23",
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",