diff --git a/static/share.js b/static/share.js index c066b26..0854f0f 100644 --- a/static/share.js +++ b/static/share.js @@ -29,6 +29,54 @@ async function screenshotDOM(el, opts = {}) { const phonetic = el.querySelector(".pronun").textContent.trim(); const [types, ...defs] = [...el.querySelectorAll("ol.defs li")].map(node => node.textContent.trim()); + function charsPerLine(text, maxWidth) { + const fontSize = Math.round(width * 0.025); + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + ctx.font = `${fontSize}px Helvetica Neue, Segoe UI, Helvetica, sans-serif`; + + return Math.floor(maxWidth / (ctx.measureText(text).width / text.length)); + } + + const renderDefs = (defs, x, y) => { + let yOffset = y; + const offset = 20; + const maxLength = charsPerLine(defs[0], width - 60); + + return defs.map((def, idx) => { + if (idx > 0) { + yOffset += vOffset; + } + + let part = ''; + const parts = []; + const words = def.split(' '); + + for (const word of words) { + if ((part + ' ' + word).trim().length <= maxLength) { + part = (part + ' ' + word).trim(); + } else { + if (part) parts.push(part); + part = word; + } + } + + if (part) parts.push(part); + + return ` + ${idx + 1}. + + ${parts.map((part, idx) => { + if (idx > 0) { + yOffset += offset; + } + return `${part}` + }).join('')} + + `; + }).join(''); + } + const vOffset = 25; const svg = ` @@ -61,6 +109,10 @@ async function screenshotDOM(el, opts = {}) { font-size: ${Math.round(width * 0.025)}px; fill: #6b7280; } + + text { + white-space: pre-wrap; + } @@ -78,10 +130,7 @@ async function screenshotDOM(el, opts = {}) { ${types} - ${defs.map((def, idx) => ` - ${idx + 1}. - ${def} - `)} + ${renderDefs(defs, 24, 75)} `;