牌位版型調整

This commit is contained in:
2026-07-31 14:45:08 +08:00
parent 4b9448d548
commit 7f1e7dd419
3 changed files with 319 additions and 168 deletions
+102 -43
View File
@@ -588,20 +588,21 @@
// newFontSize = d.fontSize;
// rowWidth = newFontSize * 2;
//}
let th = Number(d.textHeight) || 0;
let span = Number(d.textSpan) || 0;
let h = Number(d.height);
let w = Number(d.width);
//let th = Number(d.textHeight) || 0;
//let span = Number(d.textSpan) || 0;
//let h = Number(d.height);
//let w = Number(d.width);
let namesPerCol = Math.floor((h + span) / (th + span));
if (namesPerCol < 1) namesPerCol = 1;
//let namesPerCol = Math.floor((h + span) / (th + span));
//if (namesPerCol < 1) namesPerCol = 1;
// 2. 計算總共會產生幾列 (cols),並推算出每個名字能分配到的最大欄寬
let cols = Math.ceil(left.length / namesPerCol);
if (cols < 1) cols = 1;
let colWidth = Math.floor(w / cols);
//// 2. 計算總共會產生幾列 (cols),並推算出每個名字能分配到的最大欄寬
//let cols = Math.ceil(left.length / namesPerCol);
//if (cols < 1) cols = 1;
//let colWidth = Math.floor(w / cols);
html = self.renderLiveList(left, d, colWidth);
html = self.renderLiveList(left, d);
//newFontSize = d.fontSize;
} else if (d.elementID === "titletriangle") {
@@ -986,6 +987,21 @@
fix2(val) {
return Number.parseFloat(val).toFixed(2);
},
countFontSize(name, el, fontSize, rows) {
if (Number(name.length) * 2 * Number(fontSize) > el.height) {
fontSize = Number(fontSize) - 2;
rows = rows + 1;
let rowWidth = Math.floor(Number(el.width) / rows);
fontSize = Math.floor(rowWidth / 2);
// 取得遞迴後最終適合的字體大小
let finalSize = this.countFontSize(name, el, fontSize, rows);
// 若遞迴底層回傳 0 (代表沒再超過高度),則回傳當下計算出的 fontSize
return finalSize === 0 ? fontSize : finalSize;
}
return 0; // 若原本就沒超過高度,回傳 0 表示不需要縮放
},
calcIndividualFontSize(name, el, maxW) {
let s = Number(el.style ? el.style.fontSize : (el.fontSize ? el.fontSize : 18));
let maxH = Number(el.textHeight); // 限制在單一名字預設的區塊高度內
@@ -1015,51 +1031,94 @@
}
return 12; // 極限最小字體
},
renderLiveList(names, el,rowWidth) {
renderLiveList(names, el) {
//let $namelist = $(`<div class='liveList'></div>`).css({
// "writing-mode": "vertical rl",
// display: "flex",
// "flex-direction": "row",
// "flex-wrap": "wrap",
// margin: "auto",
// width: `${el.width}px`,
// height: `${el.height}px`,
// border: "0px solid #ccc",
// padding: "1px",
// "font-family": el.fontFamily,
// //"letter-spacing": "0.1em",
// "column-gap": `${el.textSpan}px`,
// //"row-gap": "1px",
// "align-items": "center",
//});
//let self = this;
//names.forEach(n => {
// $namelist.append(self.renderLiveSpan(n, el,rowWidth))
//})
let h = Number(el.height);
let w = Number(el.width);
let th = Number(el.textHeight) || h;
// 1. 單純計算總共有幾行 (列)
let namesPerCol = Math.floor(h / th);
if (namesPerCol < 1) namesPerCol = 1;
let cols = Math.ceil(names.length / namesPerCol); // 總行數
// 2. 根據行數,縮小字體直到總寬度放得下
let s = Number(el.fontSize);
while (s >= 4) {
let s_px = s * (4 / 3); // pt 轉 px
let lh = 1.1; // 行高
let gap = 0; // 對應 span 的 margin-left
// 總寬度 = 總行數 * (單行像素寬度 + 間距)
let totalWidth = cols * (s_px * lh + gap);
// 放得下就停止縮小
if (totalWidth <= w) {
break;
}
s -= 1;
}
if (s < 4) s = 4;
// 3. 建立外層 Flexbox 容器
let $namelist = $(`<div class='liveList'></div>`).css({
"writing-mode": "vertical rl",
"writing-mode": "vertical-rl",
display: "flex",
"flex-direction": "row",
"flex-wrap": "wrap",
margin: "auto",
width: `${el.width}px`,
height: `${el.height}px`,
border: "0px solid #ccc",
padding: "1px",
"font-family": el.fontFamily,
//"letter-spacing": "0.1em",
"column-gap": `${el.textSpan}px`,
//"row-gap": "1px",
"align-content": "center",
"align-items": "center",
margin: "auto",
width: `${w}px`,
height: `${h}px`,
border: "0px solid #ccc",
padding: "0px",
"font-family": el.fontFamily,
"column-gap": `${el.textSpan}px`,
});
let self = this;
names.forEach(n => {
$namelist.append(self.renderLiveSpan(n, el,rowWidth))
})
names.forEach(name => {
$namelist.append(self.renderLiveSpan(name, el, s));
});
return $namelist;
},
renderLiveSpan(name, el, colWidth) {
// 為「這個名字」獨立計算出專屬的最完美字體大小
let indSize = this.calcIndividualFontSize(name, el, colWidth);
// 2. 判斷是否發生了折行 (名字長度 * 單字像素高度 > 分配到的最大高度)
let s_px = indSize * 1.333;
let isMultiLine = (name.length * s_px) > Number(el.textHeight);
renderLiveSpan(name, el, fontSize) {
let th = Number(el.textHeight) || Number(el.height);
// 3. 根據是否折行動態決定對齊方式
// 單行:分散對齊 (justify) / 多行:置中對齊 (center) 或是改為 靠上對齊 (start)
let alignStyle = isMultiLine ? "start" : "justify";
return $(`<span style="font-size: ${indSize}pt;">${name}</span>`).css({
return $(`<span style="font-size: ${fontSize}pt;">${name}</span>`).css({
display: "block",
"min-height": `${el.textHeight}px`,
"min-height": `${th}px`, // ★ 固定分配高度,交給 Flexbox 自動排版
"max-height": `${el.height}px`,
width: "auto",
"line-height": "1.1",
"text-align": alignStyle, // ★ 動態套用對齊方式
"text-align-last": alignStyle, // ★ 動態套用最後一行對齊方式
"margin-left": "5px",
width: `${fontSize*1.33}`,
//"line-height": "1.1",
"text-align": "justify", // 統一分散對齊
"text-align-last": "justify",
//"margin-left": "5px",
"text-justify": "inter-character",
"word-break": "break-all"
"word-break": "break-all",
"white-space": "pre-line"
});
//return $(`<span class="liveSpan">${name}</span>`).css({
// display: "block",