fix(breakIntoLines): add word break for long words

This commit is contained in:
Ilia Mashkov
2026-01-25 11:42:05 +03:00
parent 3d11f7317d
commit 9b8ebed1c3

View File

@@ -77,6 +77,7 @@ export function createCharacterComparison(
const rect = container.getBoundingClientRect(); const rect = container.getBoundingClientRect();
containerWidth = rect.width; containerWidth = rect.width;
// Padding considerations - matches the container padding // Padding considerations - matches the container padding
const padding = window.innerWidth < 640 ? 48 : 96; const padding = window.innerWidth < 640 ? 48 : 96;
const availableWidth = rect.width - padding; const availableWidth = rect.width - padding;
@@ -132,8 +133,52 @@ export function createCharacterComparison(
currentWeight, currentWeight,
); );
const maxWidth = Math.max(widthA, widthB); const maxWidth = Math.max(widthA, widthB);
const isContainerOverflown = maxWidth > availableWidth;
if (maxWidth > availableWidth && currentLineWords.length > 0) { if (isContainerOverflown) {
if (currentLineWords.length > 0) {
pushLine(currentLineWords);
currentLineWords = [];
}
let remainingWord = word;
while (remainingWord.length > 0) {
let low = 1;
let high = remainingWord.length;
let bestBreak = 1;
// Binary Search to find the maximum characters that fit
while (low <= high) {
const mid = Math.floor((low + high) / 2);
const testFragment = remainingWord.slice(0, mid);
const wA = measureText(
ctx,
testFragment,
fontA().name,
fontSize,
currentWeight,
);
const wB = measureText(
ctx,
testFragment,
fontB().name,
fontSize,
currentWeight,
);
if (Math.max(wA, wB) <= availableWidth) {
bestBreak = mid;
low = mid + 1;
} else {
high = mid - 1;
}
}
pushLine([remainingWord.slice(0, bestBreak)]);
remainingWord = remainingWord.slice(bestBreak);
}
} else if (maxWidth > availableWidth && currentLineWords.length > 0) {
pushLine(currentLineWords); pushLine(currentLineWords);
currentLineWords = [word]; currentLineWords = [word];
} else { } else {
@@ -141,7 +186,9 @@ export function createCharacterComparison(
} }
} }
if (currentLineWords.length > 0) pushLine(currentLineWords); if (currentLineWords.length > 0) {
pushLine(currentLineWords);
}
lines = newLines; lines = newLines;
} }