ugcinc-render 1.5.22 → 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
@@ -1172,12 +1172,16 @@ declare function hexToRgba(hex: string, opacity?: number): string;
1172
1172
  */
1173
1173
 
1174
1174
  /**
1175
- * Calculate the actual width of a text element when autoWidth is enabled
1176
- * 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
1177
1179
  */
1178
1180
  declare function calculateAutoWidthDimensions(elem: ImageEditorElement, textContent: string, ctx?: CanvasRenderingContext2D | null): {
1179
1181
  actualWidth: number;
1180
1182
  actualX: number;
1183
+ actualHeight: number;
1184
+ lineCount: number;
1181
1185
  } | null;
1182
1186
  interface PositionResolutionError {
1183
1187
  elementId: string;
package/dist/index.d.ts CHANGED
@@ -1172,12 +1172,16 @@ declare function hexToRgba(hex: string, opacity?: number): string;
1172
1172
  */
1173
1173
 
1174
1174
  /**
1175
- * Calculate the actual width of a text element when autoWidth is enabled
1176
- * 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
1177
1179
  */
1178
1180
  declare function calculateAutoWidthDimensions(elem: ImageEditorElement, textContent: string, ctx?: CanvasRenderingContext2D | null): {
1179
1181
  actualWidth: number;
1180
1182
  actualX: number;
1183
+ actualHeight: number;
1184
+ lineCount: number;
1181
1185
  } | null;
1182
1186
  interface PositionResolutionError {
1183
1187
  elementId: string;
package/dist/index.js CHANGED
@@ -779,7 +779,7 @@ var FONT_FAMILIES2 = {
779
779
  arial: "Arial, sans-serif"
780
780
  };
781
781
  function calculateAutoWidthDimensions(elem, textContent, ctx) {
782
- if (elem.type !== "text" || !elem.autoWidth) {
782
+ if (elem.type !== "text") {
783
783
  return null;
784
784
  }
785
785
  let measureCtx = ctx;
@@ -796,9 +796,13 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
796
796
  const fontType = elem.font ?? "tiktok";
797
797
  const paddingLeft = elem.paddingLeft ?? 0;
798
798
  const paddingRight = elem.paddingRight ?? 0;
799
+ const paddingTop = elem.paddingTop ?? 0;
800
+ const paddingBottom = elem.paddingBottom ?? 0;
799
801
  const letterSpacing = elem.letterSpacing ?? 0;
802
+ const lineHeight = elem.lineHeight ?? 1.2;
800
803
  const maxWidth = elem.width;
801
804
  const boxAlign = elem.boxAlign ?? "left";
805
+ const autoWidth = elem.autoWidth ?? false;
802
806
  const fontFamily = FONT_FAMILIES2[fontType] ?? FONT_FAMILIES2.tiktok;
803
807
  measureCtx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
804
808
  const availableWidth = maxWidth - paddingLeft - paddingRight;
@@ -819,6 +823,7 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
819
823
  }
820
824
  }
821
825
  if (currentLine) lines.push(currentLine);
826
+ if (lines.length === 0) lines.push("");
822
827
  let widestLineWidth = 0;
823
828
  for (const line of lines) {
824
829
  const chars = [...line];
@@ -829,21 +834,27 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
829
834
  if (chars.length > 0) lineWidth -= letterSpacing;
830
835
  widestLineWidth = Math.max(widestLineWidth, lineWidth);
831
836
  }
832
- 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;
833
840
  let actualX;
834
- switch (boxAlign) {
835
- case "right":
836
- actualX = elem.x + maxWidth - actualWidth;
837
- break;
838
- case "center":
839
- actualX = elem.x + (maxWidth - actualWidth) / 2;
840
- break;
841
- case "left":
842
- default:
843
- actualX = elem.x;
844
- 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;
845
856
  }
846
- return { actualWidth, actualX };
857
+ return { actualWidth, actualX, actualHeight, lineCount: lines.length };
847
858
  }
848
859
  function detectCircularDependency(elements, startId, axis, visited = /* @__PURE__ */ new Set(), path = []) {
849
860
  if (visited.has(startId)) {
@@ -996,18 +1007,24 @@ function resolveElementPositions(elements, textValues) {
996
1007
  for (const elem of elements) {
997
1008
  resolvedX.set(elem.id, { x: elem.x, width: elem.width });
998
1009
  resolvedY.set(elem.id, { y: elem.y, height: elem.height });
999
- if (elem.type === "text" && elem.autoWidth) {
1010
+ if (elem.type === "text") {
1000
1011
  const textContent = getTextContent(elem);
1001
- const autoWidthResult = calculateAutoWidthDimensions(elem, textContent, measureCtx);
1002
- if (autoWidthResult) {
1003
- 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 });
1004
1020
  } else {
1005
1021
  referenceX.set(elem.id, { x: elem.x, width: elem.width });
1022
+ referenceY.set(elem.id, { y: elem.y, height: elem.height });
1006
1023
  }
1007
1024
  } else {
1008
1025
  referenceX.set(elem.id, { x: elem.x, width: elem.width });
1026
+ referenceY.set(elem.id, { y: elem.y, height: elem.height });
1009
1027
  }
1010
- referenceY.set(elem.id, { y: elem.y, height: elem.height });
1011
1028
  }
1012
1029
  for (const elem of sortedX) {
1013
1030
  if (elem.relativePositionX) {
@@ -1024,11 +1041,16 @@ function resolveElementPositions(elements, textValues) {
1024
1041
  elem.relativePositionX.offset
1025
1042
  );
1026
1043
  resolvedX.set(elem.id, { x: newX, width: elem.width });
1027
- if (elem.type === "text" && elem.autoWidth) {
1044
+ if (elem.type === "text") {
1028
1045
  const textContent = getTextContent(elem);
1029
- const autoWidthResult = calculateAutoWidthDimensions({ ...elem, x: newX }, textContent, measureCtx);
1030
- if (autoWidthResult) {
1031
- 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 });
1032
1054
  } else {
1033
1055
  referenceX.set(elem.id, { x: newX, width: elem.width });
1034
1056
  }
@@ -1053,7 +1075,17 @@ function resolveElementPositions(elements, textValues) {
1053
1075
  elem.relativePositionY.offset
1054
1076
  );
1055
1077
  resolvedY.set(elem.id, { y: newY, height: elem.height });
1056
- 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
+ }
1057
1089
  }
1058
1090
  }
1059
1091
  }
package/dist/index.mjs CHANGED
@@ -693,7 +693,7 @@ var FONT_FAMILIES2 = {
693
693
  arial: "Arial, sans-serif"
694
694
  };
695
695
  function calculateAutoWidthDimensions(elem, textContent, ctx) {
696
- if (elem.type !== "text" || !elem.autoWidth) {
696
+ if (elem.type !== "text") {
697
697
  return null;
698
698
  }
699
699
  let measureCtx = ctx;
@@ -710,9 +710,13 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
710
710
  const fontType = elem.font ?? "tiktok";
711
711
  const paddingLeft = elem.paddingLeft ?? 0;
712
712
  const paddingRight = elem.paddingRight ?? 0;
713
+ const paddingTop = elem.paddingTop ?? 0;
714
+ const paddingBottom = elem.paddingBottom ?? 0;
713
715
  const letterSpacing = elem.letterSpacing ?? 0;
716
+ const lineHeight = elem.lineHeight ?? 1.2;
714
717
  const maxWidth = elem.width;
715
718
  const boxAlign = elem.boxAlign ?? "left";
719
+ const autoWidth = elem.autoWidth ?? false;
716
720
  const fontFamily = FONT_FAMILIES2[fontType] ?? FONT_FAMILIES2.tiktok;
717
721
  measureCtx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
718
722
  const availableWidth = maxWidth - paddingLeft - paddingRight;
@@ -733,6 +737,7 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
733
737
  }
734
738
  }
735
739
  if (currentLine) lines.push(currentLine);
740
+ if (lines.length === 0) lines.push("");
736
741
  let widestLineWidth = 0;
737
742
  for (const line of lines) {
738
743
  const chars = [...line];
@@ -743,21 +748,27 @@ function calculateAutoWidthDimensions(elem, textContent, ctx) {
743
748
  if (chars.length > 0) lineWidth -= letterSpacing;
744
749
  widestLineWidth = Math.max(widestLineWidth, lineWidth);
745
750
  }
746
- 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;
747
754
  let actualX;
748
- switch (boxAlign) {
749
- case "right":
750
- actualX = elem.x + maxWidth - actualWidth;
751
- break;
752
- case "center":
753
- actualX = elem.x + (maxWidth - actualWidth) / 2;
754
- break;
755
- case "left":
756
- default:
757
- actualX = elem.x;
758
- 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;
759
770
  }
760
- return { actualWidth, actualX };
771
+ return { actualWidth, actualX, actualHeight, lineCount: lines.length };
761
772
  }
762
773
  function detectCircularDependency(elements, startId, axis, visited = /* @__PURE__ */ new Set(), path = []) {
763
774
  if (visited.has(startId)) {
@@ -910,18 +921,24 @@ function resolveElementPositions(elements, textValues) {
910
921
  for (const elem of elements) {
911
922
  resolvedX.set(elem.id, { x: elem.x, width: elem.width });
912
923
  resolvedY.set(elem.id, { y: elem.y, height: elem.height });
913
- if (elem.type === "text" && elem.autoWidth) {
924
+ if (elem.type === "text") {
914
925
  const textContent = getTextContent(elem);
915
- const autoWidthResult = calculateAutoWidthDimensions(elem, textContent, measureCtx);
916
- if (autoWidthResult) {
917
- 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 });
918
934
  } else {
919
935
  referenceX.set(elem.id, { x: elem.x, width: elem.width });
936
+ referenceY.set(elem.id, { y: elem.y, height: elem.height });
920
937
  }
921
938
  } else {
922
939
  referenceX.set(elem.id, { x: elem.x, width: elem.width });
940
+ referenceY.set(elem.id, { y: elem.y, height: elem.height });
923
941
  }
924
- referenceY.set(elem.id, { y: elem.y, height: elem.height });
925
942
  }
926
943
  for (const elem of sortedX) {
927
944
  if (elem.relativePositionX) {
@@ -938,11 +955,16 @@ function resolveElementPositions(elements, textValues) {
938
955
  elem.relativePositionX.offset
939
956
  );
940
957
  resolvedX.set(elem.id, { x: newX, width: elem.width });
941
- if (elem.type === "text" && elem.autoWidth) {
958
+ if (elem.type === "text") {
942
959
  const textContent = getTextContent(elem);
943
- const autoWidthResult = calculateAutoWidthDimensions({ ...elem, x: newX }, textContent, measureCtx);
944
- if (autoWidthResult) {
945
- 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 });
946
968
  } else {
947
969
  referenceX.set(elem.id, { x: newX, width: elem.width });
948
970
  }
@@ -967,7 +989,17 @@ function resolveElementPositions(elements, textValues) {
967
989
  elem.relativePositionY.offset
968
990
  );
969
991
  resolvedY.set(elem.id, { y: newY, height: elem.height });
970
- 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
+ }
971
1003
  }
972
1004
  }
973
1005
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc-render",
3
- "version": "1.5.22",
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",