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 +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +74 -30
- package/dist/index.mjs +81 -37
- package/package.json +1 -1
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
|
|
1173
|
-
* Returns { actualWidth, actualX } where
|
|
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
|
|
1173
|
-
* Returns { actualWidth, actualX } where
|
|
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
|
-
|
|
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
|
-
|
|
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"
|
|
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
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
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"
|
|
1010
|
+
if (elem.type === "text") {
|
|
989
1011
|
const textContent = getTextContent(elem);
|
|
990
|
-
const
|
|
991
|
-
if (
|
|
992
|
-
|
|
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"
|
|
1044
|
+
if (elem.type === "text") {
|
|
1017
1045
|
const textContent = getTextContent(elem);
|
|
1018
|
-
const
|
|
1019
|
-
if (
|
|
1020
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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"
|
|
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
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
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"
|
|
924
|
+
if (elem.type === "text") {
|
|
903
925
|
const textContent = getTextContent(elem);
|
|
904
|
-
const
|
|
905
|
-
if (
|
|
906
|
-
|
|
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"
|
|
958
|
+
if (elem.type === "text") {
|
|
931
959
|
const textContent = getTextContent(elem);
|
|
932
|
-
const
|
|
933
|
-
if (
|
|
934
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
1462
|
-
const { fps } =
|
|
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 =
|
|
1583
|
-
const { fps, durationInFrames } =
|
|
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.
|
|
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",
|