還是怪的

This commit is contained in:
2026-08-20 17:55:01 +08:00
parent 7c5e5ab984
commit 24de2c6071
+26 -16
View File
@@ -345,9 +345,9 @@
let h = Number(d.height);
let w = Number(d.width);
let th = Number(d.textHeight) || h;
let gap = 5; // 對應 span 的 margin-left
let v_gap = Number(d.textSpan)
//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 = [];
@@ -432,18 +432,20 @@
// });
//}
let s = Number(d.fontSize);
let th = parseFloat(d.textHeight) || Number(h);
let v_gap = parseFloat(d.textSpan) || 0; // 確保強制轉型為數字,避免字串相加錯誤
let h_gap = 5;
let base_s_px = Number(d.fontSize) * 1.333;
let base_s_px = parseFloat(d.fontSize) * 1.333;
// 1. 保留每個名字獨立的「專屬最大字體」,3個字跟5個字的短名大小會各自獨立計算
let items = mid.map(name => {
let l = name.length;
// 依據原始設定的基準大小,判定是短名還長名
let isShort = (l * base_s_px) <= (th + v_gap);
// 短名跟長名,各自依照容器 (th 或 h) 算出能放大的極限最佳字體
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 > parseFloat(d.fontSize)) optimal_s = parseFloat(d.fontSize);
if (optimal_s < 6) optimal_s = 6;
return { name: name, l: l, isShort: isShort, optimal_s: optimal_s, size: optimal_s, isMulti: false };
@@ -452,9 +454,9 @@
let sizes = [];
let long_ratio = 1.0;
let short_ratio = 1.0;
let shrink_turn = 'long';
let shrink_turn = 'long'; // 優先從長名開始縮小
// 2. 動態排版與比例縮小迴圈
// 2. 動態排版預測與比例縮小迴圈
while (true) {
// 套用當前的縮小比例
items.forEach(x => {
@@ -463,7 +465,7 @@
x.isMulti = false;
});
let cols = []; // 用陣列記錄每一實體欄位的寬度
let cols = []; // 用陣列精準記錄每一實體欄位所需的寬度
let current_col_h = 0;
let current_col_w = 0;
@@ -473,19 +475,23 @@
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 {
cols.push(current_col_w); // 封裝這一行
// 高度不足,結算舊欄位,開啟新欄位
cols.push(current_col_w);
current_col_h = item_h;
current_col_w = size_px;
}
} else {
// 長名字必定獨佔或多佔欄位,先將前面的短名欄位封裝
// 長名字必定獨佔或多佔欄位,先將前面累積的短名欄位結算封裝
if (current_col_h > 0) {
cols.push(current_col_w);
current_col_h = 0;
@@ -501,24 +507,27 @@
item_w = item_cols * (size_px * 1.1);
}
cols.push(item_w);
// 這裡 current_col_h 保持為 0,確保下一個短名字能順利開啟新欄位!
}
}
// 補上最後一個還沒結算的欄位
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) {
sizes = items.map(x => ({ name: x.name, size: x.size, isMulti: x.isMulti, isShort: x.isShort }));
break;
}
// 3. 寬度爆框,啟動「輪流比例縮小」
// 3. 若寬度爆框,啟動「輪流比例縮小」機制 (每次扣 5%)
let tryShrink = (type) => {
let didShrink = false;
items.forEach(x => {
if ((type === 'long' ? !x.isShort : x.isShort) && x.size > 6) {
// 模擬扣減 5% 後,字體是否真的有變小
// 預測扣減 5% 後,字體是否真的有變小 (Math.floor 的關係)
let nextRatio = (type === 'long' ? long_ratio : short_ratio) - 0.05;
let nextSize = Math.floor(x.optimal_s * nextRatio);
if (nextSize < x.size) didShrink = true;
@@ -532,6 +541,7 @@
};
let reduced = false;
// 依據回合狀態,輪流要求長、短名字縮小
if (shrink_turn === 'long') {
if (tryShrink('long')) { reduced = true; shrink_turn = 'short'; }
else if (tryShrink('short')) { reduced = true; shrink_turn = 'long'; }
@@ -540,7 +550,7 @@
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;