fix(display): 实时赛况不再挤压省略 —— 单位列宽由内容算,字号把单位列一并纳入预算
主人报:大屏「实时赛况」页在两栏显示时,单位名较长、成绩较长(如 1:12.66)会被挤压显示省略号。 实测根因:**单位列宽写死**(`.boards-2 .row` 的 `60px minmax(0,1fr) 190px …`)而单位名墨迹实测 206~343px → 必然进省略态;单栏 524 vs 694、split 166 vs 437 同理。弹性宽度全给了运动员列。 更关键的是 `fitFont.ts` 的 `fitLiveRowFontPx` **只把成绩列纳入字号计算**,单位列从未进过这笔账 —— 所以字号自适应对它一直没生效。 改法: - `fitFont.ts` 新增 `LiveRowGeometry`(各版式行宽 1710/836/815、名次列、间距、单位列下限与预算)、 `liveTeamColumnPx`(按单位名墨迹定列宽,含 logo 1.28em)、`liveNameColumnPx`; `fitLiveRowFontPx` 增加 teams/teamsWithLogo 参数,按「名次+名字(≥4 汉字)+单位+成绩装得进一行」逐像素收字号; `resultTextEm` 更名 `textEm`(成绩与单位名共用同一套字符宽度表)。 - `LivePage.vue` 把单位名喂进字号计算并导出 `--team-width`,网格改用该变量。 - **取舍**:以收字号换完整显示(split 最狠 56→41px);单位列封顶 380/430/900px,超过才由单位名省略 —— **成绩与名次在任何情况下都完整**(观众最关心的先保住)。 肉眼验收(1920×1080,ReadMediaFile 逐张看过):两栏 + 10 字单位名 + 12:34.56 → 全完整,43px(改前 44px); 单栏同样全完整,88px;**对照组短单位名网格改前改后完全一致、0 省略**(常态数据零变化)。 测试:fitFont +5、live-page +1(单位列宽由内容算、网格不得再有写死单位列、必须把单位名喂进 fitFont), 并修正 2 条因网格写法变化而失真的既有断言;改前跑这些用例会红。前端 767/767、vue-tsc 通过。 未验证:真机 4K/投影观感与真实服务端数据(本次数据为接口桩)。
This commit is contained in:
1 parent
2888200045
commit
b74768b7d5
4 files changed
+331
-34
No files matched your search
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted } from 'vue'
|
||||
import { fitLiveRowFontPx, liveResultColumnPx } from '../../fitFont'
|
||||
import { fitLiveRowFontPx, liveResultColumnPx, liveTeamColumnPx } from '../../fitFont'
|
||||
import {
|
||||
LIVE_REFRESH_INTERVAL_MS,
|
||||
fallbackLiveSources,
|
||||
@@ -49,7 +49,7 @@ const emptyText = computed(() =>
|
||||
liveFeed.value === null && !liveStale.value ? '正在获取当前项目…' : '暂无进行中的项目',
|
||||
)
|
||||
|
||||
// 字号取行数最多的那一栏,两栏行高才一致;成绩列宽再反过来给字号封顶(见 fitFont.ts)。
|
||||
// 字号取行数最多的那一栏,两栏行高才一致;成绩列与单位列的宽度再反过来给字号封顶(见 fitFont.ts)。
|
||||
const rowCount = computed(() =>
|
||||
boards.value.reduce((max, board) => Math.max(max, board.rows.length), 0),
|
||||
)
|
||||
@@ -62,20 +62,37 @@ const layout = computed(() => liveBoardLayout(boards.value.length, rowCount.valu
|
||||
|
||||
// 成绩列宽与字号互相牵制,所以由页面把一屏的成绩文本收齐了一次算完:行数 → 基准字号,
|
||||
// 文本宽度 → 字号上限,字号 + 文本宽度 → 列宽。两栏各算各的会让两栏列宽不一致。
|
||||
// 单位名列同理:它和成绩抢的是同一行的宽度,长单位名(8~12 个汉字)必须在同一笔账里算,
|
||||
// 否则列宽写死、名字一长就被挤成三个点(见 fitFont.ts 的 fitLiveRowFontPx)。
|
||||
const resultTexts = computed(() =>
|
||||
boards.value.flatMap((board) => board.rows.map((row) => displayResult(row))),
|
||||
)
|
||||
const teamTexts = computed(() =>
|
||||
boards.value.flatMap((board) => board.rows.map((row) => row.shortName ?? row.teamName)),
|
||||
)
|
||||
// 有单位 logo 时单位名那一格还要多占一个 logo 宽(TeamLogo 是 1em + 0.28em 间距)。
|
||||
const teamsWithLogo = computed(() =>
|
||||
boards.value.some((board) => board.rows.some((row) => row.logoPath !== null && row.logoPath !== '')),
|
||||
)
|
||||
const rowFontPx = computed(() =>
|
||||
fitLiveRowFontPx(
|
||||
liveBlockRowCount(rowCount.value, layout.value),
|
||||
layout.value,
|
||||
resultTexts.value,
|
||||
teamTexts.value,
|
||||
teamsWithLogo.value,
|
||||
),
|
||||
)
|
||||
|
||||
const boardStyle = computed(() => ({
|
||||
'--row-font': `${rowFontPx.value}px`,
|
||||
'--rs-width': `${liveResultColumnPx(resultTexts.value, layout.value, rowFontPx.value)}px`,
|
||||
'--team-width': `${liveTeamColumnPx(
|
||||
teamTexts.value,
|
||||
layout.value,
|
||||
rowFontPx.value,
|
||||
teamsWithLogo.value,
|
||||
)}px`,
|
||||
}))
|
||||
|
||||
// 定时兜底:项目切换靠 scheduled_at 自己过期,快照不会为时间流逝推送,所以必须有这条轮询。
|
||||
@@ -219,9 +236,12 @@ h3 {
|
||||
}
|
||||
.row {
|
||||
display: grid;
|
||||
/* 成绩列宽由内容算(--rs-width,见 fitFont.ts):写死列宽时 56px 字号的 `1:09.09`
|
||||
墨迹有 201px,超出的部分会被 .rows 的 overflow:hidden 裁掉。名字列可省略号截断,先让位。 */
|
||||
grid-template-columns: 90px minmax(0, 1fr) 300px var(--rs-width, 220px);
|
||||
/* 成绩列宽与单位列宽都由内容算(--rs-width / --team-width,见 fitFont.ts):写死列宽时
|
||||
56px 字号的 `1:09.09` 墨迹有 201px、10 个汉字的单位名有 343px,超出的部分不是被
|
||||
.rows 的 overflow:hidden 裁掉,就是缩成三个点。名字列可省略号截断,先让位。 */
|
||||
grid-template-columns:
|
||||
90px minmax(0, 1fr)
|
||||
var(--team-width, 300px) var(--rs-width, 220px);
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex: 1 1 0;
|
||||
@@ -232,23 +252,33 @@ h3 {
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.07);
|
||||
animation: row-in 0.45s ease-out both;
|
||||
}
|
||||
/* 单栏满宽:名次列留足两位数(96px 字号下 `10` 的墨迹约 134px),运动员与单位各占一半弹性宽度。
|
||||
/* 单栏满宽:名次列留足两位数(96px 字号下 `10` 的墨迹约 134px),运动员与单位一起分剩余宽度。
|
||||
单位列写成 minmax(单位宽, 1fr):单位名短的时候和运动员列一样宽(观感与改前一致),长了就先吃
|
||||
自己那份、再吃运动员列的余量,不必挤别人。字号会跟着收,保证它不会收空(见 fitFont.ts)。
|
||||
行高再封顶 3.2 倍字号——行数少时(尤其只有 1 行)不把行拉满整屏高:96px 的字铺在 460px 高的行里
|
||||
四周全是空的,封顶后 1 行约占可用高度的七成,余下的高度留在面板底部。
|
||||
这两条只加在单栏版式上:两个项目时每栏的行数可能悬殊,行高拉伸与否维持原样。 */
|
||||
.boards-1 .row {
|
||||
grid-template-columns: 170px minmax(0, 1fr) minmax(0, 1fr) var(--rs-width, 220px);
|
||||
grid-template-columns:
|
||||
170px minmax(0, 1fr)
|
||||
minmax(var(--team-width, 300px), 1fr) var(--rs-width, 220px);
|
||||
gap: 18px;
|
||||
max-height: calc(var(--row-font, 34px) * 3.2);
|
||||
}
|
||||
/* 拆成两块后每块只剩半屏宽:名次列窄一档但必须装得下两位数(56px 字号下 `10` 约 78px),
|
||||
运动员列分到的宽度比单位多一半,4 个汉字的名字才不会被省略号截掉(实测 4 字名 @56px 约 224px)。 */
|
||||
运动员列分到的宽度比单位多一半(1.5fr : 1fr,与 fitFont.ts 的 nameFr/teamFr 一致),
|
||||
单位列同样保底内容宽,长单位名不再被截成三个点。 */
|
||||
.boards-1 .rows.split .row {
|
||||
grid-template-columns: 88px minmax(0, 1.5fr) minmax(0, 1fr) var(--rs-width, 150px);
|
||||
grid-template-columns:
|
||||
88px minmax(0, 1.5fr)
|
||||
minmax(var(--team-width, 150px), 1fr) var(--rs-width, 150px);
|
||||
}
|
||||
.boards-2 .row {
|
||||
/* 两栏时名次 / 单位也窄一档,成绩列同样跟着内容走。 */
|
||||
grid-template-columns: 60px minmax(0, 1fr) 190px var(--rs-width, 150px);
|
||||
/* 两栏时名次也窄一档;成绩列与单位列都跟着内容走,剩下的宽度全给运动员列——
|
||||
半屏里两列(运动员 / 单位)再互相比份额,行数一多就两边都不够。 */
|
||||
grid-template-columns:
|
||||
60px minmax(0, 1fr)
|
||||
var(--team-width, 190px) var(--rs-width, 150px);
|
||||
gap: 8px;
|
||||
}
|
||||
.row:last-child {
|
||||
|
||||
Reference in new issue
Block a user