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