ugcinc-render 1.5.18 → 1.5.20
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.js +79 -189
- package/dist/index.mjs +89 -199
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -401,48 +401,15 @@ function calculateAutoWidthAndLines({
|
|
|
401
401
|
letterSpacing,
|
|
402
402
|
lineHeight
|
|
403
403
|
}) {
|
|
404
|
-
console.log("[TextElement/calculateAutoWidthAndLines] ===== START CALCULATION =====");
|
|
405
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Input params:", {
|
|
406
|
-
text: text.substring(0, 100) + (text.length > 100 ? "..." : ""),
|
|
407
|
-
textLength: text.length,
|
|
408
|
-
maxWidth,
|
|
409
|
-
paddingLeft,
|
|
410
|
-
paddingRight,
|
|
411
|
-
fontSize,
|
|
412
|
-
fontWeight,
|
|
413
|
-
fontFamily,
|
|
414
|
-
letterSpacing,
|
|
415
|
-
lineHeight
|
|
416
|
-
});
|
|
417
404
|
if (typeof document === "undefined") {
|
|
418
|
-
console.log("[TextElement/calculateAutoWidthAndLines] SSR mode - returning maxWidth");
|
|
419
405
|
return { width: maxWidth, lines: [text] };
|
|
420
406
|
}
|
|
421
|
-
if (typeof document.fonts !== "undefined") {
|
|
422
|
-
const fontChecks = {
|
|
423
|
-
"SF Pro normal": document.fonts.check(`normal ${fontSize}px "SF Pro"`),
|
|
424
|
-
"SF Pro bold": document.fonts.check(`bold ${fontSize}px "SF Pro"`),
|
|
425
|
-
"TikTok Sans normal": document.fonts.check(`normal ${fontSize}px "TikTok Sans"`),
|
|
426
|
-
"TikTok Sans bold": document.fonts.check(`bold ${fontSize}px "TikTok Sans"`),
|
|
427
|
-
"requestedFont": document.fonts.check(`${fontWeight} ${fontSize}px ${fontFamily.split(",")[0]}`)
|
|
428
|
-
};
|
|
429
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Font loading status:", fontChecks);
|
|
430
|
-
const loadedFonts = [];
|
|
431
|
-
document.fonts.forEach((font) => {
|
|
432
|
-
loadedFonts.push(`${font.family} (weight: ${font.weight}, status: ${font.status})`);
|
|
433
|
-
});
|
|
434
|
-
console.log("[TextElement/calculateAutoWidthAndLines] All document.fonts:", loadedFonts);
|
|
435
|
-
} else {
|
|
436
|
-
console.log("[TextElement/calculateAutoWidthAndLines] document.fonts API not available");
|
|
437
|
-
}
|
|
438
407
|
const availableWidth = maxWidth - paddingLeft - paddingRight;
|
|
439
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Available width for text:", availableWidth);
|
|
440
408
|
if (availableWidth <= 0) {
|
|
441
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Available width <= 0, returning maxWidth");
|
|
442
409
|
return { width: maxWidth, lines: [text] };
|
|
443
410
|
}
|
|
444
411
|
const measureSpan = document.createElement("span");
|
|
445
|
-
|
|
412
|
+
measureSpan.style.cssText = `
|
|
446
413
|
position: absolute;
|
|
447
414
|
visibility: hidden;
|
|
448
415
|
pointer-events: none;
|
|
@@ -452,43 +419,29 @@ function calculateAutoWidthAndLines({
|
|
|
452
419
|
letter-spacing: ${letterSpacing}px;
|
|
453
420
|
white-space: nowrap;
|
|
454
421
|
`;
|
|
455
|
-
measureSpan.style.cssText = cssText;
|
|
456
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Measurement span CSS:", cssText.replace(/\s+/g, " ").trim());
|
|
457
422
|
document.body.appendChild(measureSpan);
|
|
423
|
+
const computedStyle = window.getComputedStyle(measureSpan);
|
|
424
|
+
const computedFontFamily = computedStyle.fontFamily;
|
|
425
|
+
const requestedFontLoaded = typeof document.fonts !== "undefined" ? document.fonts.check(`${fontWeight} ${fontSize}px ${fontFamily.split(",")[0]}`) : "unknown";
|
|
458
426
|
const measureText = (textToMeasure) => {
|
|
459
427
|
measureSpan.textContent = textToMeasure;
|
|
460
|
-
|
|
461
|
-
return width;
|
|
428
|
+
return measureSpan.getBoundingClientRect().width;
|
|
462
429
|
};
|
|
463
430
|
measureSpan.textContent = "M";
|
|
464
|
-
const
|
|
465
|
-
console.log('[TextElement/calculateAutoWidthAndLines] Single "M" character width:', charWidth);
|
|
466
|
-
measureSpan.textContent = "Test String";
|
|
467
|
-
const testStringWidth = measureSpan.getBoundingClientRect().width;
|
|
468
|
-
console.log('[TextElement/calculateAutoWidthAndLines] "Test String" width:', testStringWidth);
|
|
469
|
-
const computedStyle = window.getComputedStyle(measureSpan);
|
|
470
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Computed font-family:", computedStyle.fontFamily);
|
|
471
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Computed font-size:", computedStyle.fontSize);
|
|
472
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Computed font-weight:", computedStyle.fontWeight);
|
|
473
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Computed letter-spacing:", computedStyle.letterSpacing);
|
|
431
|
+
const mWidth = measureSpan.getBoundingClientRect().width;
|
|
474
432
|
const words = text.split(/(\s+)/);
|
|
475
433
|
const lines = [];
|
|
476
434
|
let currentLine = "";
|
|
477
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Word count:", words.filter((w) => w.trim()).length);
|
|
478
435
|
for (let i = 0; i < words.length; i++) {
|
|
479
436
|
const word = words[i];
|
|
480
437
|
if (word === "\n" || word === "\r\n") {
|
|
481
|
-
if (currentLine)
|
|
482
|
-
lines.push(currentLine);
|
|
483
|
-
}
|
|
438
|
+
if (currentLine) lines.push(currentLine);
|
|
484
439
|
currentLine = "";
|
|
485
440
|
continue;
|
|
486
441
|
}
|
|
487
442
|
if (!word) continue;
|
|
488
443
|
if (/^\s+$/.test(word)) {
|
|
489
|
-
if (currentLine)
|
|
490
|
-
currentLine += word;
|
|
491
|
-
}
|
|
444
|
+
if (currentLine) currentLine += word;
|
|
492
445
|
continue;
|
|
493
446
|
}
|
|
494
447
|
const testLine = currentLine + word;
|
|
@@ -523,67 +476,34 @@ function calculateAutoWidthAndLines({
|
|
|
523
476
|
currentLine = testLine;
|
|
524
477
|
}
|
|
525
478
|
}
|
|
526
|
-
if (currentLine.trim())
|
|
527
|
-
|
|
528
|
-
}
|
|
529
|
-
if (lines.length === 0) {
|
|
530
|
-
lines.push("");
|
|
531
|
-
}
|
|
479
|
+
if (currentLine.trim()) lines.push(currentLine.trimEnd());
|
|
480
|
+
if (lines.length === 0) lines.push("");
|
|
532
481
|
let widestLineWidth = 0;
|
|
533
|
-
const lineWidths = [];
|
|
534
482
|
for (const line of lines) {
|
|
535
483
|
const lineWidth = measureText(line);
|
|
536
|
-
lineWidths.push({ line: line.substring(0, 50) + (line.length > 50 ? "..." : ""), width: lineWidth });
|
|
537
484
|
widestLineWidth = Math.max(widestLineWidth, lineWidth);
|
|
538
485
|
}
|
|
539
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Line measurements:", lineWidths);
|
|
540
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Widest line width:", widestLineWidth);
|
|
541
486
|
document.body.removeChild(measureSpan);
|
|
542
487
|
const calculatedWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
|
|
543
|
-
console.log("[TextElement
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
488
|
+
console.log("[TextElement] WIDTH_CALC:", JSON.stringify({
|
|
489
|
+
text: text.substring(0, 30),
|
|
490
|
+
fontFamily: fontFamily.split(",")[0],
|
|
491
|
+
computedFont: computedFontFamily.split(",")[0],
|
|
492
|
+
fontLoaded: requestedFontLoaded,
|
|
493
|
+
fontSize,
|
|
494
|
+
fontWeight,
|
|
495
|
+
letterSpacing,
|
|
496
|
+
mWidth: Math.round(mWidth * 100) / 100,
|
|
497
|
+
widestLine: Math.round(widestLineWidth * 100) / 100,
|
|
498
|
+
paddingL: paddingLeft,
|
|
499
|
+
paddingR: paddingRight,
|
|
500
|
+
calcWidth: Math.round(calculatedWidth * 100) / 100,
|
|
501
|
+
maxWidth,
|
|
502
|
+
lines: lines.length
|
|
503
|
+
}));
|
|
552
504
|
return { width: calculatedWidth, lines };
|
|
553
505
|
}
|
|
554
506
|
function TextElement({ segment, scale = 1 }) {
|
|
555
|
-
import_react.default.useEffect(() => {
|
|
556
|
-
const fontFamily2 = getFontFamily(segment.fontType ?? TEXT_DEFAULTS.fontType);
|
|
557
|
-
console.log("[TextElement] ===== RENDER EFFECT =====");
|
|
558
|
-
console.log("[TextElement] Segment ID:", segment.id);
|
|
559
|
-
console.log("[TextElement] Rendering with:", {
|
|
560
|
-
text: segment.text?.substring(0, 50) + (segment.text?.length > 50 ? "..." : ""),
|
|
561
|
-
fontType: segment.fontType ?? TEXT_DEFAULTS.fontType,
|
|
562
|
-
fontFamily: fontFamily2,
|
|
563
|
-
hasEmojis: /[\u{1F300}-\u{1F9FF}]/u.test(segment.text || ""),
|
|
564
|
-
autoWidth: segment.autoWidth,
|
|
565
|
-
boxAlign: segment.boxAlign
|
|
566
|
-
});
|
|
567
|
-
console.log("[TextElement] Segment dimensions:", {
|
|
568
|
-
xOffset: segment.xOffset,
|
|
569
|
-
yOffset: segment.yOffset,
|
|
570
|
-
width: segment.width,
|
|
571
|
-
height: segment.height
|
|
572
|
-
});
|
|
573
|
-
console.log("[TextElement] Segment padding:", {
|
|
574
|
-
paddingTop: segment.paddingTop,
|
|
575
|
-
paddingRight: segment.paddingRight,
|
|
576
|
-
paddingBottom: segment.paddingBottom,
|
|
577
|
-
paddingLeft: segment.paddingLeft
|
|
578
|
-
});
|
|
579
|
-
console.log("[TextElement] Segment font styling:", {
|
|
580
|
-
fontSize: segment.fontSize,
|
|
581
|
-
fontWeight: segment.fontWeight,
|
|
582
|
-
letterSpacing: segment.letterSpacing,
|
|
583
|
-
lineHeight: segment.lineHeight
|
|
584
|
-
});
|
|
585
|
-
console.log("[TextElement] Scale:", scale);
|
|
586
|
-
}, [segment, scale]);
|
|
587
507
|
const fontType = segment.fontType ?? TEXT_DEFAULTS.fontType;
|
|
588
508
|
const fontSize = (segment.fontSize ?? TEXT_DEFAULTS.fontSize) * scale;
|
|
589
509
|
const fontWeight = segment.fontWeight ?? TEXT_DEFAULTS.fontWeight;
|
|
@@ -662,7 +582,7 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
662
582
|
lineHeight
|
|
663
583
|
});
|
|
664
584
|
}
|
|
665
|
-
|
|
585
|
+
return {
|
|
666
586
|
calculatedWidth: autoWidth ? finalResult.width : width,
|
|
667
587
|
calculatedLines: autoWidth ? finalResult.lines : [segment.text],
|
|
668
588
|
paddingTop: finalPaddingTop,
|
|
@@ -670,19 +590,6 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
670
590
|
paddingBottom: finalPaddingBottom,
|
|
671
591
|
paddingLeft: finalPaddingLeft
|
|
672
592
|
};
|
|
673
|
-
console.log("[TextElement/useMemo] ===== FINAL VALUES =====");
|
|
674
|
-
console.log("[TextElement/useMemo] autoWidth:", autoWidth);
|
|
675
|
-
console.log("[TextElement/useMemo] calculatedWidth:", result.calculatedWidth);
|
|
676
|
-
console.log("[TextElement/useMemo] calculatedLines:", result.calculatedLines);
|
|
677
|
-
console.log("[TextElement/useMemo] Final padding:", {
|
|
678
|
-
top: result.paddingTop,
|
|
679
|
-
right: result.paddingRight,
|
|
680
|
-
bottom: result.paddingBottom,
|
|
681
|
-
left: result.paddingLeft
|
|
682
|
-
});
|
|
683
|
-
console.log("[TextElement/useMemo] Element width (maxWidth):", width);
|
|
684
|
-
console.log("[TextElement/useMemo] Difference (maxWidth - calculatedWidth):", width - result.calculatedWidth);
|
|
685
|
-
return result;
|
|
686
593
|
}, [
|
|
687
594
|
autoWidth,
|
|
688
595
|
segment.text,
|
|
@@ -718,24 +625,11 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
718
625
|
transformOrigin: "center center",
|
|
719
626
|
display: "flex",
|
|
720
627
|
flexDirection: "column",
|
|
721
|
-
// Vertical alignment within the container
|
|
722
628
|
justifyContent: verticalAlign === "top" ? "flex-start" : verticalAlign === "bottom" ? "flex-end" : "center",
|
|
723
|
-
// Horizontal alignment (boxAlign) - only applies when autoWidth is enabled
|
|
724
629
|
alignItems: autoWidth ? boxAlign === "center" ? "center" : boxAlign === "right" ? "flex-end" : "flex-start" : "stretch"
|
|
725
630
|
}), [x, y, width, height, rotation, verticalAlign, autoWidth, boxAlign]);
|
|
726
631
|
const backgroundBoxStyle = (0, import_react.useMemo)(() => {
|
|
727
|
-
const baseStyle = autoWidth ? {
|
|
728
|
-
// Use explicit calculated width instead of fit-content
|
|
729
|
-
// This fixes the issue where multi-line text doesn't shrink to widest line
|
|
730
|
-
width: calculatedWidth,
|
|
731
|
-
maxWidth: width
|
|
732
|
-
} : {
|
|
733
|
-
// When not autoWidth, let the text div handle everything
|
|
734
|
-
display: "flex",
|
|
735
|
-
flexDirection: "column",
|
|
736
|
-
flex: 1,
|
|
737
|
-
minHeight: 0
|
|
738
|
-
};
|
|
632
|
+
const baseStyle = autoWidth ? { width: calculatedWidth, maxWidth: width } : { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 };
|
|
739
633
|
if (!backgroundColor) return baseStyle;
|
|
740
634
|
return {
|
|
741
635
|
...baseStyle,
|
|
@@ -750,12 +644,10 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
750
644
|
color,
|
|
751
645
|
lineHeight,
|
|
752
646
|
letterSpacing,
|
|
753
|
-
// textAlign works for multi-line text within the (possibly auto-width) box
|
|
754
647
|
textAlign: alignment === "justify" ? "justify" : alignment,
|
|
755
648
|
padding: `${paddingTop}px ${paddingRight}px ${paddingBottom}px ${paddingLeft}px`,
|
|
756
649
|
whiteSpace: "pre-wrap",
|
|
757
650
|
wordBreak: "break-word",
|
|
758
|
-
// When not autoWidth, handle vertical alignment via flex
|
|
759
651
|
...!autoWidth && {
|
|
760
652
|
display: "flex",
|
|
761
653
|
flexDirection: "column",
|
|
@@ -763,7 +655,6 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
763
655
|
flex: 1,
|
|
764
656
|
minHeight: 0
|
|
765
657
|
},
|
|
766
|
-
// Text stroke using text-shadow for cross-browser support
|
|
767
658
|
...strokeWidth > 0 && strokeColor && {
|
|
768
659
|
textShadow: `
|
|
769
660
|
-${strokeWidth}px -${strokeWidth}px 0 ${strokeColor},
|
|
@@ -775,7 +666,6 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
775
666
|
-${strokeWidth}px 0 0 ${strokeColor},
|
|
776
667
|
${strokeWidth}px 0 0 ${strokeColor}
|
|
777
668
|
`,
|
|
778
|
-
// Also use WebKit text stroke for better quality where supported
|
|
779
669
|
WebkitTextStroke: `${strokeWidth}px ${strokeColor}`,
|
|
780
670
|
paintOrder: "stroke fill"
|
|
781
671
|
}
|
|
@@ -797,29 +687,11 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
797
687
|
verticalAlign
|
|
798
688
|
]);
|
|
799
689
|
if (autoWidth) {
|
|
800
|
-
console.log("[TextElement/render] ===== RENDERING WITH AUTO-WIDTH =====");
|
|
801
|
-
console.log("[TextElement/render] Segment ID:", segment.id);
|
|
802
|
-
console.log("[TextElement/render] calculatedWidth being applied:", calculatedWidth);
|
|
803
|
-
console.log("[TextElement/render] maxWidth (element width):", width);
|
|
804
|
-
console.log("[TextElement/render] boxAlign:", boxAlign);
|
|
805
|
-
console.log("[TextElement/render] textAlign:", alignment);
|
|
806
|
-
console.log("[TextElement/render] Number of lines:", calculatedLines.length);
|
|
807
|
-
console.log("[TextElement/render] textStyle padding:", textStyle.padding);
|
|
808
|
-
console.log("[TextElement/render] textStyle fontFamily:", textStyle.fontFamily);
|
|
809
|
-
console.log("[TextElement/render] textStyle fontSize:", textStyle.fontSize);
|
|
810
|
-
console.log("[TextElement/render] textStyle letterSpacing:", textStyle.letterSpacing);
|
|
811
690
|
const textContent = calculatedLines.map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [
|
|
812
691
|
line,
|
|
813
692
|
index < calculatedLines.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {})
|
|
814
693
|
] }, index));
|
|
815
694
|
if (backgroundColor) {
|
|
816
|
-
console.log("[TextElement/render] Rendering WITH background");
|
|
817
|
-
console.log("[TextElement/render] Background wrapper style:", {
|
|
818
|
-
width: calculatedWidth,
|
|
819
|
-
maxWidth: width,
|
|
820
|
-
backgroundColor: hexToRgba(backgroundColor, backgroundOpacity),
|
|
821
|
-
borderRadius: borderRadiusStyle
|
|
822
|
-
});
|
|
823
695
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: positioningContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
824
696
|
"div",
|
|
825
697
|
{
|
|
@@ -833,7 +705,6 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
833
705
|
}
|
|
834
706
|
) });
|
|
835
707
|
}
|
|
836
|
-
console.log("[TextElement/render] Rendering WITHOUT background");
|
|
837
708
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: positioningContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { width: calculatedWidth, maxWidth: width }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: textStyle, children: textContent }) }) });
|
|
838
709
|
}
|
|
839
710
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: positioningContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: backgroundBoxStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: textStyle, children: segment.text }) }) });
|
|
@@ -1394,26 +1265,17 @@ function elementToTextSegment(elem) {
|
|
|
1394
1265
|
autoWidth: elem.autoWidth,
|
|
1395
1266
|
boxAlign: elem.boxAlign
|
|
1396
1267
|
};
|
|
1397
|
-
console.log("[
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
console.log("[ImageEditorComposition/elementToTextSegment] Element font:", elem.font, "fontSize:", elem.fontSize, "fontWeight:", elem.fontWeight);
|
|
1409
|
-
console.log("[ImageEditorComposition/elementToTextSegment] Element letterSpacing:", elem.letterSpacing, "lineHeight:", elem.lineHeight);
|
|
1410
|
-
console.log("[ImageEditorComposition/elementToTextSegment] Segment created:", {
|
|
1411
|
-
fontType: segment.fontType,
|
|
1412
|
-
fontSize: segment.fontSize,
|
|
1413
|
-
fontWeight: segment.fontWeight,
|
|
1414
|
-
letterSpacing: segment.letterSpacing,
|
|
1415
|
-
lineHeight: segment.lineHeight
|
|
1416
|
-
});
|
|
1268
|
+
console.log("[Composition] ELEMENT:", JSON.stringify({
|
|
1269
|
+
id: elem.id,
|
|
1270
|
+
text: (elem.text ?? "").substring(0, 20),
|
|
1271
|
+
w: elem.width,
|
|
1272
|
+
h: elem.height,
|
|
1273
|
+
font: elem.font,
|
|
1274
|
+
fontSize: elem.fontSize,
|
|
1275
|
+
autoWidth: elem.autoWidth,
|
|
1276
|
+
pL: elem.paddingLeft,
|
|
1277
|
+
pR: elem.paddingRight
|
|
1278
|
+
}));
|
|
1417
1279
|
return segment;
|
|
1418
1280
|
}
|
|
1419
1281
|
function elementToImageSegment(elem, source) {
|
|
@@ -1450,20 +1312,45 @@ function ImageEditorComposition({
|
|
|
1450
1312
|
textValues = {},
|
|
1451
1313
|
dynamicCrop
|
|
1452
1314
|
}) {
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1315
|
+
const [fontsLoaded, setFontsLoaded] = (0, import_react3.useState)(false);
|
|
1316
|
+
(0, import_react3.useEffect)(() => {
|
|
1317
|
+
const handle = (0, import_remotion2.delayRender)("Loading fonts...");
|
|
1318
|
+
const loadFonts = async () => {
|
|
1319
|
+
try {
|
|
1320
|
+
if (typeof document !== "undefined" && document.fonts) {
|
|
1321
|
+
console.log("[Composition] Waiting for fonts to load...");
|
|
1322
|
+
await document.fonts.ready;
|
|
1323
|
+
const fontChecks = await Promise.all([
|
|
1324
|
+
document.fonts.load('normal 48px "SF Pro"').catch(() => []),
|
|
1325
|
+
document.fonts.load('bold 48px "SF Pro"').catch(() => []),
|
|
1326
|
+
document.fonts.load('normal 48px "TikTok Sans"').catch(() => []),
|
|
1327
|
+
document.fonts.load('bold 48px "TikTok Sans"').catch(() => [])
|
|
1328
|
+
]);
|
|
1329
|
+
console.log("[Composition] Fonts loaded:", {
|
|
1330
|
+
sfProNormal: document.fonts.check('normal 48px "SF Pro"'),
|
|
1331
|
+
sfProBold: document.fonts.check('bold 48px "SF Pro"'),
|
|
1332
|
+
tiktokNormal: document.fonts.check('normal 48px "TikTok Sans"'),
|
|
1333
|
+
tiktokBold: document.fonts.check('bold 48px "TikTok Sans"')
|
|
1334
|
+
});
|
|
1335
|
+
}
|
|
1336
|
+
setFontsLoaded(true);
|
|
1337
|
+
(0, import_remotion2.continueRender)(handle);
|
|
1338
|
+
} catch (err) {
|
|
1339
|
+
console.error("[Composition] Font loading error:", err);
|
|
1340
|
+
setFontsLoaded(true);
|
|
1341
|
+
(0, import_remotion2.continueRender)(handle);
|
|
1342
|
+
}
|
|
1343
|
+
};
|
|
1344
|
+
loadFonts();
|
|
1345
|
+
return () => {
|
|
1346
|
+
try {
|
|
1347
|
+
(0, import_remotion2.continueRender)(handle);
|
|
1348
|
+
} catch {
|
|
1349
|
+
}
|
|
1350
|
+
};
|
|
1351
|
+
}, []);
|
|
1464
1352
|
const canvasWidth = width ?? config?.width ?? 1080;
|
|
1465
1353
|
const canvasHeight = height ?? config?.height ?? 1920;
|
|
1466
|
-
console.log("[ImageEditorComposition] Canvas dimensions:", { canvasWidth, canvasHeight });
|
|
1467
1354
|
const resolvedElements = (0, import_react3.useMemo)(() => {
|
|
1468
1355
|
if (!elements) return null;
|
|
1469
1356
|
const result = resolveElementPositions(elements, textValues);
|
|
@@ -1516,6 +1403,9 @@ function ImageEditorComposition({
|
|
|
1516
1403
|
return void 0;
|
|
1517
1404
|
};
|
|
1518
1405
|
const containerBgColor = backgroundType === "color" && backgroundColor ? backgroundColor : "#000000";
|
|
1406
|
+
if (!fontsLoaded) {
|
|
1407
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_remotion2.AbsoluteFill, { style: { backgroundColor: containerBgColor } });
|
|
1408
|
+
}
|
|
1519
1409
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_remotion2.AbsoluteFill, { style: { backgroundColor: containerBgColor }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1520
1410
|
"div",
|
|
1521
1411
|
{
|
package/dist/index.mjs
CHANGED
|
@@ -8,8 +8,8 @@ var DIMENSION_PRESETS = {
|
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
// src/compositions/ImageEditorComposition.tsx
|
|
11
|
-
import { useMemo as useMemo3 } from "react";
|
|
12
|
-
import { AbsoluteFill, Img as Img2 } from "remotion";
|
|
11
|
+
import { useMemo as useMemo3, useState, useEffect } from "react";
|
|
12
|
+
import { AbsoluteFill, Img as Img2, delayRender, continueRender } from "remotion";
|
|
13
13
|
|
|
14
14
|
// src/components/TextElement.tsx
|
|
15
15
|
import React, { useMemo } from "react";
|
|
@@ -315,48 +315,15 @@ function calculateAutoWidthAndLines({
|
|
|
315
315
|
letterSpacing,
|
|
316
316
|
lineHeight
|
|
317
317
|
}) {
|
|
318
|
-
console.log("[TextElement/calculateAutoWidthAndLines] ===== START CALCULATION =====");
|
|
319
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Input params:", {
|
|
320
|
-
text: text.substring(0, 100) + (text.length > 100 ? "..." : ""),
|
|
321
|
-
textLength: text.length,
|
|
322
|
-
maxWidth,
|
|
323
|
-
paddingLeft,
|
|
324
|
-
paddingRight,
|
|
325
|
-
fontSize,
|
|
326
|
-
fontWeight,
|
|
327
|
-
fontFamily,
|
|
328
|
-
letterSpacing,
|
|
329
|
-
lineHeight
|
|
330
|
-
});
|
|
331
318
|
if (typeof document === "undefined") {
|
|
332
|
-
console.log("[TextElement/calculateAutoWidthAndLines] SSR mode - returning maxWidth");
|
|
333
319
|
return { width: maxWidth, lines: [text] };
|
|
334
320
|
}
|
|
335
|
-
if (typeof document.fonts !== "undefined") {
|
|
336
|
-
const fontChecks = {
|
|
337
|
-
"SF Pro normal": document.fonts.check(`normal ${fontSize}px "SF Pro"`),
|
|
338
|
-
"SF Pro bold": document.fonts.check(`bold ${fontSize}px "SF Pro"`),
|
|
339
|
-
"TikTok Sans normal": document.fonts.check(`normal ${fontSize}px "TikTok Sans"`),
|
|
340
|
-
"TikTok Sans bold": document.fonts.check(`bold ${fontSize}px "TikTok Sans"`),
|
|
341
|
-
"requestedFont": document.fonts.check(`${fontWeight} ${fontSize}px ${fontFamily.split(",")[0]}`)
|
|
342
|
-
};
|
|
343
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Font loading status:", fontChecks);
|
|
344
|
-
const loadedFonts = [];
|
|
345
|
-
document.fonts.forEach((font) => {
|
|
346
|
-
loadedFonts.push(`${font.family} (weight: ${font.weight}, status: ${font.status})`);
|
|
347
|
-
});
|
|
348
|
-
console.log("[TextElement/calculateAutoWidthAndLines] All document.fonts:", loadedFonts);
|
|
349
|
-
} else {
|
|
350
|
-
console.log("[TextElement/calculateAutoWidthAndLines] document.fonts API not available");
|
|
351
|
-
}
|
|
352
321
|
const availableWidth = maxWidth - paddingLeft - paddingRight;
|
|
353
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Available width for text:", availableWidth);
|
|
354
322
|
if (availableWidth <= 0) {
|
|
355
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Available width <= 0, returning maxWidth");
|
|
356
323
|
return { width: maxWidth, lines: [text] };
|
|
357
324
|
}
|
|
358
325
|
const measureSpan = document.createElement("span");
|
|
359
|
-
|
|
326
|
+
measureSpan.style.cssText = `
|
|
360
327
|
position: absolute;
|
|
361
328
|
visibility: hidden;
|
|
362
329
|
pointer-events: none;
|
|
@@ -366,43 +333,29 @@ function calculateAutoWidthAndLines({
|
|
|
366
333
|
letter-spacing: ${letterSpacing}px;
|
|
367
334
|
white-space: nowrap;
|
|
368
335
|
`;
|
|
369
|
-
measureSpan.style.cssText = cssText;
|
|
370
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Measurement span CSS:", cssText.replace(/\s+/g, " ").trim());
|
|
371
336
|
document.body.appendChild(measureSpan);
|
|
337
|
+
const computedStyle = window.getComputedStyle(measureSpan);
|
|
338
|
+
const computedFontFamily = computedStyle.fontFamily;
|
|
339
|
+
const requestedFontLoaded = typeof document.fonts !== "undefined" ? document.fonts.check(`${fontWeight} ${fontSize}px ${fontFamily.split(",")[0]}`) : "unknown";
|
|
372
340
|
const measureText = (textToMeasure) => {
|
|
373
341
|
measureSpan.textContent = textToMeasure;
|
|
374
|
-
|
|
375
|
-
return width;
|
|
342
|
+
return measureSpan.getBoundingClientRect().width;
|
|
376
343
|
};
|
|
377
344
|
measureSpan.textContent = "M";
|
|
378
|
-
const
|
|
379
|
-
console.log('[TextElement/calculateAutoWidthAndLines] Single "M" character width:', charWidth);
|
|
380
|
-
measureSpan.textContent = "Test String";
|
|
381
|
-
const testStringWidth = measureSpan.getBoundingClientRect().width;
|
|
382
|
-
console.log('[TextElement/calculateAutoWidthAndLines] "Test String" width:', testStringWidth);
|
|
383
|
-
const computedStyle = window.getComputedStyle(measureSpan);
|
|
384
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Computed font-family:", computedStyle.fontFamily);
|
|
385
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Computed font-size:", computedStyle.fontSize);
|
|
386
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Computed font-weight:", computedStyle.fontWeight);
|
|
387
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Computed letter-spacing:", computedStyle.letterSpacing);
|
|
345
|
+
const mWidth = measureSpan.getBoundingClientRect().width;
|
|
388
346
|
const words = text.split(/(\s+)/);
|
|
389
347
|
const lines = [];
|
|
390
348
|
let currentLine = "";
|
|
391
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Word count:", words.filter((w) => w.trim()).length);
|
|
392
349
|
for (let i = 0; i < words.length; i++) {
|
|
393
350
|
const word = words[i];
|
|
394
351
|
if (word === "\n" || word === "\r\n") {
|
|
395
|
-
if (currentLine)
|
|
396
|
-
lines.push(currentLine);
|
|
397
|
-
}
|
|
352
|
+
if (currentLine) lines.push(currentLine);
|
|
398
353
|
currentLine = "";
|
|
399
354
|
continue;
|
|
400
355
|
}
|
|
401
356
|
if (!word) continue;
|
|
402
357
|
if (/^\s+$/.test(word)) {
|
|
403
|
-
if (currentLine)
|
|
404
|
-
currentLine += word;
|
|
405
|
-
}
|
|
358
|
+
if (currentLine) currentLine += word;
|
|
406
359
|
continue;
|
|
407
360
|
}
|
|
408
361
|
const testLine = currentLine + word;
|
|
@@ -437,67 +390,34 @@ function calculateAutoWidthAndLines({
|
|
|
437
390
|
currentLine = testLine;
|
|
438
391
|
}
|
|
439
392
|
}
|
|
440
|
-
if (currentLine.trim())
|
|
441
|
-
|
|
442
|
-
}
|
|
443
|
-
if (lines.length === 0) {
|
|
444
|
-
lines.push("");
|
|
445
|
-
}
|
|
393
|
+
if (currentLine.trim()) lines.push(currentLine.trimEnd());
|
|
394
|
+
if (lines.length === 0) lines.push("");
|
|
446
395
|
let widestLineWidth = 0;
|
|
447
|
-
const lineWidths = [];
|
|
448
396
|
for (const line of lines) {
|
|
449
397
|
const lineWidth = measureText(line);
|
|
450
|
-
lineWidths.push({ line: line.substring(0, 50) + (line.length > 50 ? "..." : ""), width: lineWidth });
|
|
451
398
|
widestLineWidth = Math.max(widestLineWidth, lineWidth);
|
|
452
399
|
}
|
|
453
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Line measurements:", lineWidths);
|
|
454
|
-
console.log("[TextElement/calculateAutoWidthAndLines] Widest line width:", widestLineWidth);
|
|
455
400
|
document.body.removeChild(measureSpan);
|
|
456
401
|
const calculatedWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
|
|
457
|
-
console.log("[TextElement
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
402
|
+
console.log("[TextElement] WIDTH_CALC:", JSON.stringify({
|
|
403
|
+
text: text.substring(0, 30),
|
|
404
|
+
fontFamily: fontFamily.split(",")[0],
|
|
405
|
+
computedFont: computedFontFamily.split(",")[0],
|
|
406
|
+
fontLoaded: requestedFontLoaded,
|
|
407
|
+
fontSize,
|
|
408
|
+
fontWeight,
|
|
409
|
+
letterSpacing,
|
|
410
|
+
mWidth: Math.round(mWidth * 100) / 100,
|
|
411
|
+
widestLine: Math.round(widestLineWidth * 100) / 100,
|
|
412
|
+
paddingL: paddingLeft,
|
|
413
|
+
paddingR: paddingRight,
|
|
414
|
+
calcWidth: Math.round(calculatedWidth * 100) / 100,
|
|
415
|
+
maxWidth,
|
|
416
|
+
lines: lines.length
|
|
417
|
+
}));
|
|
466
418
|
return { width: calculatedWidth, lines };
|
|
467
419
|
}
|
|
468
420
|
function TextElement({ segment, scale = 1 }) {
|
|
469
|
-
React.useEffect(() => {
|
|
470
|
-
const fontFamily2 = getFontFamily(segment.fontType ?? TEXT_DEFAULTS.fontType);
|
|
471
|
-
console.log("[TextElement] ===== RENDER EFFECT =====");
|
|
472
|
-
console.log("[TextElement] Segment ID:", segment.id);
|
|
473
|
-
console.log("[TextElement] Rendering with:", {
|
|
474
|
-
text: segment.text?.substring(0, 50) + (segment.text?.length > 50 ? "..." : ""),
|
|
475
|
-
fontType: segment.fontType ?? TEXT_DEFAULTS.fontType,
|
|
476
|
-
fontFamily: fontFamily2,
|
|
477
|
-
hasEmojis: /[\u{1F300}-\u{1F9FF}]/u.test(segment.text || ""),
|
|
478
|
-
autoWidth: segment.autoWidth,
|
|
479
|
-
boxAlign: segment.boxAlign
|
|
480
|
-
});
|
|
481
|
-
console.log("[TextElement] Segment dimensions:", {
|
|
482
|
-
xOffset: segment.xOffset,
|
|
483
|
-
yOffset: segment.yOffset,
|
|
484
|
-
width: segment.width,
|
|
485
|
-
height: segment.height
|
|
486
|
-
});
|
|
487
|
-
console.log("[TextElement] Segment padding:", {
|
|
488
|
-
paddingTop: segment.paddingTop,
|
|
489
|
-
paddingRight: segment.paddingRight,
|
|
490
|
-
paddingBottom: segment.paddingBottom,
|
|
491
|
-
paddingLeft: segment.paddingLeft
|
|
492
|
-
});
|
|
493
|
-
console.log("[TextElement] Segment font styling:", {
|
|
494
|
-
fontSize: segment.fontSize,
|
|
495
|
-
fontWeight: segment.fontWeight,
|
|
496
|
-
letterSpacing: segment.letterSpacing,
|
|
497
|
-
lineHeight: segment.lineHeight
|
|
498
|
-
});
|
|
499
|
-
console.log("[TextElement] Scale:", scale);
|
|
500
|
-
}, [segment, scale]);
|
|
501
421
|
const fontType = segment.fontType ?? TEXT_DEFAULTS.fontType;
|
|
502
422
|
const fontSize = (segment.fontSize ?? TEXT_DEFAULTS.fontSize) * scale;
|
|
503
423
|
const fontWeight = segment.fontWeight ?? TEXT_DEFAULTS.fontWeight;
|
|
@@ -576,7 +496,7 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
576
496
|
lineHeight
|
|
577
497
|
});
|
|
578
498
|
}
|
|
579
|
-
|
|
499
|
+
return {
|
|
580
500
|
calculatedWidth: autoWidth ? finalResult.width : width,
|
|
581
501
|
calculatedLines: autoWidth ? finalResult.lines : [segment.text],
|
|
582
502
|
paddingTop: finalPaddingTop,
|
|
@@ -584,19 +504,6 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
584
504
|
paddingBottom: finalPaddingBottom,
|
|
585
505
|
paddingLeft: finalPaddingLeft
|
|
586
506
|
};
|
|
587
|
-
console.log("[TextElement/useMemo] ===== FINAL VALUES =====");
|
|
588
|
-
console.log("[TextElement/useMemo] autoWidth:", autoWidth);
|
|
589
|
-
console.log("[TextElement/useMemo] calculatedWidth:", result.calculatedWidth);
|
|
590
|
-
console.log("[TextElement/useMemo] calculatedLines:", result.calculatedLines);
|
|
591
|
-
console.log("[TextElement/useMemo] Final padding:", {
|
|
592
|
-
top: result.paddingTop,
|
|
593
|
-
right: result.paddingRight,
|
|
594
|
-
bottom: result.paddingBottom,
|
|
595
|
-
left: result.paddingLeft
|
|
596
|
-
});
|
|
597
|
-
console.log("[TextElement/useMemo] Element width (maxWidth):", width);
|
|
598
|
-
console.log("[TextElement/useMemo] Difference (maxWidth - calculatedWidth):", width - result.calculatedWidth);
|
|
599
|
-
return result;
|
|
600
507
|
}, [
|
|
601
508
|
autoWidth,
|
|
602
509
|
segment.text,
|
|
@@ -632,24 +539,11 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
632
539
|
transformOrigin: "center center",
|
|
633
540
|
display: "flex",
|
|
634
541
|
flexDirection: "column",
|
|
635
|
-
// Vertical alignment within the container
|
|
636
542
|
justifyContent: verticalAlign === "top" ? "flex-start" : verticalAlign === "bottom" ? "flex-end" : "center",
|
|
637
|
-
// Horizontal alignment (boxAlign) - only applies when autoWidth is enabled
|
|
638
543
|
alignItems: autoWidth ? boxAlign === "center" ? "center" : boxAlign === "right" ? "flex-end" : "flex-start" : "stretch"
|
|
639
544
|
}), [x, y, width, height, rotation, verticalAlign, autoWidth, boxAlign]);
|
|
640
545
|
const backgroundBoxStyle = useMemo(() => {
|
|
641
|
-
const baseStyle = autoWidth ? {
|
|
642
|
-
// Use explicit calculated width instead of fit-content
|
|
643
|
-
// This fixes the issue where multi-line text doesn't shrink to widest line
|
|
644
|
-
width: calculatedWidth,
|
|
645
|
-
maxWidth: width
|
|
646
|
-
} : {
|
|
647
|
-
// When not autoWidth, let the text div handle everything
|
|
648
|
-
display: "flex",
|
|
649
|
-
flexDirection: "column",
|
|
650
|
-
flex: 1,
|
|
651
|
-
minHeight: 0
|
|
652
|
-
};
|
|
546
|
+
const baseStyle = autoWidth ? { width: calculatedWidth, maxWidth: width } : { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 };
|
|
653
547
|
if (!backgroundColor) return baseStyle;
|
|
654
548
|
return {
|
|
655
549
|
...baseStyle,
|
|
@@ -664,12 +558,10 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
664
558
|
color,
|
|
665
559
|
lineHeight,
|
|
666
560
|
letterSpacing,
|
|
667
|
-
// textAlign works for multi-line text within the (possibly auto-width) box
|
|
668
561
|
textAlign: alignment === "justify" ? "justify" : alignment,
|
|
669
562
|
padding: `${paddingTop}px ${paddingRight}px ${paddingBottom}px ${paddingLeft}px`,
|
|
670
563
|
whiteSpace: "pre-wrap",
|
|
671
564
|
wordBreak: "break-word",
|
|
672
|
-
// When not autoWidth, handle vertical alignment via flex
|
|
673
565
|
...!autoWidth && {
|
|
674
566
|
display: "flex",
|
|
675
567
|
flexDirection: "column",
|
|
@@ -677,7 +569,6 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
677
569
|
flex: 1,
|
|
678
570
|
minHeight: 0
|
|
679
571
|
},
|
|
680
|
-
// Text stroke using text-shadow for cross-browser support
|
|
681
572
|
...strokeWidth > 0 && strokeColor && {
|
|
682
573
|
textShadow: `
|
|
683
574
|
-${strokeWidth}px -${strokeWidth}px 0 ${strokeColor},
|
|
@@ -689,7 +580,6 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
689
580
|
-${strokeWidth}px 0 0 ${strokeColor},
|
|
690
581
|
${strokeWidth}px 0 0 ${strokeColor}
|
|
691
582
|
`,
|
|
692
|
-
// Also use WebKit text stroke for better quality where supported
|
|
693
583
|
WebkitTextStroke: `${strokeWidth}px ${strokeColor}`,
|
|
694
584
|
paintOrder: "stroke fill"
|
|
695
585
|
}
|
|
@@ -711,29 +601,11 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
711
601
|
verticalAlign
|
|
712
602
|
]);
|
|
713
603
|
if (autoWidth) {
|
|
714
|
-
console.log("[TextElement/render] ===== RENDERING WITH AUTO-WIDTH =====");
|
|
715
|
-
console.log("[TextElement/render] Segment ID:", segment.id);
|
|
716
|
-
console.log("[TextElement/render] calculatedWidth being applied:", calculatedWidth);
|
|
717
|
-
console.log("[TextElement/render] maxWidth (element width):", width);
|
|
718
|
-
console.log("[TextElement/render] boxAlign:", boxAlign);
|
|
719
|
-
console.log("[TextElement/render] textAlign:", alignment);
|
|
720
|
-
console.log("[TextElement/render] Number of lines:", calculatedLines.length);
|
|
721
|
-
console.log("[TextElement/render] textStyle padding:", textStyle.padding);
|
|
722
|
-
console.log("[TextElement/render] textStyle fontFamily:", textStyle.fontFamily);
|
|
723
|
-
console.log("[TextElement/render] textStyle fontSize:", textStyle.fontSize);
|
|
724
|
-
console.log("[TextElement/render] textStyle letterSpacing:", textStyle.letterSpacing);
|
|
725
604
|
const textContent = calculatedLines.map((line, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
726
605
|
line,
|
|
727
606
|
index < calculatedLines.length - 1 && /* @__PURE__ */ jsx("br", {})
|
|
728
607
|
] }, index));
|
|
729
608
|
if (backgroundColor) {
|
|
730
|
-
console.log("[TextElement/render] Rendering WITH background");
|
|
731
|
-
console.log("[TextElement/render] Background wrapper style:", {
|
|
732
|
-
width: calculatedWidth,
|
|
733
|
-
maxWidth: width,
|
|
734
|
-
backgroundColor: hexToRgba(backgroundColor, backgroundOpacity),
|
|
735
|
-
borderRadius: borderRadiusStyle
|
|
736
|
-
});
|
|
737
609
|
return /* @__PURE__ */ jsx("div", { style: positioningContainerStyle, children: /* @__PURE__ */ jsx(
|
|
738
610
|
"div",
|
|
739
611
|
{
|
|
@@ -747,7 +619,6 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
747
619
|
}
|
|
748
620
|
) });
|
|
749
621
|
}
|
|
750
|
-
console.log("[TextElement/render] Rendering WITHOUT background");
|
|
751
622
|
return /* @__PURE__ */ jsx("div", { style: positioningContainerStyle, children: /* @__PURE__ */ jsx("div", { style: { width: calculatedWidth, maxWidth: width }, children: /* @__PURE__ */ jsx("div", { style: textStyle, children: textContent }) }) });
|
|
752
623
|
}
|
|
753
624
|
return /* @__PURE__ */ jsx("div", { style: positioningContainerStyle, children: /* @__PURE__ */ jsx("div", { style: backgroundBoxStyle, children: /* @__PURE__ */ jsx("div", { style: textStyle, children: segment.text }) }) });
|
|
@@ -1308,26 +1179,17 @@ function elementToTextSegment(elem) {
|
|
|
1308
1179
|
autoWidth: elem.autoWidth,
|
|
1309
1180
|
boxAlign: elem.boxAlign
|
|
1310
1181
|
};
|
|
1311
|
-
console.log("[
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
console.log("[ImageEditorComposition/elementToTextSegment] Element font:", elem.font, "fontSize:", elem.fontSize, "fontWeight:", elem.fontWeight);
|
|
1323
|
-
console.log("[ImageEditorComposition/elementToTextSegment] Element letterSpacing:", elem.letterSpacing, "lineHeight:", elem.lineHeight);
|
|
1324
|
-
console.log("[ImageEditorComposition/elementToTextSegment] Segment created:", {
|
|
1325
|
-
fontType: segment.fontType,
|
|
1326
|
-
fontSize: segment.fontSize,
|
|
1327
|
-
fontWeight: segment.fontWeight,
|
|
1328
|
-
letterSpacing: segment.letterSpacing,
|
|
1329
|
-
lineHeight: segment.lineHeight
|
|
1330
|
-
});
|
|
1182
|
+
console.log("[Composition] ELEMENT:", JSON.stringify({
|
|
1183
|
+
id: elem.id,
|
|
1184
|
+
text: (elem.text ?? "").substring(0, 20),
|
|
1185
|
+
w: elem.width,
|
|
1186
|
+
h: elem.height,
|
|
1187
|
+
font: elem.font,
|
|
1188
|
+
fontSize: elem.fontSize,
|
|
1189
|
+
autoWidth: elem.autoWidth,
|
|
1190
|
+
pL: elem.paddingLeft,
|
|
1191
|
+
pR: elem.paddingRight
|
|
1192
|
+
}));
|
|
1331
1193
|
return segment;
|
|
1332
1194
|
}
|
|
1333
1195
|
function elementToImageSegment(elem, source) {
|
|
@@ -1364,20 +1226,45 @@ function ImageEditorComposition({
|
|
|
1364
1226
|
textValues = {},
|
|
1365
1227
|
dynamicCrop
|
|
1366
1228
|
}) {
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1229
|
+
const [fontsLoaded, setFontsLoaded] = useState(false);
|
|
1230
|
+
useEffect(() => {
|
|
1231
|
+
const handle = delayRender("Loading fonts...");
|
|
1232
|
+
const loadFonts = async () => {
|
|
1233
|
+
try {
|
|
1234
|
+
if (typeof document !== "undefined" && document.fonts) {
|
|
1235
|
+
console.log("[Composition] Waiting for fonts to load...");
|
|
1236
|
+
await document.fonts.ready;
|
|
1237
|
+
const fontChecks = await Promise.all([
|
|
1238
|
+
document.fonts.load('normal 48px "SF Pro"').catch(() => []),
|
|
1239
|
+
document.fonts.load('bold 48px "SF Pro"').catch(() => []),
|
|
1240
|
+
document.fonts.load('normal 48px "TikTok Sans"').catch(() => []),
|
|
1241
|
+
document.fonts.load('bold 48px "TikTok Sans"').catch(() => [])
|
|
1242
|
+
]);
|
|
1243
|
+
console.log("[Composition] Fonts loaded:", {
|
|
1244
|
+
sfProNormal: document.fonts.check('normal 48px "SF Pro"'),
|
|
1245
|
+
sfProBold: document.fonts.check('bold 48px "SF Pro"'),
|
|
1246
|
+
tiktokNormal: document.fonts.check('normal 48px "TikTok Sans"'),
|
|
1247
|
+
tiktokBold: document.fonts.check('bold 48px "TikTok Sans"')
|
|
1248
|
+
});
|
|
1249
|
+
}
|
|
1250
|
+
setFontsLoaded(true);
|
|
1251
|
+
continueRender(handle);
|
|
1252
|
+
} catch (err) {
|
|
1253
|
+
console.error("[Composition] Font loading error:", err);
|
|
1254
|
+
setFontsLoaded(true);
|
|
1255
|
+
continueRender(handle);
|
|
1256
|
+
}
|
|
1257
|
+
};
|
|
1258
|
+
loadFonts();
|
|
1259
|
+
return () => {
|
|
1260
|
+
try {
|
|
1261
|
+
continueRender(handle);
|
|
1262
|
+
} catch {
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
}, []);
|
|
1378
1266
|
const canvasWidth = width ?? config?.width ?? 1080;
|
|
1379
1267
|
const canvasHeight = height ?? config?.height ?? 1920;
|
|
1380
|
-
console.log("[ImageEditorComposition] Canvas dimensions:", { canvasWidth, canvasHeight });
|
|
1381
1268
|
const resolvedElements = useMemo3(() => {
|
|
1382
1269
|
if (!elements) return null;
|
|
1383
1270
|
const result = resolveElementPositions(elements, textValues);
|
|
@@ -1430,6 +1317,9 @@ function ImageEditorComposition({
|
|
|
1430
1317
|
return void 0;
|
|
1431
1318
|
};
|
|
1432
1319
|
const containerBgColor = backgroundType === "color" && backgroundColor ? backgroundColor : "#000000";
|
|
1320
|
+
if (!fontsLoaded) {
|
|
1321
|
+
return /* @__PURE__ */ jsx3(AbsoluteFill, { style: { backgroundColor: containerBgColor } });
|
|
1322
|
+
}
|
|
1433
1323
|
return /* @__PURE__ */ jsx3(AbsoluteFill, { style: { backgroundColor: containerBgColor }, children: /* @__PURE__ */ jsxs2(
|
|
1434
1324
|
"div",
|
|
1435
1325
|
{
|
|
@@ -1942,10 +1832,10 @@ function generateOverlayId() {
|
|
|
1942
1832
|
}
|
|
1943
1833
|
|
|
1944
1834
|
// src/hooks/index.ts
|
|
1945
|
-
import { useEffect, useState, useMemo as useMemo6 } from "react";
|
|
1835
|
+
import { useEffect as useEffect2, useState as useState2, useMemo as useMemo6 } from "react";
|
|
1946
1836
|
function useFontsLoaded() {
|
|
1947
|
-
const [loaded, setLoaded] =
|
|
1948
|
-
|
|
1837
|
+
const [loaded, setLoaded] = useState2(areFontsLoaded());
|
|
1838
|
+
useEffect2(() => {
|
|
1949
1839
|
if (!loaded) {
|
|
1950
1840
|
preloadFonts().then(() => setLoaded(true)).catch(console.error);
|
|
1951
1841
|
}
|
|
@@ -1953,8 +1843,8 @@ function useFontsLoaded() {
|
|
|
1953
1843
|
return loaded;
|
|
1954
1844
|
}
|
|
1955
1845
|
function useImageLoader(src) {
|
|
1956
|
-
const [image, setImage] =
|
|
1957
|
-
|
|
1846
|
+
const [image, setImage] = useState2(null);
|
|
1847
|
+
useEffect2(() => {
|
|
1958
1848
|
if (!src) {
|
|
1959
1849
|
setImage(null);
|
|
1960
1850
|
return;
|
|
@@ -1974,9 +1864,9 @@ function useImageLoader(src) {
|
|
|
1974
1864
|
return image;
|
|
1975
1865
|
}
|
|
1976
1866
|
function useImagePreloader(sources) {
|
|
1977
|
-
const [images, setImages] =
|
|
1978
|
-
const [loaded, setLoaded] =
|
|
1979
|
-
|
|
1867
|
+
const [images, setImages] = useState2({});
|
|
1868
|
+
const [loaded, setLoaded] = useState2(false);
|
|
1869
|
+
useEffect2(() => {
|
|
1980
1870
|
const entries = Object.entries(sources);
|
|
1981
1871
|
if (entries.length === 0) {
|
|
1982
1872
|
setLoaded(true);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ugcinc-render",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.20",
|
|
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",
|