ugcinc-render 1.5.2 → 1.5.3
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 +60 -20
- package/dist/index.mjs +60 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -302,28 +302,70 @@ function calculateAutoWidth({
|
|
|
302
302
|
fontSize,
|
|
303
303
|
fontWeight,
|
|
304
304
|
fontFamily,
|
|
305
|
-
letterSpacing
|
|
305
|
+
letterSpacing,
|
|
306
|
+
lineHeight
|
|
306
307
|
}) {
|
|
307
308
|
if (typeof document === "undefined") {
|
|
308
309
|
throw new Error("calculateAutoWidth requires a browser environment with document available");
|
|
309
310
|
}
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
311
|
+
const container = document.createElement("div");
|
|
312
|
+
container.style.cssText = `
|
|
313
|
+
position: absolute;
|
|
314
|
+
visibility: hidden;
|
|
315
|
+
pointer-events: none;
|
|
316
|
+
width: ${maxWidth}px;
|
|
317
|
+
padding: 0 ${paddingRight}px 0 ${paddingLeft}px;
|
|
318
|
+
box-sizing: border-box;
|
|
319
|
+
font-family: ${fontFamily};
|
|
320
|
+
font-size: ${fontSize}px;
|
|
321
|
+
font-weight: ${fontWeight};
|
|
322
|
+
letter-spacing: ${letterSpacing}px;
|
|
323
|
+
line-height: ${lineHeight};
|
|
324
|
+
white-space: pre-wrap;
|
|
325
|
+
word-break: break-word;
|
|
326
|
+
`;
|
|
327
|
+
container.textContent = text;
|
|
328
|
+
document.body.appendChild(container);
|
|
329
|
+
const totalHeight = container.offsetHeight;
|
|
330
|
+
const lineHeightPx = fontSize * lineHeight;
|
|
331
|
+
const numLines = Math.max(1, Math.round(totalHeight / lineHeightPx));
|
|
332
|
+
if (numLines === 1) {
|
|
333
|
+
const span = document.createElement("span");
|
|
334
|
+
span.style.cssText = `
|
|
335
|
+
font-family: ${fontFamily};
|
|
336
|
+
font-size: ${fontSize}px;
|
|
337
|
+
font-weight: ${fontWeight};
|
|
338
|
+
letter-spacing: ${letterSpacing}px;
|
|
339
|
+
white-space: nowrap;
|
|
340
|
+
`;
|
|
341
|
+
span.textContent = text;
|
|
342
|
+
document.body.appendChild(span);
|
|
343
|
+
const textWidth = span.offsetWidth;
|
|
344
|
+
document.body.removeChild(span);
|
|
345
|
+
document.body.removeChild(container);
|
|
346
|
+
return Math.min(textWidth + paddingLeft + paddingRight, maxWidth);
|
|
314
347
|
}
|
|
315
|
-
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
316
|
-
const availableWidth = maxWidth - paddingLeft - paddingRight;
|
|
317
348
|
const words = text.split(" ");
|
|
318
349
|
const lines = [];
|
|
319
350
|
let currentLine = "";
|
|
351
|
+
const measureSpan = document.createElement("span");
|
|
352
|
+
measureSpan.style.cssText = `
|
|
353
|
+
position: absolute;
|
|
354
|
+
visibility: hidden;
|
|
355
|
+
font-family: ${fontFamily};
|
|
356
|
+
font-size: ${fontSize}px;
|
|
357
|
+
font-weight: ${fontWeight};
|
|
358
|
+
letter-spacing: ${letterSpacing}px;
|
|
359
|
+
white-space: nowrap;
|
|
360
|
+
`;
|
|
361
|
+
document.body.appendChild(measureSpan);
|
|
362
|
+
const availableWidth = maxWidth - paddingLeft - paddingRight;
|
|
320
363
|
for (const word of words) {
|
|
321
364
|
if (!word) continue;
|
|
322
365
|
const testLine = currentLine + (currentLine ? " " : "") + word;
|
|
323
|
-
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
if (totalWidth > availableWidth && currentLine) {
|
|
366
|
+
measureSpan.textContent = testLine;
|
|
367
|
+
const testWidth = measureSpan.offsetWidth;
|
|
368
|
+
if (testWidth > availableWidth && currentLine) {
|
|
327
369
|
lines.push(currentLine);
|
|
328
370
|
currentLine = word;
|
|
329
371
|
} else {
|
|
@@ -333,14 +375,11 @@ function calculateAutoWidth({
|
|
|
333
375
|
if (currentLine) lines.push(currentLine);
|
|
334
376
|
let widestLineWidth = 0;
|
|
335
377
|
for (const line of lines) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
for (const char of chars) {
|
|
339
|
-
lineWidth += ctx.measureText(char).width + letterSpacing;
|
|
340
|
-
}
|
|
341
|
-
if (chars.length > 0) lineWidth -= letterSpacing;
|
|
342
|
-
widestLineWidth = Math.max(widestLineWidth, lineWidth);
|
|
378
|
+
measureSpan.textContent = line;
|
|
379
|
+
widestLineWidth = Math.max(widestLineWidth, measureSpan.offsetWidth);
|
|
343
380
|
}
|
|
381
|
+
document.body.removeChild(measureSpan);
|
|
382
|
+
document.body.removeChild(container);
|
|
344
383
|
return Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
|
|
345
384
|
}
|
|
346
385
|
function TextElement({ segment, scale = 1 }) {
|
|
@@ -380,9 +419,10 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
380
419
|
fontSize,
|
|
381
420
|
fontWeight,
|
|
382
421
|
fontFamily,
|
|
383
|
-
letterSpacing
|
|
422
|
+
letterSpacing,
|
|
423
|
+
lineHeight
|
|
384
424
|
});
|
|
385
|
-
}, [autoWidth, segment.text, width, paddingLeft, paddingRight, fontSize, fontWeight, fontFamily, letterSpacing]);
|
|
425
|
+
}, [autoWidth, segment.text, width, paddingLeft, paddingRight, fontSize, fontWeight, fontFamily, letterSpacing, lineHeight]);
|
|
386
426
|
const borderRadiusStyle = (0, import_react.useMemo)(() => {
|
|
387
427
|
if (!backgroundBorderRadius) return void 0;
|
|
388
428
|
const radii = getBorderRadii(backgroundBorderRadius);
|
package/dist/index.mjs
CHANGED
|
@@ -228,28 +228,70 @@ function calculateAutoWidth({
|
|
|
228
228
|
fontSize,
|
|
229
229
|
fontWeight,
|
|
230
230
|
fontFamily,
|
|
231
|
-
letterSpacing
|
|
231
|
+
letterSpacing,
|
|
232
|
+
lineHeight
|
|
232
233
|
}) {
|
|
233
234
|
if (typeof document === "undefined") {
|
|
234
235
|
throw new Error("calculateAutoWidth requires a browser environment with document available");
|
|
235
236
|
}
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
237
|
+
const container = document.createElement("div");
|
|
238
|
+
container.style.cssText = `
|
|
239
|
+
position: absolute;
|
|
240
|
+
visibility: hidden;
|
|
241
|
+
pointer-events: none;
|
|
242
|
+
width: ${maxWidth}px;
|
|
243
|
+
padding: 0 ${paddingRight}px 0 ${paddingLeft}px;
|
|
244
|
+
box-sizing: border-box;
|
|
245
|
+
font-family: ${fontFamily};
|
|
246
|
+
font-size: ${fontSize}px;
|
|
247
|
+
font-weight: ${fontWeight};
|
|
248
|
+
letter-spacing: ${letterSpacing}px;
|
|
249
|
+
line-height: ${lineHeight};
|
|
250
|
+
white-space: pre-wrap;
|
|
251
|
+
word-break: break-word;
|
|
252
|
+
`;
|
|
253
|
+
container.textContent = text;
|
|
254
|
+
document.body.appendChild(container);
|
|
255
|
+
const totalHeight = container.offsetHeight;
|
|
256
|
+
const lineHeightPx = fontSize * lineHeight;
|
|
257
|
+
const numLines = Math.max(1, Math.round(totalHeight / lineHeightPx));
|
|
258
|
+
if (numLines === 1) {
|
|
259
|
+
const span = document.createElement("span");
|
|
260
|
+
span.style.cssText = `
|
|
261
|
+
font-family: ${fontFamily};
|
|
262
|
+
font-size: ${fontSize}px;
|
|
263
|
+
font-weight: ${fontWeight};
|
|
264
|
+
letter-spacing: ${letterSpacing}px;
|
|
265
|
+
white-space: nowrap;
|
|
266
|
+
`;
|
|
267
|
+
span.textContent = text;
|
|
268
|
+
document.body.appendChild(span);
|
|
269
|
+
const textWidth = span.offsetWidth;
|
|
270
|
+
document.body.removeChild(span);
|
|
271
|
+
document.body.removeChild(container);
|
|
272
|
+
return Math.min(textWidth + paddingLeft + paddingRight, maxWidth);
|
|
240
273
|
}
|
|
241
|
-
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
242
|
-
const availableWidth = maxWidth - paddingLeft - paddingRight;
|
|
243
274
|
const words = text.split(" ");
|
|
244
275
|
const lines = [];
|
|
245
276
|
let currentLine = "";
|
|
277
|
+
const measureSpan = document.createElement("span");
|
|
278
|
+
measureSpan.style.cssText = `
|
|
279
|
+
position: absolute;
|
|
280
|
+
visibility: hidden;
|
|
281
|
+
font-family: ${fontFamily};
|
|
282
|
+
font-size: ${fontSize}px;
|
|
283
|
+
font-weight: ${fontWeight};
|
|
284
|
+
letter-spacing: ${letterSpacing}px;
|
|
285
|
+
white-space: nowrap;
|
|
286
|
+
`;
|
|
287
|
+
document.body.appendChild(measureSpan);
|
|
288
|
+
const availableWidth = maxWidth - paddingLeft - paddingRight;
|
|
246
289
|
for (const word of words) {
|
|
247
290
|
if (!word) continue;
|
|
248
291
|
const testLine = currentLine + (currentLine ? " " : "") + word;
|
|
249
|
-
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
if (totalWidth > availableWidth && currentLine) {
|
|
292
|
+
measureSpan.textContent = testLine;
|
|
293
|
+
const testWidth = measureSpan.offsetWidth;
|
|
294
|
+
if (testWidth > availableWidth && currentLine) {
|
|
253
295
|
lines.push(currentLine);
|
|
254
296
|
currentLine = word;
|
|
255
297
|
} else {
|
|
@@ -259,14 +301,11 @@ function calculateAutoWidth({
|
|
|
259
301
|
if (currentLine) lines.push(currentLine);
|
|
260
302
|
let widestLineWidth = 0;
|
|
261
303
|
for (const line of lines) {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
for (const char of chars) {
|
|
265
|
-
lineWidth += ctx.measureText(char).width + letterSpacing;
|
|
266
|
-
}
|
|
267
|
-
if (chars.length > 0) lineWidth -= letterSpacing;
|
|
268
|
-
widestLineWidth = Math.max(widestLineWidth, lineWidth);
|
|
304
|
+
measureSpan.textContent = line;
|
|
305
|
+
widestLineWidth = Math.max(widestLineWidth, measureSpan.offsetWidth);
|
|
269
306
|
}
|
|
307
|
+
document.body.removeChild(measureSpan);
|
|
308
|
+
document.body.removeChild(container);
|
|
270
309
|
return Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
|
|
271
310
|
}
|
|
272
311
|
function TextElement({ segment, scale = 1 }) {
|
|
@@ -306,9 +345,10 @@ function TextElement({ segment, scale = 1 }) {
|
|
|
306
345
|
fontSize,
|
|
307
346
|
fontWeight,
|
|
308
347
|
fontFamily,
|
|
309
|
-
letterSpacing
|
|
348
|
+
letterSpacing,
|
|
349
|
+
lineHeight
|
|
310
350
|
});
|
|
311
|
-
}, [autoWidth, segment.text, width, paddingLeft, paddingRight, fontSize, fontWeight, fontFamily, letterSpacing]);
|
|
351
|
+
}, [autoWidth, segment.text, width, paddingLeft, paddingRight, fontSize, fontWeight, fontFamily, letterSpacing, lineHeight]);
|
|
312
352
|
const borderRadiusStyle = useMemo(() => {
|
|
313
353
|
if (!backgroundBorderRadius) return void 0;
|
|
314
354
|
const radii = getBorderRadii(backgroundBorderRadius);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ugcinc-render",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
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",
|