| const MAX_TEXT_WIDTH = 950; |
| const MAX_FONT_SIZE = 80; |
| const MIN_SINGLE_LINE_SIZE = 65; |
|
|
| function slugifyTitle(title) { |
| if (!title || typeof title !== "string") return "video"; |
| return title.normalize("NFKD").replace(/[^\w\s]/g, "").replace(/\s+/g, "").substring(0, 50) || "video"; |
| } |
|
|
| function optimizeTextLayout(rawText) { |
| const text = rawText.trim(); |
| const charCount = text.length; |
| const CHAR_WIDTH_FACTOR = 0.55; |
| const estimatedWidthMax = charCount * MAX_FONT_SIZE * CHAR_WIDTH_FACTOR; |
| |
| |
| if (estimatedWidthMax <= MAX_TEXT_WIDTH) return { lines: [text], fontSize: MAX_FONT_SIZE }; |
| |
| |
| const requiredFontSize = MAX_TEXT_WIDTH / (charCount * CHAR_WIDTH_FACTOR); |
| if (requiredFontSize >= MIN_SINGLE_LINE_SIZE) return { lines: [text], fontSize: Math.floor(requiredFontSize) }; |
| |
| |
| const words = text.split(" "); |
| let splitIndex = Math.ceil(words.length / 2); |
| |
| |
| let currentCount = 0; |
| const totalChars = text.length; |
| for(let i=0; i<words.length; i++) { |
| currentCount += words[i].length; |
| if (currentCount >= totalChars / 2) { splitIndex = i + 1; break; } |
| } |
| if (splitIndex === 0 || splitIndex === words.length) splitIndex = Math.ceil(words.length / 2); |
| |
| const line1 = words.slice(0, splitIndex).join(" "); |
| const line2 = words.slice(splitIndex).join(" "); |
| |
| |
| const longestLineChars = Math.max(line1.length, line2.length); |
| let doubleLineFontSize = MAX_TEXT_WIDTH / (longestLineChars * CHAR_WIDTH_FACTOR); |
| |
| |
| if (doubleLineFontSize > MAX_FONT_SIZE) doubleLineFontSize = MAX_FONT_SIZE; |
| |
| |
| if (doubleLineFontSize < 40) doubleLineFontSize = 40; |
| |
| return { lines: [line1, line2], fontSize: Math.floor(doubleLineFontSize) }; |
| } |
|
|
| module.exports = { slugifyTitle, optimizeTextLayout }; |