ugcinc-render 1.5.16 → 1.5.18
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 +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +265 -33
- package/dist/index.mjs +264 -33
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1002,6 +1002,10 @@ declare function preloadFonts(): Promise<void>;
|
|
|
1002
1002
|
* Check if fonts are loaded
|
|
1003
1003
|
*/
|
|
1004
1004
|
declare function areFontsLoaded(): boolean;
|
|
1005
|
+
/**
|
|
1006
|
+
* Debug utility to log current font status
|
|
1007
|
+
*/
|
|
1008
|
+
declare function debugFontStatus(): void;
|
|
1005
1009
|
|
|
1006
1010
|
/**
|
|
1007
1011
|
* Fit calculation utilities for media positioning
|
|
@@ -1357,4 +1361,4 @@ declare function useResolvedPositions(elements: ImageEditorElement[], textValues
|
|
|
1357
1361
|
|
|
1358
1362
|
declare const RenderRoot: React.FC;
|
|
1359
1363
|
|
|
1360
|
-
export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
|
|
1364
|
+
export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, debugFontStatus, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
|
package/dist/index.d.ts
CHANGED
|
@@ -1002,6 +1002,10 @@ declare function preloadFonts(): Promise<void>;
|
|
|
1002
1002
|
* Check if fonts are loaded
|
|
1003
1003
|
*/
|
|
1004
1004
|
declare function areFontsLoaded(): boolean;
|
|
1005
|
+
/**
|
|
1006
|
+
* Debug utility to log current font status
|
|
1007
|
+
*/
|
|
1008
|
+
declare function debugFontStatus(): void;
|
|
1005
1009
|
|
|
1006
1010
|
/**
|
|
1007
1011
|
* Fit calculation utilities for media positioning
|
|
@@ -1357,4 +1361,4 @@ declare function useResolvedPositions(elements: ImageEditorElement[], textValues
|
|
|
1357
1361
|
|
|
1358
1362
|
declare const RenderRoot: React.FC;
|
|
1359
1363
|
|
|
1360
|
-
export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
|
|
1364
|
+
export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, debugFontStatus, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
|
package/dist/index.js
CHANGED
|
@@ -56,6 +56,7 @@ __export(index_exports, {
|
|
|
56
56
|
calculateLineWidth: () => calculateLineWidth,
|
|
57
57
|
calculateTimelineContentEnd: () => calculateTimelineContentEnd,
|
|
58
58
|
canSetAsReference: () => canSetAsReference,
|
|
59
|
+
debugFontStatus: () => debugFontStatus,
|
|
59
60
|
defaultOffset: () => defaultOffset,
|
|
60
61
|
formatTime: () => formatTime,
|
|
61
62
|
generateOverlayId: () => generateOverlayId,
|
|
@@ -190,43 +191,117 @@ var FONT_URLS = {
|
|
|
190
191
|
}
|
|
191
192
|
};
|
|
192
193
|
async function preloadFonts() {
|
|
194
|
+
console.log("[ugcinc-render/fonts] preloadFonts() called");
|
|
193
195
|
if (typeof document !== "undefined") {
|
|
194
|
-
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
196
|
+
console.log("[ugcinc-render/fonts] Browser environment detected, loading fonts...");
|
|
197
|
+
const fontResults = [];
|
|
198
|
+
try {
|
|
199
|
+
const tiktokRegular = new FontFace(
|
|
200
|
+
"TikTok Sans",
|
|
201
|
+
`url(${FONT_URLS.tiktok.regular})`,
|
|
202
|
+
{ weight: "normal" }
|
|
203
|
+
);
|
|
204
|
+
console.log(`[ugcinc-render/fonts] Loading TikTok Sans Regular from: ${FONT_URLS.tiktok.regular}`);
|
|
205
|
+
await tiktokRegular.load();
|
|
206
|
+
document.fonts.add(tiktokRegular);
|
|
207
|
+
fontResults.push({ name: "TikTok Sans Regular", status: "success" });
|
|
208
|
+
} catch (err) {
|
|
209
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
210
|
+
console.error(`[ugcinc-render/fonts] Failed to load TikTok Sans Regular:`, errorMsg);
|
|
211
|
+
fontResults.push({ name: "TikTok Sans Regular", status: "error", error: errorMsg });
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
const tiktokBold = new FontFace(
|
|
215
|
+
"TikTok Sans",
|
|
216
|
+
`url(${FONT_URLS.tiktok.bold})`,
|
|
217
|
+
{ weight: "bold" }
|
|
218
|
+
);
|
|
219
|
+
console.log(`[ugcinc-render/fonts] Loading TikTok Sans Bold from: ${FONT_URLS.tiktok.bold}`);
|
|
220
|
+
await tiktokBold.load();
|
|
221
|
+
document.fonts.add(tiktokBold);
|
|
222
|
+
fontResults.push({ name: "TikTok Sans Bold", status: "success" });
|
|
223
|
+
} catch (err) {
|
|
224
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
225
|
+
console.error(`[ugcinc-render/fonts] Failed to load TikTok Sans Bold:`, errorMsg);
|
|
226
|
+
fontResults.push({ name: "TikTok Sans Bold", status: "error", error: errorMsg });
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
const sfPro = new FontFace(
|
|
230
|
+
"SF Pro",
|
|
231
|
+
`url(${FONT_URLS.apple.regular})`,
|
|
232
|
+
{ weight: "normal" }
|
|
233
|
+
);
|
|
234
|
+
console.log(`[ugcinc-render/fonts] Loading SF Pro from: ${FONT_URLS.apple.regular}`);
|
|
235
|
+
await sfPro.load();
|
|
236
|
+
document.fonts.add(sfPro);
|
|
237
|
+
fontResults.push({ name: "SF Pro", status: "success" });
|
|
238
|
+
} catch (err) {
|
|
239
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
240
|
+
console.error(`[ugcinc-render/fonts] Failed to load SF Pro:`, errorMsg);
|
|
241
|
+
fontResults.push({ name: "SF Pro", status: "error", error: errorMsg });
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
const appleEmoji = new FontFace(
|
|
245
|
+
"Apple Color Emoji",
|
|
246
|
+
`url(${FONT_URLS.emoji.apple})`,
|
|
247
|
+
{ weight: "normal" }
|
|
248
|
+
);
|
|
249
|
+
console.log(`[ugcinc-render/fonts] Loading Apple Color Emoji from: ${FONT_URLS.emoji.apple}`);
|
|
250
|
+
await appleEmoji.load();
|
|
251
|
+
document.fonts.add(appleEmoji);
|
|
252
|
+
fontResults.push({ name: "Apple Color Emoji", status: "success" });
|
|
253
|
+
} catch (err) {
|
|
254
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
255
|
+
console.error(`[ugcinc-render/fonts] Failed to load Apple Color Emoji:`, errorMsg);
|
|
256
|
+
fontResults.push({ name: "Apple Color Emoji", status: "error", error: errorMsg });
|
|
257
|
+
}
|
|
258
|
+
console.log("[ugcinc-render/fonts] Font loading complete. Results:", fontResults);
|
|
259
|
+
const availableFonts = [];
|
|
260
|
+
document.fonts.forEach((font) => {
|
|
261
|
+
availableFonts.push(`${font.family} (${font.weight}, ${font.status})`);
|
|
222
262
|
});
|
|
263
|
+
console.log("[ugcinc-render/fonts] Available fonts in document:", availableFonts);
|
|
264
|
+
} else {
|
|
265
|
+
console.log("[ugcinc-render/fonts] Not in browser environment, skipping font loading");
|
|
223
266
|
}
|
|
224
267
|
}
|
|
225
268
|
function areFontsLoaded() {
|
|
226
269
|
if (typeof document === "undefined") {
|
|
270
|
+
console.log("[ugcinc-render/fonts] areFontsLoaded: Not in browser environment");
|
|
227
271
|
return false;
|
|
228
272
|
}
|
|
229
|
-
|
|
273
|
+
const tiktokRegular = document.fonts.check('normal 16px "TikTok Sans"');
|
|
274
|
+
const tiktokBold = document.fonts.check('bold 16px "TikTok Sans"');
|
|
275
|
+
const sfPro = document.fonts.check('normal 16px "SF Pro"');
|
|
276
|
+
const appleEmoji = document.fonts.check('normal 16px "Apple Color Emoji"');
|
|
277
|
+
console.log("[ugcinc-render/fonts] areFontsLoaded check:", {
|
|
278
|
+
tiktokRegular,
|
|
279
|
+
tiktokBold,
|
|
280
|
+
sfPro,
|
|
281
|
+
appleEmoji
|
|
282
|
+
});
|
|
283
|
+
return tiktokRegular && tiktokBold && sfPro && appleEmoji;
|
|
284
|
+
}
|
|
285
|
+
function debugFontStatus() {
|
|
286
|
+
console.log("[ugcinc-render/fonts] === FONT DEBUG STATUS ===");
|
|
287
|
+
if (typeof document === "undefined") {
|
|
288
|
+
console.log("[ugcinc-render/fonts] Not in browser environment");
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
console.log("[ugcinc-render/fonts] Font checks:");
|
|
292
|
+
console.log(" - TikTok Sans (normal):", document.fonts.check('normal 16px "TikTok Sans"'));
|
|
293
|
+
console.log(" - TikTok Sans (bold):", document.fonts.check('bold 16px "TikTok Sans"'));
|
|
294
|
+
console.log(" - SF Pro:", document.fonts.check('normal 16px "SF Pro"'));
|
|
295
|
+
console.log(" - Apple Color Emoji:", document.fonts.check('normal 16px "Apple Color Emoji"'));
|
|
296
|
+
console.log("[ugcinc-render/fonts] All fonts in document.fonts:");
|
|
297
|
+
document.fonts.forEach((font) => {
|
|
298
|
+
console.log(` - ${font.family}: weight=${font.weight}, style=${font.style}, status=${font.status}`);
|
|
299
|
+
});
|
|
300
|
+
console.log("[ugcinc-render/fonts] Font family stacks:");
|
|
301
|
+
console.log(" - tiktok:", FONT_FAMILIES.tiktok);
|
|
302
|
+
console.log(" - apple:", FONT_FAMILIES.apple);
|
|
303
|
+
console.log(" - arial:", FONT_FAMILIES.arial);
|
|
304
|
+
console.log("[ugcinc-render/fonts] === END FONT DEBUG ===");
|
|
230
305
|
}
|
|
231
306
|
|
|
232
307
|
// src/utils/text.ts
|
|
@@ -326,15 +401,48 @@ function calculateAutoWidthAndLines({
|
|
|
326
401
|
letterSpacing,
|
|
327
402
|
lineHeight
|
|
328
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
|
+
});
|
|
329
417
|
if (typeof document === "undefined") {
|
|
418
|
+
console.log("[TextElement/calculateAutoWidthAndLines] SSR mode - returning maxWidth");
|
|
330
419
|
return { width: maxWidth, lines: [text] };
|
|
331
420
|
}
|
|
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
|
+
}
|
|
332
438
|
const availableWidth = maxWidth - paddingLeft - paddingRight;
|
|
439
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Available width for text:", availableWidth);
|
|
333
440
|
if (availableWidth <= 0) {
|
|
441
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Available width <= 0, returning maxWidth");
|
|
334
442
|
return { width: maxWidth, lines: [text] };
|
|
335
443
|
}
|
|
336
444
|
const measureSpan = document.createElement("span");
|
|
337
|
-
|
|
445
|
+
const cssText = `
|
|
338
446
|
position: absolute;
|
|
339
447
|
visibility: hidden;
|
|
340
448
|
pointer-events: none;
|
|
@@ -344,16 +452,29 @@ function calculateAutoWidthAndLines({
|
|
|
344
452
|
letter-spacing: ${letterSpacing}px;
|
|
345
453
|
white-space: nowrap;
|
|
346
454
|
`;
|
|
455
|
+
measureSpan.style.cssText = cssText;
|
|
456
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Measurement span CSS:", cssText.replace(/\s+/g, " ").trim());
|
|
347
457
|
document.body.appendChild(measureSpan);
|
|
348
458
|
const measureText = (textToMeasure) => {
|
|
349
459
|
measureSpan.textContent = textToMeasure;
|
|
350
|
-
|
|
460
|
+
const width = measureSpan.getBoundingClientRect().width;
|
|
461
|
+
return width;
|
|
351
462
|
};
|
|
352
463
|
measureSpan.textContent = "M";
|
|
353
464
|
const charWidth = measureSpan.getBoundingClientRect().width;
|
|
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);
|
|
354
474
|
const words = text.split(/(\s+)/);
|
|
355
475
|
const lines = [];
|
|
356
476
|
let currentLine = "";
|
|
477
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Word count:", words.filter((w) => w.trim()).length);
|
|
357
478
|
for (let i = 0; i < words.length; i++) {
|
|
358
479
|
const word = words[i];
|
|
359
480
|
if (word === "\n" || word === "\r\n") {
|
|
@@ -409,15 +530,60 @@ function calculateAutoWidthAndLines({
|
|
|
409
530
|
lines.push("");
|
|
410
531
|
}
|
|
411
532
|
let widestLineWidth = 0;
|
|
533
|
+
const lineWidths = [];
|
|
412
534
|
for (const line of lines) {
|
|
413
535
|
const lineWidth = measureText(line);
|
|
536
|
+
lineWidths.push({ line: line.substring(0, 50) + (line.length > 50 ? "..." : ""), width: lineWidth });
|
|
414
537
|
widestLineWidth = Math.max(widestLineWidth, lineWidth);
|
|
415
538
|
}
|
|
539
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Line measurements:", lineWidths);
|
|
540
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Widest line width:", widestLineWidth);
|
|
416
541
|
document.body.removeChild(measureSpan);
|
|
417
542
|
const calculatedWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
|
|
543
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Final calculation:", {
|
|
544
|
+
widestLineWidth,
|
|
545
|
+
paddingLeft,
|
|
546
|
+
paddingRight,
|
|
547
|
+
rawCalculatedWidth: widestLineWidth + paddingLeft + paddingRight,
|
|
548
|
+
cappedToMaxWidth: calculatedWidth,
|
|
549
|
+
maxWidth
|
|
550
|
+
});
|
|
551
|
+
console.log("[TextElement/calculateAutoWidthAndLines] ===== END CALCULATION =====");
|
|
418
552
|
return { width: calculatedWidth, lines };
|
|
419
553
|
}
|
|
420
554
|
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]);
|
|
421
587
|
const fontType = segment.fontType ?? TEXT_DEFAULTS.fontType;
|
|
422
588
|
const fontSize = (segment.fontSize ?? TEXT_DEFAULTS.fontSize) * scale;
|
|
423
589
|
const fontWeight = segment.fontWeight ?? TEXT_DEFAULTS.fontWeight;
|
|
@@ -496,7 +662,7 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
496
662
|
lineHeight
|
|
497
663
|
});
|
|
498
664
|
}
|
|
499
|
-
|
|
665
|
+
const result = {
|
|
500
666
|
calculatedWidth: autoWidth ? finalResult.width : width,
|
|
501
667
|
calculatedLines: autoWidth ? finalResult.lines : [segment.text],
|
|
502
668
|
paddingTop: finalPaddingTop,
|
|
@@ -504,6 +670,19 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
504
670
|
paddingBottom: finalPaddingBottom,
|
|
505
671
|
paddingLeft: finalPaddingLeft
|
|
506
672
|
};
|
|
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;
|
|
507
686
|
}, [
|
|
508
687
|
autoWidth,
|
|
509
688
|
segment.text,
|
|
@@ -618,11 +797,29 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
618
797
|
verticalAlign
|
|
619
798
|
]);
|
|
620
799
|
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);
|
|
621
811
|
const textContent = calculatedLines.map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [
|
|
622
812
|
line,
|
|
623
813
|
index < calculatedLines.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {})
|
|
624
814
|
] }, index));
|
|
625
815
|
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
|
+
});
|
|
626
823
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: positioningContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
627
824
|
"div",
|
|
628
825
|
{
|
|
@@ -636,6 +833,7 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
636
833
|
}
|
|
637
834
|
) });
|
|
638
835
|
}
|
|
836
|
+
console.log("[TextElement/render] Rendering WITHOUT background");
|
|
639
837
|
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 }) }) });
|
|
640
838
|
}
|
|
641
839
|
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 }) }) });
|
|
@@ -1158,7 +1356,7 @@ function getSortedSegments(config) {
|
|
|
1158
1356
|
});
|
|
1159
1357
|
}
|
|
1160
1358
|
function elementToTextSegment(elem) {
|
|
1161
|
-
|
|
1359
|
+
const segment = {
|
|
1162
1360
|
id: elem.id,
|
|
1163
1361
|
type: "text",
|
|
1164
1362
|
source: "",
|
|
@@ -1196,6 +1394,27 @@ function elementToTextSegment(elem) {
|
|
|
1196
1394
|
autoWidth: elem.autoWidth,
|
|
1197
1395
|
boxAlign: elem.boxAlign
|
|
1198
1396
|
};
|
|
1397
|
+
console.log("[ImageEditorComposition/elementToTextSegment] ===== CONVERTING ELEMENT TO SEGMENT =====");
|
|
1398
|
+
console.log("[ImageEditorComposition/elementToTextSegment] Element ID:", elem.id);
|
|
1399
|
+
console.log("[ImageEditorComposition/elementToTextSegment] Element text:", (elem.text ?? "").substring(0, 50));
|
|
1400
|
+
console.log("[ImageEditorComposition/elementToTextSegment] Element dimensions:", { x: elem.x, y: elem.y, width: elem.width, height: elem.height });
|
|
1401
|
+
console.log("[ImageEditorComposition/elementToTextSegment] Element padding:", {
|
|
1402
|
+
paddingTop: elem.paddingTop,
|
|
1403
|
+
paddingRight: elem.paddingRight,
|
|
1404
|
+
paddingBottom: elem.paddingBottom,
|
|
1405
|
+
paddingLeft: elem.paddingLeft
|
|
1406
|
+
});
|
|
1407
|
+
console.log("[ImageEditorComposition/elementToTextSegment] Element autoWidth:", elem.autoWidth, "boxAlign:", elem.boxAlign);
|
|
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
|
+
});
|
|
1417
|
+
return segment;
|
|
1199
1418
|
}
|
|
1200
1419
|
function elementToImageSegment(elem, source) {
|
|
1201
1420
|
return {
|
|
@@ -1231,8 +1450,20 @@ function ImageEditorComposition({
|
|
|
1231
1450
|
textValues = {},
|
|
1232
1451
|
dynamicCrop
|
|
1233
1452
|
}) {
|
|
1453
|
+
console.log("[ImageEditorComposition] ===== COMPOSITION RENDER =====");
|
|
1454
|
+
console.log("[ImageEditorComposition] Props received:", {
|
|
1455
|
+
hasConfig: !!config,
|
|
1456
|
+
hasElements: !!elements,
|
|
1457
|
+
elementCount: elements?.length ?? 0,
|
|
1458
|
+
width,
|
|
1459
|
+
height,
|
|
1460
|
+
scale,
|
|
1461
|
+
backgroundType,
|
|
1462
|
+
textValuesKeys: Object.keys(textValues)
|
|
1463
|
+
});
|
|
1234
1464
|
const canvasWidth = width ?? config?.width ?? 1080;
|
|
1235
1465
|
const canvasHeight = height ?? config?.height ?? 1920;
|
|
1466
|
+
console.log("[ImageEditorComposition] Canvas dimensions:", { canvasWidth, canvasHeight });
|
|
1236
1467
|
const resolvedElements = (0, import_react3.useMemo)(() => {
|
|
1237
1468
|
if (!elements) return null;
|
|
1238
1469
|
const result = resolveElementPositions(elements, textValues);
|
|
@@ -1958,6 +2189,7 @@ var RenderRoot = () => {
|
|
|
1958
2189
|
calculateLineWidth,
|
|
1959
2190
|
calculateTimelineContentEnd,
|
|
1960
2191
|
canSetAsReference,
|
|
2192
|
+
debugFontStatus,
|
|
1961
2193
|
defaultOffset,
|
|
1962
2194
|
formatTime,
|
|
1963
2195
|
generateOverlayId,
|
package/dist/index.mjs
CHANGED
|
@@ -105,43 +105,117 @@ var FONT_URLS = {
|
|
|
105
105
|
}
|
|
106
106
|
};
|
|
107
107
|
async function preloadFonts() {
|
|
108
|
+
console.log("[ugcinc-render/fonts] preloadFonts() called");
|
|
108
109
|
if (typeof document !== "undefined") {
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
110
|
+
console.log("[ugcinc-render/fonts] Browser environment detected, loading fonts...");
|
|
111
|
+
const fontResults = [];
|
|
112
|
+
try {
|
|
113
|
+
const tiktokRegular = new FontFace(
|
|
114
|
+
"TikTok Sans",
|
|
115
|
+
`url(${FONT_URLS.tiktok.regular})`,
|
|
116
|
+
{ weight: "normal" }
|
|
117
|
+
);
|
|
118
|
+
console.log(`[ugcinc-render/fonts] Loading TikTok Sans Regular from: ${FONT_URLS.tiktok.regular}`);
|
|
119
|
+
await tiktokRegular.load();
|
|
120
|
+
document.fonts.add(tiktokRegular);
|
|
121
|
+
fontResults.push({ name: "TikTok Sans Regular", status: "success" });
|
|
122
|
+
} catch (err) {
|
|
123
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
124
|
+
console.error(`[ugcinc-render/fonts] Failed to load TikTok Sans Regular:`, errorMsg);
|
|
125
|
+
fontResults.push({ name: "TikTok Sans Regular", status: "error", error: errorMsg });
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
const tiktokBold = new FontFace(
|
|
129
|
+
"TikTok Sans",
|
|
130
|
+
`url(${FONT_URLS.tiktok.bold})`,
|
|
131
|
+
{ weight: "bold" }
|
|
132
|
+
);
|
|
133
|
+
console.log(`[ugcinc-render/fonts] Loading TikTok Sans Bold from: ${FONT_URLS.tiktok.bold}`);
|
|
134
|
+
await tiktokBold.load();
|
|
135
|
+
document.fonts.add(tiktokBold);
|
|
136
|
+
fontResults.push({ name: "TikTok Sans Bold", status: "success" });
|
|
137
|
+
} catch (err) {
|
|
138
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
139
|
+
console.error(`[ugcinc-render/fonts] Failed to load TikTok Sans Bold:`, errorMsg);
|
|
140
|
+
fontResults.push({ name: "TikTok Sans Bold", status: "error", error: errorMsg });
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
const sfPro = new FontFace(
|
|
144
|
+
"SF Pro",
|
|
145
|
+
`url(${FONT_URLS.apple.regular})`,
|
|
146
|
+
{ weight: "normal" }
|
|
147
|
+
);
|
|
148
|
+
console.log(`[ugcinc-render/fonts] Loading SF Pro from: ${FONT_URLS.apple.regular}`);
|
|
149
|
+
await sfPro.load();
|
|
150
|
+
document.fonts.add(sfPro);
|
|
151
|
+
fontResults.push({ name: "SF Pro", status: "success" });
|
|
152
|
+
} catch (err) {
|
|
153
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
154
|
+
console.error(`[ugcinc-render/fonts] Failed to load SF Pro:`, errorMsg);
|
|
155
|
+
fontResults.push({ name: "SF Pro", status: "error", error: errorMsg });
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
const appleEmoji = new FontFace(
|
|
159
|
+
"Apple Color Emoji",
|
|
160
|
+
`url(${FONT_URLS.emoji.apple})`,
|
|
161
|
+
{ weight: "normal" }
|
|
162
|
+
);
|
|
163
|
+
console.log(`[ugcinc-render/fonts] Loading Apple Color Emoji from: ${FONT_URLS.emoji.apple}`);
|
|
164
|
+
await appleEmoji.load();
|
|
165
|
+
document.fonts.add(appleEmoji);
|
|
166
|
+
fontResults.push({ name: "Apple Color Emoji", status: "success" });
|
|
167
|
+
} catch (err) {
|
|
168
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
169
|
+
console.error(`[ugcinc-render/fonts] Failed to load Apple Color Emoji:`, errorMsg);
|
|
170
|
+
fontResults.push({ name: "Apple Color Emoji", status: "error", error: errorMsg });
|
|
171
|
+
}
|
|
172
|
+
console.log("[ugcinc-render/fonts] Font loading complete. Results:", fontResults);
|
|
173
|
+
const availableFonts = [];
|
|
174
|
+
document.fonts.forEach((font) => {
|
|
175
|
+
availableFonts.push(`${font.family} (${font.weight}, ${font.status})`);
|
|
137
176
|
});
|
|
177
|
+
console.log("[ugcinc-render/fonts] Available fonts in document:", availableFonts);
|
|
178
|
+
} else {
|
|
179
|
+
console.log("[ugcinc-render/fonts] Not in browser environment, skipping font loading");
|
|
138
180
|
}
|
|
139
181
|
}
|
|
140
182
|
function areFontsLoaded() {
|
|
141
183
|
if (typeof document === "undefined") {
|
|
184
|
+
console.log("[ugcinc-render/fonts] areFontsLoaded: Not in browser environment");
|
|
142
185
|
return false;
|
|
143
186
|
}
|
|
144
|
-
|
|
187
|
+
const tiktokRegular = document.fonts.check('normal 16px "TikTok Sans"');
|
|
188
|
+
const tiktokBold = document.fonts.check('bold 16px "TikTok Sans"');
|
|
189
|
+
const sfPro = document.fonts.check('normal 16px "SF Pro"');
|
|
190
|
+
const appleEmoji = document.fonts.check('normal 16px "Apple Color Emoji"');
|
|
191
|
+
console.log("[ugcinc-render/fonts] areFontsLoaded check:", {
|
|
192
|
+
tiktokRegular,
|
|
193
|
+
tiktokBold,
|
|
194
|
+
sfPro,
|
|
195
|
+
appleEmoji
|
|
196
|
+
});
|
|
197
|
+
return tiktokRegular && tiktokBold && sfPro && appleEmoji;
|
|
198
|
+
}
|
|
199
|
+
function debugFontStatus() {
|
|
200
|
+
console.log("[ugcinc-render/fonts] === FONT DEBUG STATUS ===");
|
|
201
|
+
if (typeof document === "undefined") {
|
|
202
|
+
console.log("[ugcinc-render/fonts] Not in browser environment");
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
console.log("[ugcinc-render/fonts] Font checks:");
|
|
206
|
+
console.log(" - TikTok Sans (normal):", document.fonts.check('normal 16px "TikTok Sans"'));
|
|
207
|
+
console.log(" - TikTok Sans (bold):", document.fonts.check('bold 16px "TikTok Sans"'));
|
|
208
|
+
console.log(" - SF Pro:", document.fonts.check('normal 16px "SF Pro"'));
|
|
209
|
+
console.log(" - Apple Color Emoji:", document.fonts.check('normal 16px "Apple Color Emoji"'));
|
|
210
|
+
console.log("[ugcinc-render/fonts] All fonts in document.fonts:");
|
|
211
|
+
document.fonts.forEach((font) => {
|
|
212
|
+
console.log(` - ${font.family}: weight=${font.weight}, style=${font.style}, status=${font.status}`);
|
|
213
|
+
});
|
|
214
|
+
console.log("[ugcinc-render/fonts] Font family stacks:");
|
|
215
|
+
console.log(" - tiktok:", FONT_FAMILIES.tiktok);
|
|
216
|
+
console.log(" - apple:", FONT_FAMILIES.apple);
|
|
217
|
+
console.log(" - arial:", FONT_FAMILIES.arial);
|
|
218
|
+
console.log("[ugcinc-render/fonts] === END FONT DEBUG ===");
|
|
145
219
|
}
|
|
146
220
|
|
|
147
221
|
// src/utils/text.ts
|
|
@@ -241,15 +315,48 @@ function calculateAutoWidthAndLines({
|
|
|
241
315
|
letterSpacing,
|
|
242
316
|
lineHeight
|
|
243
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
|
+
});
|
|
244
331
|
if (typeof document === "undefined") {
|
|
332
|
+
console.log("[TextElement/calculateAutoWidthAndLines] SSR mode - returning maxWidth");
|
|
245
333
|
return { width: maxWidth, lines: [text] };
|
|
246
334
|
}
|
|
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
|
+
}
|
|
247
352
|
const availableWidth = maxWidth - paddingLeft - paddingRight;
|
|
353
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Available width for text:", availableWidth);
|
|
248
354
|
if (availableWidth <= 0) {
|
|
355
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Available width <= 0, returning maxWidth");
|
|
249
356
|
return { width: maxWidth, lines: [text] };
|
|
250
357
|
}
|
|
251
358
|
const measureSpan = document.createElement("span");
|
|
252
|
-
|
|
359
|
+
const cssText = `
|
|
253
360
|
position: absolute;
|
|
254
361
|
visibility: hidden;
|
|
255
362
|
pointer-events: none;
|
|
@@ -259,16 +366,29 @@ function calculateAutoWidthAndLines({
|
|
|
259
366
|
letter-spacing: ${letterSpacing}px;
|
|
260
367
|
white-space: nowrap;
|
|
261
368
|
`;
|
|
369
|
+
measureSpan.style.cssText = cssText;
|
|
370
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Measurement span CSS:", cssText.replace(/\s+/g, " ").trim());
|
|
262
371
|
document.body.appendChild(measureSpan);
|
|
263
372
|
const measureText = (textToMeasure) => {
|
|
264
373
|
measureSpan.textContent = textToMeasure;
|
|
265
|
-
|
|
374
|
+
const width = measureSpan.getBoundingClientRect().width;
|
|
375
|
+
return width;
|
|
266
376
|
};
|
|
267
377
|
measureSpan.textContent = "M";
|
|
268
378
|
const charWidth = measureSpan.getBoundingClientRect().width;
|
|
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);
|
|
269
388
|
const words = text.split(/(\s+)/);
|
|
270
389
|
const lines = [];
|
|
271
390
|
let currentLine = "";
|
|
391
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Word count:", words.filter((w) => w.trim()).length);
|
|
272
392
|
for (let i = 0; i < words.length; i++) {
|
|
273
393
|
const word = words[i];
|
|
274
394
|
if (word === "\n" || word === "\r\n") {
|
|
@@ -324,15 +444,60 @@ function calculateAutoWidthAndLines({
|
|
|
324
444
|
lines.push("");
|
|
325
445
|
}
|
|
326
446
|
let widestLineWidth = 0;
|
|
447
|
+
const lineWidths = [];
|
|
327
448
|
for (const line of lines) {
|
|
328
449
|
const lineWidth = measureText(line);
|
|
450
|
+
lineWidths.push({ line: line.substring(0, 50) + (line.length > 50 ? "..." : ""), width: lineWidth });
|
|
329
451
|
widestLineWidth = Math.max(widestLineWidth, lineWidth);
|
|
330
452
|
}
|
|
453
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Line measurements:", lineWidths);
|
|
454
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Widest line width:", widestLineWidth);
|
|
331
455
|
document.body.removeChild(measureSpan);
|
|
332
456
|
const calculatedWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
|
|
457
|
+
console.log("[TextElement/calculateAutoWidthAndLines] Final calculation:", {
|
|
458
|
+
widestLineWidth,
|
|
459
|
+
paddingLeft,
|
|
460
|
+
paddingRight,
|
|
461
|
+
rawCalculatedWidth: widestLineWidth + paddingLeft + paddingRight,
|
|
462
|
+
cappedToMaxWidth: calculatedWidth,
|
|
463
|
+
maxWidth
|
|
464
|
+
});
|
|
465
|
+
console.log("[TextElement/calculateAutoWidthAndLines] ===== END CALCULATION =====");
|
|
333
466
|
return { width: calculatedWidth, lines };
|
|
334
467
|
}
|
|
335
468
|
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]);
|
|
336
501
|
const fontType = segment.fontType ?? TEXT_DEFAULTS.fontType;
|
|
337
502
|
const fontSize = (segment.fontSize ?? TEXT_DEFAULTS.fontSize) * scale;
|
|
338
503
|
const fontWeight = segment.fontWeight ?? TEXT_DEFAULTS.fontWeight;
|
|
@@ -411,7 +576,7 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
411
576
|
lineHeight
|
|
412
577
|
});
|
|
413
578
|
}
|
|
414
|
-
|
|
579
|
+
const result = {
|
|
415
580
|
calculatedWidth: autoWidth ? finalResult.width : width,
|
|
416
581
|
calculatedLines: autoWidth ? finalResult.lines : [segment.text],
|
|
417
582
|
paddingTop: finalPaddingTop,
|
|
@@ -419,6 +584,19 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
419
584
|
paddingBottom: finalPaddingBottom,
|
|
420
585
|
paddingLeft: finalPaddingLeft
|
|
421
586
|
};
|
|
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;
|
|
422
600
|
}, [
|
|
423
601
|
autoWidth,
|
|
424
602
|
segment.text,
|
|
@@ -533,11 +711,29 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
533
711
|
verticalAlign
|
|
534
712
|
]);
|
|
535
713
|
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);
|
|
536
725
|
const textContent = calculatedLines.map((line, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
537
726
|
line,
|
|
538
727
|
index < calculatedLines.length - 1 && /* @__PURE__ */ jsx("br", {})
|
|
539
728
|
] }, index));
|
|
540
729
|
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
|
+
});
|
|
541
737
|
return /* @__PURE__ */ jsx("div", { style: positioningContainerStyle, children: /* @__PURE__ */ jsx(
|
|
542
738
|
"div",
|
|
543
739
|
{
|
|
@@ -551,6 +747,7 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
551
747
|
}
|
|
552
748
|
) });
|
|
553
749
|
}
|
|
750
|
+
console.log("[TextElement/render] Rendering WITHOUT background");
|
|
554
751
|
return /* @__PURE__ */ jsx("div", { style: positioningContainerStyle, children: /* @__PURE__ */ jsx("div", { style: { width: calculatedWidth, maxWidth: width }, children: /* @__PURE__ */ jsx("div", { style: textStyle, children: textContent }) }) });
|
|
555
752
|
}
|
|
556
753
|
return /* @__PURE__ */ jsx("div", { style: positioningContainerStyle, children: /* @__PURE__ */ jsx("div", { style: backgroundBoxStyle, children: /* @__PURE__ */ jsx("div", { style: textStyle, children: segment.text }) }) });
|
|
@@ -1073,7 +1270,7 @@ function getSortedSegments(config) {
|
|
|
1073
1270
|
});
|
|
1074
1271
|
}
|
|
1075
1272
|
function elementToTextSegment(elem) {
|
|
1076
|
-
|
|
1273
|
+
const segment = {
|
|
1077
1274
|
id: elem.id,
|
|
1078
1275
|
type: "text",
|
|
1079
1276
|
source: "",
|
|
@@ -1111,6 +1308,27 @@ function elementToTextSegment(elem) {
|
|
|
1111
1308
|
autoWidth: elem.autoWidth,
|
|
1112
1309
|
boxAlign: elem.boxAlign
|
|
1113
1310
|
};
|
|
1311
|
+
console.log("[ImageEditorComposition/elementToTextSegment] ===== CONVERTING ELEMENT TO SEGMENT =====");
|
|
1312
|
+
console.log("[ImageEditorComposition/elementToTextSegment] Element ID:", elem.id);
|
|
1313
|
+
console.log("[ImageEditorComposition/elementToTextSegment] Element text:", (elem.text ?? "").substring(0, 50));
|
|
1314
|
+
console.log("[ImageEditorComposition/elementToTextSegment] Element dimensions:", { x: elem.x, y: elem.y, width: elem.width, height: elem.height });
|
|
1315
|
+
console.log("[ImageEditorComposition/elementToTextSegment] Element padding:", {
|
|
1316
|
+
paddingTop: elem.paddingTop,
|
|
1317
|
+
paddingRight: elem.paddingRight,
|
|
1318
|
+
paddingBottom: elem.paddingBottom,
|
|
1319
|
+
paddingLeft: elem.paddingLeft
|
|
1320
|
+
});
|
|
1321
|
+
console.log("[ImageEditorComposition/elementToTextSegment] Element autoWidth:", elem.autoWidth, "boxAlign:", elem.boxAlign);
|
|
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
|
+
});
|
|
1331
|
+
return segment;
|
|
1114
1332
|
}
|
|
1115
1333
|
function elementToImageSegment(elem, source) {
|
|
1116
1334
|
return {
|
|
@@ -1146,8 +1364,20 @@ function ImageEditorComposition({
|
|
|
1146
1364
|
textValues = {},
|
|
1147
1365
|
dynamicCrop
|
|
1148
1366
|
}) {
|
|
1367
|
+
console.log("[ImageEditorComposition] ===== COMPOSITION RENDER =====");
|
|
1368
|
+
console.log("[ImageEditorComposition] Props received:", {
|
|
1369
|
+
hasConfig: !!config,
|
|
1370
|
+
hasElements: !!elements,
|
|
1371
|
+
elementCount: elements?.length ?? 0,
|
|
1372
|
+
width,
|
|
1373
|
+
height,
|
|
1374
|
+
scale,
|
|
1375
|
+
backgroundType,
|
|
1376
|
+
textValuesKeys: Object.keys(textValues)
|
|
1377
|
+
});
|
|
1149
1378
|
const canvasWidth = width ?? config?.width ?? 1080;
|
|
1150
1379
|
const canvasHeight = height ?? config?.height ?? 1920;
|
|
1380
|
+
console.log("[ImageEditorComposition] Canvas dimensions:", { canvasWidth, canvasHeight });
|
|
1151
1381
|
const resolvedElements = useMemo3(() => {
|
|
1152
1382
|
if (!elements) return null;
|
|
1153
1383
|
const result = resolveElementPositions(elements, textValues);
|
|
@@ -1872,6 +2102,7 @@ export {
|
|
|
1872
2102
|
calculateLineWidth,
|
|
1873
2103
|
calculateTimelineContentEnd,
|
|
1874
2104
|
canSetAsReference,
|
|
2105
|
+
debugFontStatus,
|
|
1875
2106
|
defaultOffset,
|
|
1876
2107
|
formatTime,
|
|
1877
2108
|
generateOverlayId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ugcinc-render",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.18",
|
|
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",
|