diff --git a/web/admin/print/TabletDesign.aspx b/web/admin/print/TabletDesign.aspx index b603079..7fdc846 100644 --- a/web/admin/print/TabletDesign.aspx +++ b/web/admin/print/TabletDesign.aspx @@ -1356,16 +1356,54 @@ html, body, * { else if (el.id === 'title1') { //要先去算出需要縮到多小字,根據總寬度跟行數,這樣才會在正中間 //字體大小*2如果大於行數就要縮字體 - let perRow = Math.floor(Number(el.height) / Number(el.textHeight)); - let rows = Math.ceil(Number(slice.length) / Number(perRow));//總行數 - let rowWidth = Math.floor(Number(el.width) / rows); - fontSize = Math.floor(rowWidth / 2); - //console.log(el.height, el.textHeight, perRow, rows, rowWidth, fontSize) - if (fontSize > el.style.fontSize) { - fontSize = el.style.fontSize; - rowWidth = fontSize * 2; + //let perRow = Math.floor(Number(el.height) / Number(el.textHeight)); + //let rows = Math.ceil(Number(slice.length) / Number(perRow));//總行數 + //let rowWidth = Math.floor(Number(el.width) / rows); + //fontSize = Math.floor(rowWidth / 2); + ////console.log(el.height, el.textHeight, perRow, rows, rowWidth, fontSize) + //if (fontSize > el.style.fontSize) { + // fontSize = el.style.fontSize; + // rowWidth = fontSize * 2; + //} + + + // 1. 初始化最大字體 + let s = Number(el.style.fontSize); + let h = Number(el.height); + let w = Number(el.width); + let gap = 5; // 對應 span 樣式裡的 margin-left: 5px + + // 2. 模擬所有名字的總寬度,找出不會爆框的最佳字體 + while (s >= 8) { + let s_px = s * 2; // 將 pt 轉 px + let charsPerCol = Math.floor(h / s_px); // 這個字體大小下,垂直一行最多能塞幾個字 + console.log(charsPerCol); + if (charsPerCol < 1) charsPerCol = 1; + + let totalWidth = 0; + + // 加總這批名單的真正排版寬度 + slice.forEach((name, index) => { + let cols = Math.ceil(name.length / charsPerCol); // 計算這個人需要折成幾行 + let nameWidth = cols * (s_px * 2); // 1.1 為緊密行高 (line-height) + + totalWidth += nameWidth; + if (index < slice.length - 1) { + totalWidth += gap; // 加上每個人之間的間距 + } + }); + + // 3. 如果總寬度小於等於容器寬度,代表這個字體剛好能讓所有人塞進去! + if (totalWidth <= w) { + break; + } + + s -= 1; // 放不下就縮小 1pt 繼續嘗試 } - html = this.renderNameList(slice, el, rowWidth); + + // 確保極限最小字體為 4pt + let fontSize = s < 8 ? 8 : s; + html = this.renderNameList(slice, el, 0); } else if (el.id === 'alive') { //console.log("createEl:", slice, el) @@ -1390,6 +1428,38 @@ html, body, * { }) .html(html); }, + countFontSize(name, el, baseFontSize) { + let s = Number(baseFontSize); + let h = Number(el.height); + let w = Number(el.width); + let l = Number(name.length); + + // 逐步縮小字體 (最低限制到 4pt) + while (s >= 4) { + // ★ 關鍵修正:將 pt 轉換為實際的像素(px)高度 (1pt ≈ 1.333px) + let s_px = s * 1.333; + + // 如果單行的高度夠放 + if (l * s_px <= h) { + // 如果原本的字體就放得下回傳 0,否則回傳縮小後的字體大小 + return s === Number(baseFontSize) ? 0 : s; + } + + // 單行放不下,必須折行 + let charsPerCol = Math.floor(h / s_px); // 一行(垂直)最多能塞幾個字 + if (charsPerCol < 1) charsPerCol = 1; + + let cols = Math.ceil(l / charsPerCol); // 計算總共需要折成幾行 + let neededWidth = cols * (s_px * 1.2); // 估算折行後需要的總像素寬度 (1.2為行距緩衝) + + // 若折行後的總寬度小於等於容器寬度,代表此字體大小剛好能安全放下 + if (neededWidth <= w) { + return s; + } + s -= 1; // 放不下則縮小 1pt 繼續嘗試 + } + return 8; // 極限最小字體 + }, renderNameList(names, el,rowWidth) { let $namelist = $(`
`).css({ "writing-mode": "vertical rl", @@ -1417,15 +1487,27 @@ html, body, * { renderNameSpan(name, el, rowWidth) { return $(`${name}`).css({ display: "block", - "min-height": `${el.textHeight}px`, + "min-height": `${el.textHeight}px`, // ★ 拿掉原本的 textHeight 限制,避免短字被硬撐 "max-height": `${el.height}px`, - width: `${rowWidth}px`, + width: "auto", // ★ 讓多行文字自然撐開寬度 + "line-height": "1.1", // ★ 緊密行高,讓折行的「劉三..」跟「陳五」黏緊 "text-align": "justify", "text-align-last": "justify", - "margin-left": "5px", "text-justify": "inter-character", - });// "margin-bottom": `${el.textSpan}px`, + "word-break": "break-all" + }); + //return $(`${name}`).css({ + // display: "block", + // "min-height": `${el.textHeight}px`, + // "max-height": `${el.height}px`, + // width: `${rowWidth}px`, + // "text-align": "justify", + // "text-align-last": "justify", + + // "margin-left": "5px", + // "text-justify": "inter-character", + //});// "margin-bottom": `${el.textSpan}px`, }, renderLiveList(names, el, rowWidth) { //console.log("renderLiveList:", names); @@ -1596,16 +1678,52 @@ html, body, * { let names = el.text.split('\n').filter(s => s.trim()); let slice = names.slice(0 * this.rosterLimit, (0 + 1) * this.rosterLimit); - let perRow = Math.floor(Number(el.height) / Number(el.textHeight)); - let rows = Math.ceil(Number(slice.length) / Number(perRow));//總行數 - let rowWidth = Math.floor(Number(el.width) / rows); - let fontSize = Math.floor(rowWidth / 2); - if (fontSize > el.style.fontSize) { - fontSize = el.style.fontSize; - rowWidth = fontSize * 2; + //let perRow = Math.floor(Number(el.height) / Number(el.textHeight)); + //let rows = Math.ceil(Number(slice.length) / Number(perRow));//總行數 + //let rowWidth = Math.floor(Number(el.width) / rows); + //let fontSize = Math.floor(rowWidth / 2); + //if (fontSize > el.style.fontSize) { + // fontSize = el.style.fontSize; + // rowWidth = fontSize * 2; + //} + + // 1. 初始化最大字體 + let s = Number(el.style.fontSize); + let h = Number(el.height); + let w = Number(el.width); + let gap = 5; // 對應 span 樣式裡的 margin-left: 5px + + // 2. 模擬所有名字的總寬度,找出不會爆框的最佳字體 + while (s >= 8) { + let s_px = s *2; // 將 pt 轉 px + let charsPerCol = Math.floor(h / s_px); // 這個字體大小下,垂直一行最多能塞幾個字 + if (charsPerCol < 1) charsPerCol = 1; + + let totalWidth = 0; + + // 加總這批名單的真正排版寬度 + slice.forEach((name, index) => { + let cols = Math.ceil(name.length / charsPerCol); // 計算這個人需要折成幾行 + let nameWidth = cols * (s_px * 2); // 1.1 為緊密行高 (line-height) + + totalWidth += nameWidth; + if (index < slice.length - 1) { + totalWidth += gap; // 加上每個人之間的間距 + } + }); + + // 3. 如果總寬度小於等於容器寬度,代表這個字體剛好能讓所有人塞進去! + if (totalWidth <= w) { + break; + } + + s -= 1; // 放不下就縮小 1pt 繼續嘗試 } + + // 確保極限最小字體為 4pt + let fontSize = s < 8 ? 8 : s; //console.log(el.height, el.textHeight, perRow, rows, rowWidth, fontSize) - html = this.renderNameList(slice, el, rowWidth);//el.style.fontSize + html = this.renderNameList(slice, el, 0);//el.style.fontSize $(`.tablet-element[id="${this.activeId}"]`).css({ position: "absolute", left: el.x + "mm", top: el.y + "mm", fontSize: fontSize + 'pt', fontFamily: el.style.fontFamily, "z-index": 9999, visibility: el.style.visibility }).html(html);