調整牌位,還是有點怪怪的
This commit is contained in:
@@ -347,86 +347,212 @@
|
||||
let w = Number(d.width);
|
||||
let th = Number(d.textHeight) || h;
|
||||
let gap = 5; // 對應 span 的 margin-left
|
||||
let v_gap = Number(d.textSpan)
|
||||
|
||||
//let s = Number(d.fontSize);
|
||||
//let sizes = [];
|
||||
//let base_s_px = s * 1.333;
|
||||
|
||||
//// 1. 模擬排版:找出能讓全體塞入的最佳字體組合
|
||||
//while (s >= 12) {
|
||||
// let short_s_px = s * 1.333*1.1;
|
||||
// let hasShort = mid.some(n => (n.length * short_s_px) <=Number(th) + Number(d.textSpan));
|
||||
|
||||
// let long_s = hasShort ? Math.floor(s * 0.75) : s; // 長字體最多縮小 25%
|
||||
// if (long_s < 12) long_s = 12;
|
||||
// let long_s_px = long_s * 1.333*1.1;
|
||||
|
||||
// let currentColHeight = 0;
|
||||
// let totalWidth = 0;
|
||||
// let tempSizes = [];
|
||||
// let anyWrapped = false;
|
||||
// for (let i = 0; i < mid.length; i++) {
|
||||
// let name = mid[i];
|
||||
// let l = name.length;
|
||||
// //let isMulti = (l * short_s_px) > th;
|
||||
// let isShort = (l * short_s_px) <= (Number(th) + Number(d.textSpan));
|
||||
// console.log("冷涼:",name,(l * short_s_px), (Number(d.textHeight) + Number(d.textSpan)),s,isShort)
|
||||
// let size = isShort ? s : long_s;//isMulti ? long_s : s;
|
||||
// let size_px = size * (4 / 3); //isMulti ? long_s_px : short_s_px;
|
||||
// let padding = (name.length > 10) ? 5 : 0
|
||||
// let isMulti = !isShort && (l * size_px >= h - padding);
|
||||
// if (isMulti) anyWrapped = true;
|
||||
|
||||
// tempSizes.push({ name: name, size: size, isMulti: isMulti,isShort:isShort });
|
||||
|
||||
// if (isMulti) {
|
||||
// // 多行長名
|
||||
// let charsPerCol = Math.floor(h / size_px);
|
||||
// if (charsPerCol < 1) charsPerCol = 1;
|
||||
// let lines = Math.ceil(l / charsPerCol);
|
||||
// let nameW = lines * (size_px * 1.1); // 1.1倍行距
|
||||
|
||||
// if (currentColHeight > 0) currentColHeight = 0;
|
||||
// totalWidth += nameW + gap;
|
||||
// } else {
|
||||
// if (isShort) {
|
||||
// // 單行短名
|
||||
// if (currentColHeight > 0 && (currentColHeight + th + gap) <= h) {
|
||||
// currentColHeight += th + gap;
|
||||
// } else {
|
||||
// currentColHeight = th;
|
||||
// totalWidth += short_s_px + gap;
|
||||
// }
|
||||
// } else {
|
||||
// currentColHeight = 0;
|
||||
// totalWidth += size_px + gap;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (totalWidth > 0) totalWidth -= gap;
|
||||
// console.log("QQ:",name,totalWidth,w)
|
||||
// // 總寬度未爆框,確定最佳組合
|
||||
// if (totalWidth <= w) {
|
||||
// if (hasShort) {
|
||||
// sizes = tempSizes;
|
||||
// break;
|
||||
// } else {
|
||||
// if (!anyWrapped || s === 12) {
|
||||
// sizes = tempSizes;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// s -= 1;
|
||||
// console.log("計算過:",s)
|
||||
//}
|
||||
|
||||
//// 處理極端情況
|
||||
//if (sizes.length === 0) {
|
||||
// sizes = mid.map(name => {
|
||||
// return { name: name, size: 12, isMulti: (name.length * 12 * 1.333) > th };
|
||||
// });
|
||||
//}
|
||||
let s = Number(d.fontSize);
|
||||
let sizes = [];
|
||||
|
||||
// 1. 模擬排版:找出能讓全體塞入的最佳字體組合
|
||||
while (s >= 12) {
|
||||
let short_s_px = s * 1.333;
|
||||
let hasShort = mid.some(n => (n.length * short_s_px) <= th);
|
||||
|
||||
let long_s = hasShort ? Math.floor(s * 0.75) : s; // 長字體最多縮小 25%
|
||||
if (long_s < 12) long_s = 12;
|
||||
let long_s_px = long_s * 1.333;
|
||||
let h_gap = 5;
|
||||
let base_s_px = Number(d.fontSize) * 1.333;
|
||||
|
||||
let currentColHeight = 0;
|
||||
let totalWidth = 0;
|
||||
let tempSizes = [];
|
||||
let anyWrapped = false;
|
||||
for (let i = 0; i < mid.length; i++) {
|
||||
let name = mid[i];
|
||||
// 1. 保留每個名字獨立的「專屬最大字體」,3個字跟5個字的短名大小會各自獨立計算
|
||||
let items = mid.map(name => {
|
||||
let l = name.length;
|
||||
//let isMulti = (l * short_s_px) > th;
|
||||
let isShort = (l * short_s_px) <= th;
|
||||
let size = isShort ? s : long_s;//isMulti ? long_s : s;
|
||||
let size_px = size * 1.333; //isMulti ? long_s_px : short_s_px;
|
||||
let isShort = (l * base_s_px) <= (th + v_gap);
|
||||
|
||||
let isMulti = !isShort && (l * size_px >= h);
|
||||
if (isMulti) anyWrapped = true;
|
||||
let optimal_s = Math.floor((isShort ? th : h) / (l * 1.333));
|
||||
if (optimal_s > Number(d.fontSize)) optimal_s = Number(d.fontSize);
|
||||
if (optimal_s < 6) optimal_s = 6;
|
||||
|
||||
tempSizes.push({ name: name, size: size, isMulti: isMulti,isShort:isShort });
|
||||
return { name: name, l: l, isShort: isShort, optimal_s: optimal_s, size: optimal_s, isMulti: false };
|
||||
});
|
||||
|
||||
if (isMulti) {
|
||||
// 多行長名
|
||||
let charsPerCol = Math.floor(h / size_px);
|
||||
if (charsPerCol < 1) charsPerCol = 1;
|
||||
let lines = Math.ceil(l / charsPerCol);
|
||||
let nameW = lines * (size_px * 1.1); // 1.1倍行距
|
||||
let sizes = [];
|
||||
let long_ratio = 1.0;
|
||||
let short_ratio = 1.0;
|
||||
let shrink_turn = 'long';
|
||||
|
||||
if (currentColHeight > 0) currentColHeight = 0;
|
||||
totalWidth += nameW + gap;
|
||||
// 2. 動態排版與比例縮小迴圈
|
||||
while (true) {
|
||||
// 套用當前的縮小比例
|
||||
items.forEach(x => {
|
||||
let s = Math.floor(x.optimal_s * (x.isShort ? short_ratio : long_ratio));
|
||||
x.size = s < 6 ? 6 : s;
|
||||
x.isMulti = false;
|
||||
});
|
||||
|
||||
let cols = []; // 用陣列記錄每一實體欄位的寬度
|
||||
let current_col_h = 0;
|
||||
let current_col_w = 0;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let item = items[i];
|
||||
let size_px = item.size * 1.333;
|
||||
|
||||
if (item.isShort) {
|
||||
let item_h = Math.max(th, item.l * size_px);
|
||||
if (current_col_h === 0) {
|
||||
current_col_h = item_h;
|
||||
current_col_w = size_px;
|
||||
} else if (current_col_h + v_gap + item_h <= h) {
|
||||
current_col_h += v_gap + item_h;
|
||||
if (size_px > current_col_w) current_col_w = size_px;
|
||||
} else {
|
||||
if (isShort) {
|
||||
// 單行短名
|
||||
if (currentColHeight > 0 && (currentColHeight + th + gap) <= h) {
|
||||
currentColHeight += th + gap;
|
||||
} else {
|
||||
currentColHeight = th;
|
||||
totalWidth += short_s_px + gap;
|
||||
cols.push(current_col_w); // 封裝這一行
|
||||
current_col_h = item_h;
|
||||
current_col_w = size_px;
|
||||
}
|
||||
} else {
|
||||
currentColHeight = 0;
|
||||
totalWidth += size_px + gap;
|
||||
}
|
||||
}
|
||||
// 長名字必定獨佔或多佔欄位,先將前面的短名欄位封裝
|
||||
if (current_col_h > 0) {
|
||||
cols.push(current_col_w);
|
||||
current_col_h = 0;
|
||||
current_col_w = 0;
|
||||
}
|
||||
|
||||
if (totalWidth > 0) totalWidth -= gap;
|
||||
let item_w = size_px;
|
||||
if (item.l * size_px > h) {
|
||||
item.isMulti = true;
|
||||
let chars_per_col = Math.floor(h / size_px);
|
||||
if (chars_per_col < 1) chars_per_col = 1;
|
||||
let item_cols = Math.ceil(item.l / chars_per_col);
|
||||
item_w = item_cols * (size_px * 1.1);
|
||||
}
|
||||
cols.push(item_w);
|
||||
}
|
||||
}
|
||||
if (current_col_h > 0) cols.push(current_col_w);
|
||||
|
||||
// 總寬度 = 所有欄寬總和 + 欄間距
|
||||
let totalWidth = cols.reduce((a, b) => a + b, 0) + (cols.length > 1 ? (cols.length - 1) * h_gap : 0);
|
||||
|
||||
// 總寬度未爆框,確定最佳組合
|
||||
if (totalWidth <= w) {
|
||||
if (hasShort) {
|
||||
sizes = tempSizes;
|
||||
sizes = items.map(x => ({ name: x.name, size: x.size, isMulti: x.isMulti, isShort: x.isShort }));
|
||||
break;
|
||||
}
|
||||
|
||||
// 3. 寬度爆框,啟動「輪流比例縮小」
|
||||
let tryShrink = (type) => {
|
||||
let didShrink = false;
|
||||
items.forEach(x => {
|
||||
if ((type === 'long' ? !x.isShort : x.isShort) && x.size > 6) {
|
||||
// 模擬扣減 5% 後,字體是否真的有變小
|
||||
let nextRatio = (type === 'long' ? long_ratio : short_ratio) - 0.05;
|
||||
let nextSize = Math.floor(x.optimal_s * nextRatio);
|
||||
if (nextSize < x.size) didShrink = true;
|
||||
}
|
||||
});
|
||||
if (didShrink) {
|
||||
if (type === 'long') long_ratio -= 0.05;
|
||||
else short_ratio -= 0.05;
|
||||
}
|
||||
return didShrink;
|
||||
};
|
||||
|
||||
let reduced = false;
|
||||
if (shrink_turn === 'long') {
|
||||
if (tryShrink('long')) { reduced = true; shrink_turn = 'short'; }
|
||||
else if (tryShrink('short')) { reduced = true; shrink_turn = 'long'; }
|
||||
} else {
|
||||
if (!anyWrapped || s === 12) {
|
||||
sizes = tempSizes;
|
||||
if (tryShrink('short')) { reduced = true; shrink_turn = 'long'; }
|
||||
else if (tryShrink('long')) { reduced = true; shrink_turn = 'short'; }
|
||||
}
|
||||
|
||||
// 全部到達極限,強制退出
|
||||
if (!reduced) {
|
||||
sizes = items.map(x => ({ name: x.name, size: x.size, isMulti: x.isMulti, isShort: x.isShort }));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
s -= 1;
|
||||
}
|
||||
|
||||
// 處理極端情況
|
||||
// 防呆處理
|
||||
if (sizes.length === 0) {
|
||||
sizes = mid.map(name => {
|
||||
return { name: name, size: 12, isMulti: (name.length * 12 * 1.333) > th };
|
||||
return { name: name, size: 6, isMulti: false, isShort: true };
|
||||
});
|
||||
}
|
||||
|
||||
// 2. 建立外層的 Flexbox 容器
|
||||
let $namelist = $(`<div class='nameList'></div>`).css({
|
||||
"writing-mode": "vertical-rl",
|
||||
@@ -445,9 +571,8 @@
|
||||
});
|
||||
sizes.forEach(item => {
|
||||
let th = Number(d.textHeight) || Number(d.height)
|
||||
let minH = item.isShort ? `${th}px` : `${d.height}px`
|
||||
;
|
||||
let alignStyle = item.isMulti ? "start" : "justify";
|
||||
let minH = item.isShort ? `${th}px` : `${d.height}px` ;
|
||||
let alignStyle = item.isMulti || (!item.isMulti && !item.isShort) ? "start" : "justify";
|
||||
|
||||
let $span= $(`<span style="font-size: ${item.size}pt;">${item.name}</span>`).css({
|
||||
display: "block",
|
||||
@@ -480,14 +605,14 @@
|
||||
<span class="sub-text">${parts[1] || ''}</span>
|
||||
</div>`;
|
||||
} else if (d.elementID === "address") {
|
||||
newFontSize = self.scaleFontSize(mid, d.fontSize, d.width);
|
||||
newFontSize = self.scaleFontSize(address, d.fontSize, d.height);
|
||||
html = self.renderNormal(address, d)
|
||||
} else if (d.elementID === "lefttitle") {
|
||||
newFontSize = self.scaleFontSize(mid, d.fontSize, d.width);
|
||||
newFontSize = self.scaleFontSize(lefttitle, d.fontSize, d.height);
|
||||
html = self.renderNormal(lefttitle, d)
|
||||
}
|
||||
else if (d.elementID === "righttitle") {
|
||||
newFontSize = self.scaleFontSize(mid, d.fontSize, d.width);
|
||||
newFontSize = self.scaleFontSize(righttitle, d.fontSize, d.height);
|
||||
html = self.renderNormal(righttitle, d)
|
||||
}
|
||||
if (newFontSize < 10) {
|
||||
@@ -1019,15 +1144,22 @@
|
||||
|
||||
let font = this.getTextSize("講", parseInt(fontSize));
|
||||
//自動判斷縮小字型的規則,要同時縮小間距
|
||||
|
||||
//if (dStyle.elementID === 'title1') {//表示是一般正名,也就是牌位正中間的一般格式,排法是上下上下
|
||||
if ((Math.ceil(txtContent.length / 2) * font.width) * 2 > parseFloat(elementWidth)) {
|
||||
let newfontSize = parseInt(fontSize) - 1;
|
||||
// console.log("scaleFontSize:", txtContent, fontSize, elementWidth)
|
||||
if (Math.ceil(txtContent.length * fontSize * (4 / 3) * 1.1) > Number(elementWidth)) {
|
||||
let newfontSize = Number(fontSize) - 1;
|
||||
if (newfontSize <= 10) {
|
||||
return newfontSize;
|
||||
}
|
||||
return this.scaleFontSize(txtContent, newfontSize, elementWidth);
|
||||
}
|
||||
//if (dStyle.elementID === 'title1') {//表示是一般正名,也就是牌位正中間的一般格式,排法是上下上下
|
||||
//if ((Math.ceil(txtContent.length / 2) * font.width) * 2 > parseFloat(elementWidth)) {
|
||||
// let newfontSize = parseInt(fontSize) - 1;
|
||||
// if (newfontSize <= 10) {
|
||||
// return newfontSize;
|
||||
// }
|
||||
// return this.scaleFontSize(txtContent, newfontSize, elementWidth);
|
||||
//}
|
||||
return fontSize;
|
||||
},
|
||||
breakWord(txtContent, style, dStyle) {
|
||||
|
||||
Reference in New Issue
Block a user