Files
TankIC/3DTank/docs/ShopStyleTable.md
T

292 lines
10 KiB
Markdown
Raw 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.
# Shop Style Table
> 来源:`3DTank/src/module_82347.js`(与 `3dtank.com/play/static/js/unpacked/module_82347.js` 同构)。
> 提取方法:`3DTank/tools/headless_probe.js` 加载 `module_37036` + `module_82347`,实例化样式类,执行 `dk(...)` 的 style 函数。
> Kotlin 侧:`TankiOffline/app/src/jsMain/kotlin/App/Browser/Ui/LobbyScreens.kt` 的 `ShopScreen` 及其上方 `Shop*` 样式。
## 1. 样式类
| 类 | 语义名 | 定义 | 访问器 |
|---|---|---|---|
| `$Fi` | `NewShopCommonComponentStyle` | `93477` | `e1hz` container / `b1sk` commonBlockMenuShop / `b1k7` commonContainer / `c1sj` gradient / `l1sk` containerAnnouncement |
| `zHi` | `ShopSelectedSectionComponentStyle` | `94195` | `y1qq` commonCard / `a1sp` gradientCategory / `y1so` limitedOffersCommon / `x1so` mobileCardContainer / `c1sp` scrollContainerShop / `u1ju` commonBlock / `u1sj` activeCategory / `v1sj` notifier / `k1nd` timer;参数化 `t1sj(icon, active)` |
| `MVi` | `ShopCategoryComponentStyle` | `95731` | `e1hz` container / `ri5` header / `gax` description / `t1su` bonusContainer / `v1su` bonus / `w1su` marginItemsContainer;参数化 `u1su(rec, bonus)` |
| `YVi` | `ShopCategoryOfferSectionStyle` | `95908` | `x1su` promoCodesItemsContainer / `p1st` widthSearchInput / `b1m1` containerItem / `y1su` containerCoin / `z1su` containerLimitOffers / `a1sv` containerKitOffers |
| `RKi` | `ShopFooterComponentStyle` | `96243` | `u1hz` mainContainer / `n1sw` buttonAndTextContainer / `o1sw` exclamation / `k1sw` reportButton |
| `uXi` | `ShopItemComponentStyle` | `96891` | `k1sy` 基础卡片 / `h1sy` footerContent / `h1pt` headerContainer / `j1sy` headerScroll / `y1sx` headerContent / `i1sy` containerName / `n1sy` previewContainer / `e1mb` discount / `s1ma` discountContainer 等 |
| `PZt` | `ShopBuyButtonComponentStyle` | `31920` | `u11p` root / `vck` price |
## 2. 关键 CSS
### 2.1 左侧分类菜单
`commonBlockMenuShop`(`b1sk`):
```css
display:flex; flex-direction:column; align-items:center; justify-content:flex-start;
cursor:default; background-color:rgba(3,8,13,.25); backdrop-filter:blur(.781em);
border-radius:1rem; border-right:1.25em solid transparent;
height:max-content; margin-left:2em; margin-top:2em;
max-height:calc(100% - 9.8em); z-index:2;
padding:1.25em; padding-right:0; width:25em;
```
分类项 `t1sj(icon, active)`:
```css
display:flex; align-items:center; justify-content:flex-start;
width:23.75em; height:3.5em; min-height:3.5em; max-height:3.5em;
margin:0; position:relative; overflow:hidden; cursor:pointer;
/* active */
background-color:rgba(255,204,0,.25); border-radius:.5rem; color:rgb(255,204,0);
```
图标(`div`):
```css
width:1.5em; height:1.5em; margin-right:1.25em;
background-color:white; /* active: rgb(255,204,0) + margin-left:1.25em */
mask-image:url(icon); mask-position:center; mask-repeat:no-repeat; mask-size:contain;
```
标签(`h4`):
```css
font:500 1em/1 BaseFontMedium; text-transform:uppercase;
color:white; /* active: rgb(255,204,0) */
margin:.2em 0 0;
```
### 2.2 主容器
`commonContainer`(`b1k7`):
```css
background:radial-gradient(50% 100% at 50% 100%, #203040 0%, #03080D 100%);
display:flex; align-items:stretch; justify-content:space-between;
height:100%; width:100%; max-height:calc(100% - 6em);
```
原版 `pFi.tap` 的三个子节点:左菜单、分类内容、右侧选中区。
### 2.3 分类内容
`ShopCategoryComponentStyle-container`(`e1hz`)是 `display:contents`;标题/描述/物品网格直接进入 `commonContainer`。
标题(`ri5`):
```css
font:500 1.875em/1.4em BaseFontBold; margin:1em 0 0; text-transform:uppercase;
```
描述(`gax`):
```css
opacity:.6; line-height:1.25em; font-size:.938em;
```
物品容器 `u1su(rec, bonus)`:
```css
display:flex; flex-wrap:wrap; align-items:flex-start; justify-content:flex-start;
width:37em; height:100%; gap:1em; margin-left:.25em; margin-top:.25em; /* bonus: .6em */
```
`containerItem`(`b1m1`):
```css
display:grid; grid-template-columns:50% 50%; grid-template-rows:31.35%;
gap:1em; width:37.25em; margin:2em .9em 1em .25em; padding:0 0 0 .25em;
justify-content:flex-start; align-content:flex-start; z-index:3;
```
### 2.4 物品卡片
`k1sy`:
```css
display:flex; flex-direction:column; align-items:center; justify-content:center;
position:relative; user-select:none; box-sizing:border-box; cursor:pointer;
border-radius:1rem; background-color:rgba(255,255,255,.15);
width:17.5em; height:inherit;
box-shadow:0 0 0 1px rgba(255,255,255,.3);
```
标题容器 `h1pt`:
```css
width:calc(100% - 1.5em); position:absolute; left:.75em; top:.75em;
display:flex; align-items:center; justify-content:flex-start; z-index:1;
```
标题文字 `y1sx`:
```css
font:500 1em/1 BaseFontMedium; text-transform:uppercase; color:white; margin-top:.2em;
```
价格文字 `h1sy`:
```css
font:500 1.125em/1.125 BaseFontMedium; text-transform:uppercase; margin-top:.125em;
```
预览 `n1sy`:
```css
display:flex; align-items:center; justify-content:center;
height:auto; width:auto; max-width:80%; z-index:3;
```
折扣 `e1mb`:
```css
position:absolute; right:.625em; bottom:1em;
line-height:1.333em; font-size:.938em; font-weight:bold;
```
### 2.5 底部栏
`ShopFooterComponentStyle-mainContainer`(`u1hz`):
```css
display:flex; align-items:center; justify-content:flex-start;
width:100%; height:3.125em; position:absolute; bottom:0;
border-top:.063em solid rgba(255,255,255,.1);
backdrop-filter:blur(2.688em); z-index:3;
```
`buttonAndTextContainer`(`n1sw`):
```css
width:auto; height:2.2em; margin-left:1.8em;
display:flex; align-items:center; justify-content:flex-start;
```
`exclamation`(`o1sw`):
```css
margin-left:.7em; opacity:.5;
font:400 .875em/1 BaseFontRegular;
```
### 2.6 分类卡(`ShopSelectedSectionComponentStyle-commonBlock`)
原版 `$Gi` 的 DOM:
```text
div (commonCard / limitedOffersCommon)
├─ div.cardImg (z1so) 背景图 100%×100%,background-size:cover,圆角 .625em
└─ span (b1sp) 标题,absolute,top:1em(limited: bottom:1em)
```
`commonCard`:
```css
display:flex; align-items:center; justify-content:center;
width:22.5em; height:calc(100% / 2 - 1.2em);
padding:.4em; border-radius:.625em; overflow:hidden;
position:relative; cursor:pointer;
```
`z1so`:
```css
background-color:rgba(191,213,255,.15);
background-size:cover; background-position:center; background-repeat:no-repeat;
border-radius:.625em; width:100%; height:100%; z-index:1;
```
`b1sp`:
```css
font:500 1.125em/1 BaseFontMedium; text-transform:uppercase;
position:absolute; top:1em; z-index:3;
```
离线实现:没有 `dsw_1` 分类美术 URL,保留官方 `z1so` 的背景色/尺寸/圆角,图像区域用 `stub.shop.card.art` 虚线占位;标题仍按 `b1sp` 定位。
#### 两种列布局
原版 `MGi.tap` 先渲染 `specialCategories`,再渲染 `generalCategories`:
| 类型 | 列样式 | 卡片样式 | 高度 |
|---|---|---|---|
| 普通分类(一排两行) | `w1hz`:`flex column; justify-content:space-between` | `commonCard` | `calc(100% / 2 - 1.2em)` |
| 特殊/限时(一排一行) | `f1if`:`flex column; justify-content:flex-start` | `limitedOffersCommon` | `calc(100% - .5em)` |
两种列都是 `width:22.5em; flex:0 0 22.5em; height:calc(100% - .5em); margin-right:1em`。
离线数据没有原版 `esw_1` 特殊分类标记;当前用 `KIT(套件)` 作为特殊分类演示全高卡(代码内有 `STUB` 注释)。
#### Hover 细节
| 目标 | 原版 | CSS |
|---|---|---|
| 分类卡图像 | `VGi` / `KGi` | `transform:scale(1.05,1.05); transition:all .2s ease-in-out` |
| 分类菜单项(未激活) | `pHi` / `wHi` | `box-shadow:0 0 0 2px rgb(255,255,255); border-radius:.5em; margin-left:1.25em; transition:all .1s ease-in-out` |
| 分类菜单项(激活) | `aHi` / `cHi` | `box-shadow:none` |
| 物品卡 | `TYi` | `box-shadow:0 0 0 2px rgb(255,255,255)` |
这些都已用无头探针确认生成的 CSS,例如:
```css
.css-1vz2w25:hover { transform: scale(1.05, 1.05); transition: 0.2s ease-in-out; }
.css-1owq6vw:hover { box-shadow: rgb(255, 255, 255) 0em 0em 0em 2px; }
.css-1vberae:hover { box-shadow: none; }
```
## 3. 资源
| 用途 | 资源 |
|---|---|
| 红宝石 | `ruby.ce62efbc.svg` |
| 水晶 | `crystalSmall.242e6c15.svg` |
| 金币 | `coin.3a16e831.svg` |
| 红宝石加号 | `addRuby.ff47c8be.svg` |
| 水晶加号 | `addCrystal.af9a397c.svg` |
| 金币加号 | `addCoin.cc7a25d3.svg` |
## 4. 当前实现状态
已还原:
- 先进入 `ShopSelectedSectionComponentStyle-commonBlock`:横向滚动的 22.5em 分类卡(每列 2 张,`commonCard` / `scrollContainerShop`)
- 点击分类卡后进入 `NewShopCommonComponentStyle-commonContainer`
- 左侧竖向分类菜单(25em 面板 + 23.75em × 3.5em 分类项 + 图标/激活态)
- 主容器径向渐变
- 右侧 37.25em 物品区:分类标题/描述 + 2 列物品网格
- 物品卡片(17.5em 宽,1rem 圆角,15% 白底,1px 内描边)
- 物品名称/价格/货币图标
- 底部 3.125em 栏 + `报告问题` 按钮 + 提示
未展开 / 近似:
- 分类卡背景:原版 `z1so` 使用 `dsw_1` 分类美术(服务器下发 URL),离线资源里没有;当前保留官方 `z1so` 背景色/尺寸/圆角,图像区域用 `stub.shop.card.art` 虚线占位(`STUB` 标记)
- `containerItem` 的 `grid-template-rows:31.35%` 动态行高(当前固定 `11.5em`)
- `ShopFooterComponentStyle-reportButton` 的共享 Button 完整外观(当前金色按钮近似)
- 金币 / 限时 / 礼包特殊分类(`containerCoin` / `containerLimitOffers` / `containerKitOffers`)
- 折扣/加成/促销码/能源条(当前数据模型没有这些字段)
- 分类菜单的 `(any-hover:hover)` 悬停样式(当前未加)
- 物品目录按 `Name` 去重显示(离线目录同一炮塔有多个等级条目;原版按服务器商品条目显示)
## 5. 验收
```powershell
node 3DTank/tools/headless_probe.js `
--url "http://localhost:8080/?autoconnect=1" `
--out "build/probe/shop" `
--width 1296 --height 1006 --wait 14000 `
--eval-file "C:\Users\TermiNexus\AppData\Local\Temp\opencode\goto_shop.js"
```
实测:
```text
分类卡页:22.5em 宽,每列 2 张,横向滚动
shop.menu x=36 y=104 w=328 h=452
shop.category x=805 y=104 w=483 h=...
shop.item 226.8 × 149.0(17.5em × 11.5em)
shop.footer y=966 h=40
```