Files
TankIC/3DTank/docs/HeadStyleTable.md

164 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HEAD Style Table
> 来源:`3dtank.com/play/static/js/unpacked/module_82347.js` + `module_63383.js`(CSS DSL)+ `module_24923.js`(ksc 样式引擎)+ `module_37036.js`(Kotlin 运行时)。
> 目标:把原版 Kotlin/JS style 函数逐块展开成具体 CSS,再 1:1 写成 Emotion style object。
## 0. 先澄清 `Sq` / `Lq`
```js
Sq = To.$_$.ld, // module_37036: ld = ie = ne("object", ...)
Lq = To.$_$.gd, // module_37036: gd = te = ne("class", ...)
```
`Sq` / `Lq` 是 **Kotlin class/object metadata**,不是 Emotion 注册。
真正的样式类:
- `d7n` = `MainScreenComponentStyle`
- `fni` = `UserInfoContainerStyle`
- `Yni` = `UserScoreComponentStyle`
- `o2n` = `HeaderCommonStyle`
样式值在 `K2n` / `X2n` / `J2n` / `Z2n` / `Q2n` / `Oti` / `Dti` / `Kti` / `Jti` 这些 DSL 函数里。
## 1. DSL 映射
| 压缩名 | 导出 | CSS |
|---|---|---|
| `Wy` | `Ho.$_$.sb` → `Pc` | `width` |
| `Vy` | `Ho.$_$.b9` → `ua` | `height` |
| `fx` | `Ho.$_$.n6` → `m_` | `background` |
| `jj` | `Ho.$_$.x6` → `Uu` | `borderBottom` |
| `B$` | `Ho.$_$.vb` → `Bc` | `zIndex` |
| `Hy` | `Ho.$_$.ia` | `new Os(t, "%")` → 百分比 |
| `Zy` | `Ho.$_$.e8` | `new Os(t, "em")` → em |
| `Knr(px)` | 本地函数 | `Zy(px / 16)` → px 转 em(16px 基准) |
| `t.gp8("x", "y")` | 原始 CSS | 直接写属性 |
## 2. 已确认的原版函数
| 原版函数 | 语义 | 展开值 |
|---|---|---|
| `Oti` | `rankIconContainer` | `width: 95px → 5.9375em`,`height: 96px → 6em`,`position: relative` |
| `Dti` | `containerRightBorder` | `border-right: 1px solid rgba(255,255,255,0.25)` |
| `Kti` | `blockLeftPanel` | `position: relative`,`width: P$().np9_1`(线上 12.5em),`z-index: 2` |
| `Jti` | `containerProgressMainScreen` | `width: 10em`,`height: 3.75em`,`margin-top: 1em` |
| `Xti` | `titleRankIcon` | `width: 4.375em`,`height: 4.375em`,`margin-left: 0 0.813em` |
| `Zti` | progress bar | `height: 0.875em`,`margin-bottom: 0.55em`,`opacity: 0.8` |
| `Qti` | xp icon | `width: 1em`,`height: 1em`,`margin-bottom: 1px` |
| `Q2n` | `buttonPlay` | `backdrop-filter: blur(1.563em)`,`width: 350px → 21.875em`,`height: 172px → 10.75em` |
| `Z2n` | `gradientBlockRight` | `linear-gradient(90deg,#000 0%,rgba(0,0,0,0) 100%)`,`width: 444px → 27.75em`,`opacity: .75`,`transform: rotate(-180deg)` |
| `x6n.tap` | HEAD premium 按钮 | `box-shadow:1px 0 0 0 rgba(255,255,255,.25)`,`width/height:96px → 6em`,`flexCenterAlignCenterColumn`,未开通 VIP 时金红径向渐变 |
| `L4.tap` | HEAD 组队按钮 | `width:95px → 5.9375em`,`height:96px → 6em`,`border-right:1px solid rgba(255,255,255,.25)`,`flexCenterAlignCenter` |
| `q4` | 2 人组成员图标 | `24px → 1.5em` 方形,绝对定位 `left/right:0; bottom:0`,`background:url(groupUser.67c9ec61.svg) center/contain no-repeat` + 成员状态色 |
| `UserGroupTitleButtonComponentStyle` | `commonUserIconsBlockGroup` | `position:relative; display:flex; justify-content:center; width:3.25em; height:1.9em` |
## 3. HEAD 组件表
| `data-ui` | 原版/线上对应 | CSS | Emotion |
|---|---|---|---|
| `head.root` | `MainScreenComponentStyle-containerPanel` | `display:flex; align-items:center; justify-content:space-between; width:100%; height:100%; position:relative; background:linear-gradient(180deg,rgba(0,25,38,.98),rgba(0,16,24,.94)); border-bottom:1px solid rgba(255,255,255,.25)` | `RootStyle` |
| `head.left` | `blockLeftPanel` | `display:flex; align-items:center; height:100%` | `LeftStyle` |
| `head.vip` | `x6n.tap`(premiumButton) | `box-shadow:1px 0 0 0 rgba(255,255,255,.25); cursor:pointer; display:flex; flex-direction:column; align-items:center; justify-content:center; position:relative; width:6em; height:6em`;未开通 VIP 时 `background:radial-gradient(100% 100% at 0% 0%, rgba(255,204,0,.75) 0%, rgba(255,38,74,.5) 50%, rgba(255,38,74,0) 100%)`,开通后 `none`;`:hover{background-color:rgba(255,255,255,.05)}` | `VipStyle(HasPremium)` |
| `head.vip.icon` | `x6n.tap` 图标 | `width:2em; height:2em; position:absolute; background-image:url(iconButtonPremium.bc17a592.svg); background-position:center; background-repeat:no-repeat; background-size:cover` | `VipIconStyle` |
| `head.exit` | 子页面 VIP → 退出键 | `width:6em; height:6em; display:flex; align-items:center; justify-content:center; border:0; box-shadow:1px 0 0 0 rgba(255,255,255,.25); background:transparent; cursor:pointer`;图标 `back.72d79619.svg`(左箭头,不是右上角的退出箭头) | `ExitStyle` |
| `head.group` | `L4.tap`(组队) | `width:5.9375em; height:6em; position:relative; border-right:1px solid rgba(255,255,255,.25); display:flex; align-items:center; justify-content:center; cursor:pointer; :hover{background-color:rgba(255,255,255,.05)}` | `GroupStyle` |
| `head.group.icons` | `UserGroupTitleButtonComponentStyle-commonUserIconsBlockGroup`(2 人组) | `position:relative; display:flex; justify-content:center; width:3.25em; height:1.9em` | `GroupIconsStyle` |
| `head.group.g1` | `q4` 左位 | `width:1.5em; height:1.5em; display:block; position:absolute; left:0; bottom:0; background-color:rgba(191,212,255,.5); background-image:url(groupUser.67c9ec61.svg); background-position:center; background-repeat:no-repeat; background-size:contain` | `GroupIconStyle("left", …)` |
| `head.group.g2` | `q4` 右位 | 同上,`right:0` | `GroupIconStyle("right", …)` |
| `head.rank` | `rankIconContainer` | `width:5.9375em; height:6em; display:flex; align-items:center; justify-content:center; border-right:1px solid rgba(255,255,255,.25); cursor:pointer` | `RankStyle` |
| `head.user` | `containerProgressMainScreen` 外层 | `display:flex; flex-direction:column; justify-content:center; min-width:10em; margin-left:1em; height:3.75em` | `UserStyle` |
| `head.user.name` | 昵称 | `font:500 1.1em/1.2 BaseFontMedium; text-shadow:0 0 .25em rgba(0,0,0,.5); white-space:nowrap; overflow:hidden; text-overflow:ellipsis` | `UserNameStyle` |
| `head.user.xp` | `xp-bar` | `width:12.5em; height:.25em; margin-top:.375em; background:rgba(118,255,51,.5); border-radius:.375em; overflow:hidden` | `XpBarStyle` |
| `head.user.xp.wrap` | `containerParameterProgress` | `display:flex; align-items:flex-start; height:.875em; margin-top:.55em; opacity:.8; white-space:nowrap` | `XpBarWrap` |
| `head.user.xp.fill` | XP 进度 | `display:block; height:100%; width:<ratio>%; background:rgb(118,255,51); border-radius:inherit` | `XpFillStyle(Ratio)` |
| `head.user.xp.text` | XP 数字 | `display:flex; align-items:center; margin-top:.35em; margin-left:.25em; font:500 1em/1 BaseFontMedium; text-shadow:0 0 .25em rgba(0,0,0,.5); color:rgb(118,255,51)` | `XpTextStyle` |
| `head.logo` | `blockForIconTankiOnline` | `position:absolute; inset:0; margin:auto; display:flex; align-items:center; justify-content:center; z-index:1; pointer-events:none`;图片 `iconTankiOnline.2a9c236f.svg`,`192×60px → 14.81em×4.63em` | `LogoStyle` |
| `head.right` | `blockRightPanel`(`Dni`) | `display:flex; justify-content:flex-end; align-items:center; align-self:center; margin-right:0; height:6em; margin-top:0; z-index:5` | `RightStyle` |
| `head.currencies` | `nti`(红宝石/水晶列) | `display:flex; flex-direction:column; position:relative`。没有 `coinsContainer` 的 `9.2em` / `margin-right:2em` / 右边框 | `CurrenciesStyle` |
| `head.currency.ruby` | `HeaderCommonStyle-icons` + `l1qd` | `display:flex; align-items:center; justify-content:flex-start; height:3em; order:1; flex-grow:1; flex-shrink:0; cursor:pointer; min-width:7.9375em; box-sizing:border-box; padding-right:.75em; border-bottom:1px solid rgba(255,255,255,.25)` | `CurrencyStyle(true, false)` |
| `head.currency.crystal` | `HeaderCommonStyle-icons` + `n1qd` | 同上,`padding-left:.75em; padding-right:.75em`,无 `border-bottom` | `CurrencyStyle(false, true)` |
| `head.currency.value` | `l1qd`/`n1qd` 的 `span` | `font:500 1.125em/1.313em BaseFontMedium; font-style:normal; text-transform:uppercase; word-spacing:.1em; margin-left:.6em; margin-right:1em`;红宝石 `color:rgb(255,102,102); margin-top:.1em`,水晶 `color:rgb(0,215,255)` | `CurrencyValueStyle(Color, MarginTop)` |
| `head.currency.ruby.icon` | `iconCoinSizeMedium` + `margin-right:0` | `width:1em; height:1em; margin-right:0` | `RubyIconStyle` |
| `head.currency.crystal.icon` | `iconCrystal` | `width:1em; height:1em; margin-left:-.78em` | `CrystalIconStyle` |
| `head.currency.plus` | `addRubyCrystal` | `width:1em; height:1em; position:absolute; right:1em` | `PlusStyle` |
| `head.fullscreen` | `uKt`(`eKt` 全屏按钮) | `display:flex; align-items:center; justify-content:center; width:6em; height:6em; padding:0; position:relative; border-left:1px solid rgba(255,255,255,.25); border-right:1px solid rgba(255,255,255,.25); background:transparent; cursor:pointer; :hover{background-color:rgba(255,255,255,.05)}` | `FullscreenStyle` |
| `head.fullscreen.icon` | `hKt().c1m0(n)` | `width:1.5em; height:1.5em; background-color:rgb(191,213,255); mask:url(fullscreen.0b4547f5.svg) center/contain no-repeat`;全屏时换 `fullscreenOff.5691cd5d.svg`;hover 变白 | `FullscreenIconStyle` |
| `head.logout` | `BreadcrumbsComponentStyle-logout`(`i1pt`) | `display:flex; align-items:center; justify-content:center; width:6em; height:6em; margin-left:0; border:0; background:transparent; cursor:pointer; :hover{background-color:rgba(255,255,255,.05)}` | `LogoutStyle` |
| `head.logout.icon` | `BreadcrumbsComponentStyle-iconLogout`(`a1n`) | `width:1.5em; height:1.5em; background-color:rgb(191,213,255); mask:url(iconBack.62869951.svg) center/contain no-repeat`;hover 变白 | `LogoutIconStyle` |
## 4. 子页面状态
`HeadContext.Page`:
- `"home"`:渲染 `head.vip`
- 其它(如 `"garage"`):渲染 `head.exit`,点击调用 `HeadContext.OnBack()`
## 5. 验收
无头探针:
```powershell
node 3DTank/tools/headless_probe.js `
--url "http://localhost:8080/?autoconnect=1&v=19" `
--out "build/probe/head-home" `
--width 1296 --height 1006 --wait 6000
```
子页面:
```powershell
node 3DTank/tools/headless_probe.js `
--url "http://localhost:8080/?autoconnect=1&v=19" `
--out "build/probe/head-garage" `
--width 1296 --height 1006 --wait 6000 `
--eval-file "3DTank/tools/probe_garage.js"
```
断言项:
- `head.root`:`1296×77.75`
- `head.left`:`408.58×77.75`
- `head.vip` / `head.exit`:`77.75×77.75`
- `head.group`:`77.94×77.75`
- `head.rank`:`77.94×77.75`
- `head.user`:`162×48.59`
- `head.currencies`:`102.86×77.75`(x=1035.64)
- `head.right`:`260.36×77.75`(x=1035.64)
- `head.fullscreen`:`79.75×77.75`
- `head.logout`:`77.75×77.75`
## 6. 已确认 / 待核对常量
已确认(`module_63383` 导出 → 函数):
| 压缩名 | 导出键 | 语义 |
|---|---|---|
| `Wy` | `sb` | `width` |
| `Vy` | `b9` | `height` |
| `R$` | `ka` | `position` |
| `A$()` | `p2` | `relative` |
| `O$()` | `l2` | `absolute` |
| `H$` | `b8` | `cursor` |
| `G$()` | `z` | `pointer` |
| `r$` | `i7` | `borderRight` |
| `jj` | `x6` | `borderBottom` |
| `J$` | `i9` | `left` |
| `L$` | `ra` | `right` |
| `D$` | `t7` | `bottom` |
| `Z$` | `db` | `top` |
| `fx` | `n6` | `background` |
| `e$` | `p6` | `backgroundColor` |
| `Wy` | `sb` | `width` |
`E9i().z1hz_1` = `rgb(255,255,255)`(`Palette.White`),`.xp6(0.05)` = `rgba(255,255,255,.05)`(`Palette.White05`)。
待核对:
- `otr().k1i9()` / `q1i7()` / `r1i7()` / `h1if()` / `h1iw()` / `c1jf()` / `g1ie()`:display / position / flex 组合
- `P$().np9_1`:线上实测 12.5em
- `E9i().b1i1_1` / `h1i4_1` / `i1i4_1`:颜色/背景
- `Enr().o1i7_1`:z-index 基准
这些是有限符号表,后续可继续展开;当前 HEAD 已按线上实测值实现。