ugcinc-render 1.5.8 → 1.5.10
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 +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +84 -11
- package/dist/index.mjs +84 -11
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -290,6 +290,10 @@ interface ImageEditorElement {
|
|
|
290
290
|
paddingRight?: number;
|
|
291
291
|
paddingBottom?: number;
|
|
292
292
|
paddingLeft?: number;
|
|
293
|
+
multiLineExtraPaddingTop?: number;
|
|
294
|
+
multiLineExtraPaddingRight?: number;
|
|
295
|
+
multiLineExtraPaddingBottom?: number;
|
|
296
|
+
multiLineExtraPaddingLeft?: number;
|
|
293
297
|
/** When true, box shrinks to fit content (width becomes max width) */
|
|
294
298
|
autoWidth?: boolean;
|
|
295
299
|
/** Which side the box anchors to when autoWidth is true */
|
|
@@ -618,6 +622,14 @@ interface TextSegment extends VisualSegment {
|
|
|
618
622
|
paddingBottom?: number;
|
|
619
623
|
/** Left padding in pixels (overrides uniform padding) */
|
|
620
624
|
paddingLeft?: number;
|
|
625
|
+
/** Extra top padding added when text has 2+ lines */
|
|
626
|
+
multiLineExtraPaddingTop?: number;
|
|
627
|
+
/** Extra right padding added when text has 2+ lines */
|
|
628
|
+
multiLineExtraPaddingRight?: number;
|
|
629
|
+
/** Extra bottom padding added when text has 2+ lines */
|
|
630
|
+
multiLineExtraPaddingBottom?: number;
|
|
631
|
+
/** Extra left padding added when text has 2+ lines */
|
|
632
|
+
multiLineExtraPaddingLeft?: number;
|
|
621
633
|
/** Font family (default: 'arial') */
|
|
622
634
|
fontType?: FontType;
|
|
623
635
|
/** Font size in pixels (default: 40) */
|
package/dist/index.d.ts
CHANGED
|
@@ -290,6 +290,10 @@ interface ImageEditorElement {
|
|
|
290
290
|
paddingRight?: number;
|
|
291
291
|
paddingBottom?: number;
|
|
292
292
|
paddingLeft?: number;
|
|
293
|
+
multiLineExtraPaddingTop?: number;
|
|
294
|
+
multiLineExtraPaddingRight?: number;
|
|
295
|
+
multiLineExtraPaddingBottom?: number;
|
|
296
|
+
multiLineExtraPaddingLeft?: number;
|
|
293
297
|
/** When true, box shrinks to fit content (width becomes max width) */
|
|
294
298
|
autoWidth?: boolean;
|
|
295
299
|
/** Which side the box anchors to when autoWidth is true */
|
|
@@ -618,6 +622,14 @@ interface TextSegment extends VisualSegment {
|
|
|
618
622
|
paddingBottom?: number;
|
|
619
623
|
/** Left padding in pixels (overrides uniform padding) */
|
|
620
624
|
paddingLeft?: number;
|
|
625
|
+
/** Extra top padding added when text has 2+ lines */
|
|
626
|
+
multiLineExtraPaddingTop?: number;
|
|
627
|
+
/** Extra right padding added when text has 2+ lines */
|
|
628
|
+
multiLineExtraPaddingRight?: number;
|
|
629
|
+
/** Extra bottom padding added when text has 2+ lines */
|
|
630
|
+
multiLineExtraPaddingBottom?: number;
|
|
631
|
+
/** Extra left padding added when text has 2+ lines */
|
|
632
|
+
multiLineExtraPaddingLeft?: number;
|
|
621
633
|
/** Font family (default: 'arial') */
|
|
622
634
|
fontType?: FontType;
|
|
623
635
|
/** Font size in pixels (default: 40) */
|
package/dist/index.js
CHANGED
|
@@ -416,10 +416,15 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
416
416
|
const strokeColor = segment.strokeColor;
|
|
417
417
|
const strokeWidth = (segment.strokeWidth ?? TEXT_DEFAULTS.strokeWidth) * scale;
|
|
418
418
|
const uniformPadding = (segment.padding ?? TEXT_DEFAULTS.padding) * scale;
|
|
419
|
-
const
|
|
420
|
-
const
|
|
421
|
-
const
|
|
422
|
-
const
|
|
419
|
+
const basePaddingTop = segment.paddingTop !== void 0 ? segment.paddingTop * scale : uniformPadding;
|
|
420
|
+
const basePaddingRight = segment.paddingRight !== void 0 ? segment.paddingRight * scale : uniformPadding;
|
|
421
|
+
const basePaddingBottom = segment.paddingBottom !== void 0 ? segment.paddingBottom * scale : uniformPadding;
|
|
422
|
+
const basePaddingLeft = segment.paddingLeft !== void 0 ? segment.paddingLeft * scale : uniformPadding;
|
|
423
|
+
const extraPaddingTop = (segment.multiLineExtraPaddingTop ?? 0) * scale;
|
|
424
|
+
const extraPaddingRight = (segment.multiLineExtraPaddingRight ?? 0) * scale;
|
|
425
|
+
const extraPaddingBottom = (segment.multiLineExtraPaddingBottom ?? 0) * scale;
|
|
426
|
+
const extraPaddingLeft = (segment.multiLineExtraPaddingLeft ?? 0) * scale;
|
|
427
|
+
const hasExtraPadding = extraPaddingTop > 0 || extraPaddingRight > 0 || extraPaddingBottom > 0 || extraPaddingLeft > 0;
|
|
423
428
|
const x = segment.xOffset * scale;
|
|
424
429
|
const y = segment.yOffset * scale;
|
|
425
430
|
const width = segment.width * scale;
|
|
@@ -431,22 +436,86 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
431
436
|
const backgroundOpacity = segment.backgroundOpacity ?? TEXT_DEFAULTS.backgroundOpacity;
|
|
432
437
|
const backgroundBorderRadius = segment.backgroundBorderRadius;
|
|
433
438
|
const fontFamily = getFontFamily(fontType);
|
|
434
|
-
const autoWidthResult = (0, import_react.useMemo)(() => {
|
|
435
|
-
if (!autoWidth)
|
|
436
|
-
|
|
439
|
+
const { autoWidthResult, isMultiLine } = (0, import_react.useMemo)(() => {
|
|
440
|
+
if (!autoWidth && !hasExtraPadding) {
|
|
441
|
+
return {
|
|
442
|
+
autoWidthResult: null,
|
|
443
|
+
isMultiLine: false
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
const result = calculateAutoWidthAndLines({
|
|
437
447
|
text: segment.text,
|
|
438
448
|
maxWidth: width,
|
|
439
|
-
paddingLeft,
|
|
440
|
-
paddingRight,
|
|
449
|
+
paddingLeft: basePaddingLeft,
|
|
450
|
+
paddingRight: basePaddingRight,
|
|
441
451
|
fontSize,
|
|
442
452
|
fontWeight,
|
|
443
453
|
fontFamily,
|
|
444
454
|
letterSpacing,
|
|
445
455
|
lineHeight
|
|
446
456
|
});
|
|
447
|
-
|
|
448
|
-
|
|
457
|
+
return {
|
|
458
|
+
autoWidthResult: autoWidth ? result : null,
|
|
459
|
+
isMultiLine: result.lines.length >= 2
|
|
460
|
+
};
|
|
461
|
+
}, [
|
|
462
|
+
autoWidth,
|
|
463
|
+
segment.text,
|
|
464
|
+
width,
|
|
465
|
+
basePaddingLeft,
|
|
466
|
+
basePaddingRight,
|
|
467
|
+
hasExtraPadding,
|
|
468
|
+
fontSize,
|
|
469
|
+
fontWeight,
|
|
470
|
+
fontFamily,
|
|
471
|
+
letterSpacing,
|
|
472
|
+
lineHeight
|
|
473
|
+
]);
|
|
449
474
|
const calculatedLines = autoWidthResult?.lines ?? [segment.text];
|
|
475
|
+
const paddingTop = basePaddingTop + (isMultiLine ? extraPaddingTop : 0);
|
|
476
|
+
const paddingRight = basePaddingRight + (isMultiLine ? extraPaddingRight : 0);
|
|
477
|
+
const paddingBottom = basePaddingBottom + (isMultiLine ? extraPaddingBottom : 0);
|
|
478
|
+
const paddingLeft = basePaddingLeft + (isMultiLine ? extraPaddingLeft : 0);
|
|
479
|
+
const calculatedWidth = (0, import_react.useMemo)(() => {
|
|
480
|
+
if (!autoWidth) return width;
|
|
481
|
+
if (!isMultiLine || extraPaddingLeft === 0 && extraPaddingRight === 0) {
|
|
482
|
+
return autoWidthResult?.width ?? width;
|
|
483
|
+
}
|
|
484
|
+
if (typeof document === "undefined") return width;
|
|
485
|
+
const measureSpan = document.createElement("span");
|
|
486
|
+
measureSpan.style.cssText = `
|
|
487
|
+
position: absolute;
|
|
488
|
+
visibility: hidden;
|
|
489
|
+
pointer-events: none;
|
|
490
|
+
font-family: ${fontFamily};
|
|
491
|
+
font-size: ${fontSize}px;
|
|
492
|
+
font-weight: ${fontWeight};
|
|
493
|
+
letter-spacing: ${letterSpacing}px;
|
|
494
|
+
white-space: nowrap;
|
|
495
|
+
`;
|
|
496
|
+
document.body.appendChild(measureSpan);
|
|
497
|
+
let widestLineWidth = 0;
|
|
498
|
+
for (const line of calculatedLines) {
|
|
499
|
+
measureSpan.textContent = line;
|
|
500
|
+
widestLineWidth = Math.max(widestLineWidth, measureSpan.getBoundingClientRect().width);
|
|
501
|
+
}
|
|
502
|
+
document.body.removeChild(measureSpan);
|
|
503
|
+
return Math.min(widestLineWidth + paddingLeft + paddingRight, width);
|
|
504
|
+
}, [
|
|
505
|
+
autoWidth,
|
|
506
|
+
autoWidthResult,
|
|
507
|
+
width,
|
|
508
|
+
isMultiLine,
|
|
509
|
+
extraPaddingLeft,
|
|
510
|
+
extraPaddingRight,
|
|
511
|
+
paddingLeft,
|
|
512
|
+
paddingRight,
|
|
513
|
+
calculatedLines,
|
|
514
|
+
fontFamily,
|
|
515
|
+
fontSize,
|
|
516
|
+
fontWeight,
|
|
517
|
+
letterSpacing
|
|
518
|
+
]);
|
|
450
519
|
const borderRadiusStyle = (0, import_react.useMemo)(() => {
|
|
451
520
|
if (!backgroundBorderRadius) return void 0;
|
|
452
521
|
const radii = getBorderRadii(backgroundBorderRadius);
|
|
@@ -1113,6 +1182,10 @@ function elementToTextSegment(elem) {
|
|
|
1113
1182
|
paddingRight: elem.paddingRight,
|
|
1114
1183
|
paddingBottom: elem.paddingBottom,
|
|
1115
1184
|
paddingLeft: elem.paddingLeft,
|
|
1185
|
+
multiLineExtraPaddingTop: elem.multiLineExtraPaddingTop,
|
|
1186
|
+
multiLineExtraPaddingRight: elem.multiLineExtraPaddingRight,
|
|
1187
|
+
multiLineExtraPaddingBottom: elem.multiLineExtraPaddingBottom,
|
|
1188
|
+
multiLineExtraPaddingLeft: elem.multiLineExtraPaddingLeft,
|
|
1116
1189
|
autoWidth: elem.autoWidth,
|
|
1117
1190
|
boxAlign: elem.boxAlign
|
|
1118
1191
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -332,10 +332,15 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
332
332
|
const strokeColor = segment.strokeColor;
|
|
333
333
|
const strokeWidth = (segment.strokeWidth ?? TEXT_DEFAULTS.strokeWidth) * scale;
|
|
334
334
|
const uniformPadding = (segment.padding ?? TEXT_DEFAULTS.padding) * scale;
|
|
335
|
-
const
|
|
336
|
-
const
|
|
337
|
-
const
|
|
338
|
-
const
|
|
335
|
+
const basePaddingTop = segment.paddingTop !== void 0 ? segment.paddingTop * scale : uniformPadding;
|
|
336
|
+
const basePaddingRight = segment.paddingRight !== void 0 ? segment.paddingRight * scale : uniformPadding;
|
|
337
|
+
const basePaddingBottom = segment.paddingBottom !== void 0 ? segment.paddingBottom * scale : uniformPadding;
|
|
338
|
+
const basePaddingLeft = segment.paddingLeft !== void 0 ? segment.paddingLeft * scale : uniformPadding;
|
|
339
|
+
const extraPaddingTop = (segment.multiLineExtraPaddingTop ?? 0) * scale;
|
|
340
|
+
const extraPaddingRight = (segment.multiLineExtraPaddingRight ?? 0) * scale;
|
|
341
|
+
const extraPaddingBottom = (segment.multiLineExtraPaddingBottom ?? 0) * scale;
|
|
342
|
+
const extraPaddingLeft = (segment.multiLineExtraPaddingLeft ?? 0) * scale;
|
|
343
|
+
const hasExtraPadding = extraPaddingTop > 0 || extraPaddingRight > 0 || extraPaddingBottom > 0 || extraPaddingLeft > 0;
|
|
339
344
|
const x = segment.xOffset * scale;
|
|
340
345
|
const y = segment.yOffset * scale;
|
|
341
346
|
const width = segment.width * scale;
|
|
@@ -347,22 +352,86 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
347
352
|
const backgroundOpacity = segment.backgroundOpacity ?? TEXT_DEFAULTS.backgroundOpacity;
|
|
348
353
|
const backgroundBorderRadius = segment.backgroundBorderRadius;
|
|
349
354
|
const fontFamily = getFontFamily(fontType);
|
|
350
|
-
const autoWidthResult = useMemo(() => {
|
|
351
|
-
if (!autoWidth)
|
|
352
|
-
|
|
355
|
+
const { autoWidthResult, isMultiLine } = useMemo(() => {
|
|
356
|
+
if (!autoWidth && !hasExtraPadding) {
|
|
357
|
+
return {
|
|
358
|
+
autoWidthResult: null,
|
|
359
|
+
isMultiLine: false
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
const result = calculateAutoWidthAndLines({
|
|
353
363
|
text: segment.text,
|
|
354
364
|
maxWidth: width,
|
|
355
|
-
paddingLeft,
|
|
356
|
-
paddingRight,
|
|
365
|
+
paddingLeft: basePaddingLeft,
|
|
366
|
+
paddingRight: basePaddingRight,
|
|
357
367
|
fontSize,
|
|
358
368
|
fontWeight,
|
|
359
369
|
fontFamily,
|
|
360
370
|
letterSpacing,
|
|
361
371
|
lineHeight
|
|
362
372
|
});
|
|
363
|
-
|
|
364
|
-
|
|
373
|
+
return {
|
|
374
|
+
autoWidthResult: autoWidth ? result : null,
|
|
375
|
+
isMultiLine: result.lines.length >= 2
|
|
376
|
+
};
|
|
377
|
+
}, [
|
|
378
|
+
autoWidth,
|
|
379
|
+
segment.text,
|
|
380
|
+
width,
|
|
381
|
+
basePaddingLeft,
|
|
382
|
+
basePaddingRight,
|
|
383
|
+
hasExtraPadding,
|
|
384
|
+
fontSize,
|
|
385
|
+
fontWeight,
|
|
386
|
+
fontFamily,
|
|
387
|
+
letterSpacing,
|
|
388
|
+
lineHeight
|
|
389
|
+
]);
|
|
365
390
|
const calculatedLines = autoWidthResult?.lines ?? [segment.text];
|
|
391
|
+
const paddingTop = basePaddingTop + (isMultiLine ? extraPaddingTop : 0);
|
|
392
|
+
const paddingRight = basePaddingRight + (isMultiLine ? extraPaddingRight : 0);
|
|
393
|
+
const paddingBottom = basePaddingBottom + (isMultiLine ? extraPaddingBottom : 0);
|
|
394
|
+
const paddingLeft = basePaddingLeft + (isMultiLine ? extraPaddingLeft : 0);
|
|
395
|
+
const calculatedWidth = useMemo(() => {
|
|
396
|
+
if (!autoWidth) return width;
|
|
397
|
+
if (!isMultiLine || extraPaddingLeft === 0 && extraPaddingRight === 0) {
|
|
398
|
+
return autoWidthResult?.width ?? width;
|
|
399
|
+
}
|
|
400
|
+
if (typeof document === "undefined") return width;
|
|
401
|
+
const measureSpan = document.createElement("span");
|
|
402
|
+
measureSpan.style.cssText = `
|
|
403
|
+
position: absolute;
|
|
404
|
+
visibility: hidden;
|
|
405
|
+
pointer-events: none;
|
|
406
|
+
font-family: ${fontFamily};
|
|
407
|
+
font-size: ${fontSize}px;
|
|
408
|
+
font-weight: ${fontWeight};
|
|
409
|
+
letter-spacing: ${letterSpacing}px;
|
|
410
|
+
white-space: nowrap;
|
|
411
|
+
`;
|
|
412
|
+
document.body.appendChild(measureSpan);
|
|
413
|
+
let widestLineWidth = 0;
|
|
414
|
+
for (const line of calculatedLines) {
|
|
415
|
+
measureSpan.textContent = line;
|
|
416
|
+
widestLineWidth = Math.max(widestLineWidth, measureSpan.getBoundingClientRect().width);
|
|
417
|
+
}
|
|
418
|
+
document.body.removeChild(measureSpan);
|
|
419
|
+
return Math.min(widestLineWidth + paddingLeft + paddingRight, width);
|
|
420
|
+
}, [
|
|
421
|
+
autoWidth,
|
|
422
|
+
autoWidthResult,
|
|
423
|
+
width,
|
|
424
|
+
isMultiLine,
|
|
425
|
+
extraPaddingLeft,
|
|
426
|
+
extraPaddingRight,
|
|
427
|
+
paddingLeft,
|
|
428
|
+
paddingRight,
|
|
429
|
+
calculatedLines,
|
|
430
|
+
fontFamily,
|
|
431
|
+
fontSize,
|
|
432
|
+
fontWeight,
|
|
433
|
+
letterSpacing
|
|
434
|
+
]);
|
|
366
435
|
const borderRadiusStyle = useMemo(() => {
|
|
367
436
|
if (!backgroundBorderRadius) return void 0;
|
|
368
437
|
const radii = getBorderRadii(backgroundBorderRadius);
|
|
@@ -1029,6 +1098,10 @@ function elementToTextSegment(elem) {
|
|
|
1029
1098
|
paddingRight: elem.paddingRight,
|
|
1030
1099
|
paddingBottom: elem.paddingBottom,
|
|
1031
1100
|
paddingLeft: elem.paddingLeft,
|
|
1101
|
+
multiLineExtraPaddingTop: elem.multiLineExtraPaddingTop,
|
|
1102
|
+
multiLineExtraPaddingRight: elem.multiLineExtraPaddingRight,
|
|
1103
|
+
multiLineExtraPaddingBottom: elem.multiLineExtraPaddingBottom,
|
|
1104
|
+
multiLineExtraPaddingLeft: elem.multiLineExtraPaddingLeft,
|
|
1032
1105
|
autoWidth: elem.autoWidth,
|
|
1033
1106
|
boxAlign: elem.boxAlign
|
|
1034
1107
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ugcinc-render",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.10",
|
|
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",
|