From d6e7f477be550308f668a79cd8124ea811bd88f2 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 26 Oct 2026 21:18:23 +0800 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=E6=8C=89=E5=8E=9F=E7=89=88=E5=B1=95?= =?UTF-8?q?=E5=BC=80=20HEAD=20=E7=9A=84=20VIP=20=E4=B8=8E=E7=BB=84?= =?UTF-8?q?=E9=98=9F=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3DTank/docs/ColorPalette.md | 13 ++ 3DTank/docs/HeadStyleTable.md | 56 +++++-- 3DTank/docs/UI_Rebuild_Plan.md | 6 +- 3DTank/docs/UiTranslationStatus.md | 1 + .../kotlin/App/Browser/Ui/HeadScreen.kt | 139 +++++++++++------- .../jsMain/kotlin/App/Browser/Ui/Palette.kt | 6 + 6 files changed, 157 insertions(+), 64 deletions(-) diff --git a/3DTank/docs/ColorPalette.md b/3DTank/docs/ColorPalette.md index 41f5257..d991c4c 100644 --- a/3DTank/docs/ColorPalette.md +++ b/3DTank/docs/ColorPalette.md @@ -53,6 +53,19 @@ | `t1i1_1` | `linear-gradient(135deg, #16B9FF 0%, rgba(22,185,255,0) 84.37%)` | 蓝色渐变 | | `u1i1_1` | `linear-gradient(225deg, #BFFF56 0%, rgba(191,255,86,0) 59.26%)` | 绿色渐变 | +## 组队成员状态色 + +> 来源:`module_82347` 的 `p4`(`w4()` 单例),与 `C9i` 主题分开。 + +| 原字段 | 值 | 用途 | +|---|---|---| +| `x1ih_1` | `rgba(191,212,255,0.5)` | 空位 / 离线成员(`#BFD4FF` @ 0.5) | +| `y1ih_1` | `rgb(255,204,0)` | 自己(VIP) | +| `z1ih_1` | `rgb(118,255,51)` | 自己 / 在线成员 | +| `a1ii_1` | `rgb(0,212,255)` | 好友 | + +Kotlin 侧:`Palette.GroupMemberOffline` / `GroupMemberSelfPremium` / `GroupMemberOnline` / `GroupMemberFriend`。 + ## 使用规则 - 子页面根背景:`Palette.PageGradient` diff --git a/3DTank/docs/HeadStyleTable.md b/3DTank/docs/HeadStyleTable.md index 8f73fd6..ce5b987 100644 --- a/3DTank/docs/HeadStyleTable.md +++ b/3DTank/docs/HeadStyleTable.md @@ -48,6 +48,10 @@ Lq = To.$_$.gd, // module_37036: gd = te = ne("class", ...) | `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 组件表 @@ -55,25 +59,29 @@ Lq = To.$_$.gd, // module_37036: gd = te = ne("class", ...) |---|---|---|---| | `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` | 主页 VIP 区 | `width:6em; height:6em; display:flex; align-items:center; justify-content:center; position:relative; cursor:pointer; 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%)`;off:`opacity:.55; filter:grayscale(.3)` | `VipStyle(On)` | +| `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` | 组队区 | `width:6em; height:6em; display:flex; align-items:center; justify-content:center; position:relative; border-left:1px solid rgba(255,255,255,.25); cursor:pointer` | `GroupStyle(Active)` | -| `head.group.g1` | 组队图标左半 | `position:absolute; top:50%; left:50%; width:1.5em; height:1.5em; margin-top:-.75em; margin-left:-.75em; background:rgba(191,212,255,.5); mask:url(groupUser.svg) center/contain no-repeat; transform:translateX(-.8em)` | `GroupIconStyle("-0.8em")` | -| `head.group.g2` | 组队图标右半 | 同上,`translateX(.8em)` | `GroupIconStyle("0.8em")` | +| `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:%; background:rgba(118,255,51,.8); border-radius:inherit` | `XpFillStyle(Ratio)` | +| `head.user.xp.fill` | XP 进度 | `display:block; height:100%; width:%; 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` | `display:flex; align-items:center; height:100%; z-index:5` | `RightStyle` | | `head.currencies` | `coinsContainer` | `display:flex; flex-direction:column; justify-content:center; height:100%; width:9.2em; box-sizing:border-box; border-right:1px solid rgba(255,255,255,.25); margin-right:2em` | `CurrenciesStyle` | | `head.currency.ruby` | 红宝石 | `position:relative; display:flex; align-items:center; gap:.4em; width:100%; height:3em; padding:0 .75em 0 .6em; box-sizing:border-box; cursor:pointer; border-bottom:1px solid rgba(255,255,255,.25)` | `CurrencyStyle(true)` | | `head.currency.crystal` | 水晶 | 同上,无 `border-bottom` | `CurrencyStyle(false)` | -| `head.fullscreen` | F11 | `display:flex; align-items:center; justify-content:center; gap:.3em; width:6em; height:6em; border-left:1px solid rgba(255,255,255,.25); cursor:pointer` | `FullscreenStyle` | -| `head.logout` | 退出 | `display:flex; align-items:center; justify-content:center; width:6em; height:6em; border:0; border-left:1px solid rgba(255,255,255,.25); background:transparent; cursor:pointer` | `LogoutStyle` | +| `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. 子页面状态 @@ -106,18 +114,44 @@ node 3DTank/tools/headless_probe.js ` 断言项: - `head.root`:`1296×77.75` +- `head.left`:`408.58×77.75` - `head.vip` / `head.exit`:`77.75×77.75` -- `head.group`:`77.75×77.75` -- `head.rank`:`77.75×77.75` +- `head.group`:`77.94×77.75` +- `head.rank`:`77.94×77.75` - `head.user`:`162×48.59` - `head.currencies`:`119.22×77.75` - `head.fullscreen` / `head.logout`:`77.75×77.75` -## 6. 待核对常量 +## 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().z1hz_1` / `b1i1_1` / `h1i4_1` / `i1i4_1`:颜色/背景 +- `E9i().b1i1_1` / `h1i4_1` / `i1i4_1`:颜色/背景 - `Enr().o1i7_1`:z-index 基准 这些是有限符号表,后续可继续展开;当前 HEAD 已按线上实测值实现。 diff --git a/3DTank/docs/UI_Rebuild_Plan.md b/3DTank/docs/UI_Rebuild_Plan.md index 106f9e0..c18b845 100644 --- a/3DTank/docs/UI_Rebuild_Plan.md +++ b/3DTank/docs/UI_Rebuild_Plan.md @@ -469,4 +469,8 @@ HEAD 已按第 10 节方法重写: - XP 容器:`.875em` 高,`margin-top:.55em`,`opacity:.8` - XP 条:`12.5em × .25em`,绿色 50% 背景 - 货币列:`9.2em` 宽,`margin-right:2em` -- 实测 rect:左块 `409×77.75`、用户 `162×48.59`、右块从 `994` 开始,与计划 9.1 基本一致。 +- VIP 块(`x6n.tap`):`6em × 6em`,`box-shadow:1px 0 0 0 rgba(255,255,255,.25)`,未开通 VIP 时金红径向渐变,`:hover` 5% 白;图标 `iconButtonPremium.bc17a592.svg`,`2em × 2em` +- 组队块(`L4.tap`):`5.9375em × 6em`,右边框,`:hover` 5% 白;2 人组 `commonUserIconsBlockGroup` `3.25em × 1.9em` + 两个 `q4` 图标 `1.5em`(`groupUser.67c9ec61.svg`,空位色 `rgba(191,212,255,.5)`) +- 全屏块(`uKt`):`6em × 6em`,左右各 1px 白 25% 边框,`:hover` 5% 白 + 图标变白;图标 `fullscreen.0b4547f5.svg`,`1.5em` +- 退出块(`BreadcrumbsComponentStyle-logout`):`6em × 6em`,无边框,`:hover` 5% 白 + 图标变白;图标 `iconBack.62869951.svg`,`1.5em` +- 实测 rect:左块 `408.58×77.75`、VIP `77.75×77.75`、组队/等级 `77.94×77.75`、用户 `162×48.59`、右块从 `994` 开始,与计划 9.1 基本一致。 diff --git a/3DTank/docs/UiTranslationStatus.md b/3DTank/docs/UiTranslationStatus.md index 61aea61..3400712 100644 --- a/3DTank/docs/UiTranslationStatus.md +++ b/3DTank/docs/UiTranslationStatus.md @@ -50,6 +50,7 @@ | 3D 坦克模型 | `Item3DCC.Resource` | 资源 URL 索引未打通;当前用官方预览图/图标占位 | | 真实迷彩预览 | `Item3DCC.Resource` | 迷彩资源 URL 未打通;车库用色块、商店用色块渐变占位 | | 军团/好友真实数据 | `RootState` | 已接状态与列表;真实服务器数据下会替换离线示例 | +| HEAD 组队 3/4 人分支 | `module_82347` `UserGroupTitleButtonComponentStyle-commonBlockGroup` | 2 人组(默认上限)已按 `q4` + `groupUser.svg` 还原;3/4 人组的等级小图标分支未接组队数据 | ## 说明 diff --git a/TankiOffline/app/src/jsMain/kotlin/App/Browser/Ui/HeadScreen.kt b/TankiOffline/app/src/jsMain/kotlin/App/Browser/Ui/HeadScreen.kt index 2070c6a..0938037 100644 --- a/TankiOffline/app/src/jsMain/kotlin/App/Browser/Ui/HeadScreen.kt +++ b/TankiOffline/app/src/jsMain/kotlin/App/Browser/Ui/HeadScreen.kt @@ -14,10 +14,8 @@ import react.FC import react.Props import react.create import react.dom.html.HTMLAttributes -import react.dom.html.ReactHTML.b import react.dom.html.ReactHTML.button import react.dom.html.ReactHTML.div -import react.dom.html.ReactHTML.i import react.dom.html.ReactHTML.img import react.dom.html.ReactHTML.span @@ -89,31 +87,52 @@ private val RightStyle: PropertiesBuilder.() -> Unit = { private val Divider = "1px solid rgba(255, 255, 255, 0.25)" +/** Emotion 嵌套选择器:原版 `qp7(m6n)` / `qp7(x4)` 的 hover 背景。 */ +private fun PropertiesBuilder.HoverBackground(Color: String) { + val Style: dynamic = js("({})") + Style["backgroundColor"] = Color + asDynamic()["&:hover"] = Style +} + +/** 原版 `sKt` / `a1n`:hover 时背景 5% 白,内部图标变纯白。 */ +private fun PropertiesBuilder.HoverBackgroundAndIcon() { + val Style: dynamic = js("({})") + val Child: dynamic = js("({})") + Child["backgroundColor"] = Palette.White + Style["backgroundColor"] = Palette.White05 + Style["div"] = Child + asDynamic()["&:hover"] = Style +} + // ---------------------------------------------------------------- VIP / 退出 -private fun VipStyle(On: Boolean): PropertiesBuilder.() -> Unit = { +/** 原版 `x6n.tap`:未开通 VIP 时显示金红渐变,开通后 `background:none`。 */ +private val PremiumGradient = + "radial-gradient(100% 100% at 0% 0%, rgba(255, 204, 0, 0.75) 0%, " + + "rgba(255, 38, 74, 0.5) 50%, rgba(255, 38, 74, 0) 100%)" + +private fun VipStyle(HasPremium: Boolean): PropertiesBuilder.() -> Unit = { + Css("box-shadow", "1px 0 0 0 rgba(255, 255, 255, 0.25)") + Css("cursor", "pointer") + Css("display", "flex") + Css("flex-direction", "column") + Css("align-items", "center") + Css("justify-content", "center") Css("position", "relative") Css("width", "6em") Css("height", "6em") - Css("display", "flex") - Css("align-items", "center") - Css("justify-content", "center") - Css("cursor", "pointer") - Css( - "background", - "radial-gradient(100% 100% at 0% 0%, rgba(255, 204, 0, 0.75) 0%, " + - "rgba(255, 38, 74, 0.5) 50%, rgba(255, 38, 74, 0) 100%)", - ) - if (!On) { - Css("opacity", "0.55") - Css("filter", "grayscale(0.3)") - } + if (!HasPremium) Css("background", PremiumGradient) + HoverBackground(Palette.White05) } private val VipIconStyle: PropertiesBuilder.() -> Unit = { Css("width", "2em") Css("height", "2em") - Css("background", "url(\"${Asset("static/images/iconButtonPremium.bc17a592.svg")}\") center / contain no-repeat") + Css("position", "absolute") + Css("background-image", "url(\"${Asset("static/images/iconButtonPremium.bc17a592.svg")}\")") + Css("background-position", "center") + Css("background-repeat", "no-repeat") + Css("background-size", "cover") } private val ExitStyle: PropertiesBuilder.() -> Unit = { @@ -137,30 +156,41 @@ private val ExitIconStyle: PropertiesBuilder.() -> Unit = { // ---------------------------------------------------------------- 组队 -private fun GroupStyle(Active: Boolean): PropertiesBuilder.() -> Unit = { - Css("position", "relative") - Css("width", "6em") +/** 原版 `L4.tap`:`width:95px → 5.9375em`,右边框,悬停 5% 白。 */ +private val GroupStyle: PropertiesBuilder.() -> Unit = { + Css("width", "5.9375em") Css("height", "6em") + Css("position", "relative") + Css("border-right", Divider) Css("display", "flex") Css("align-items", "center") Css("justify-content", "center") - Css("border-right", Divider) Css("cursor", "pointer") - if (!Active) Css("opacity", "0.55") + HoverBackground(Palette.White05) } -private fun GroupIconStyle(Offset: String): PropertiesBuilder.() -> Unit = { - Css("position", "absolute") - Css("top", "50%") - Css("left", "50%") +/** 原版 `UserGroupTitleButtonComponentStyle-commonUserIconsBlockGroup`(2 人组)。 */ +private val GroupIconsStyle: PropertiesBuilder.() -> Unit = { + Css("position", "relative") + Css("display", "flex") + Css("justify-content", "center") + Css("width", "3.25em") + Css("height", "1.9em") +} + +/** 原版 `q4`:1.5em 组员图标,绝对定位贴左/右下角。 */ +private fun GroupIconStyle(Side: String, Color: String): PropertiesBuilder.() -> Unit = { Css("width", "1.5em") Css("height", "1.5em") - Css("margin-top", "-0.75em") - Css("margin-left", "-0.75em") - Css("background", "rgba(191, 212, 255, 0.5)") - Css("mask", "url(\"${Asset("static/images/groupUser.67c9ec61.svg")}\") center / contain no-repeat") - Css("-webkit-mask", "url(\"${Asset("static/images/groupUser.67c9ec61.svg")}\") center / contain no-repeat") - Css("transform", "translateX($Offset)") + Css("display", "block") + Css("position", "absolute") + Css(Side, "0") + Css("bottom", "0") + Css("background-color", Color) + Css("background-image", "url(\"${Asset("static/images/groupUser.67c9ec61.svg")}\")") + Css("background-position", "center") + Css("background-repeat", "no-repeat") + Css("background-size", "contain") } // ---------------------------------------------------------------- 等级 / 用户 @@ -313,42 +343,42 @@ private val FullscreenStyle: PropertiesBuilder.() -> Unit = { Css("display", "flex") Css("align-items", "center") Css("justify-content", "center") - Css("gap", "0.3em") Css("width", "6em") Css("height", "6em") + Css("padding", "0") + Css("position", "relative") Css("border-left", Divider) + Css("border-right", Divider) + Css("background", "transparent") Css("cursor", "pointer") + HoverBackgroundAndIcon() } private val FullscreenIconStyle: PropertiesBuilder.() -> Unit = { Css("width", "1.5em") Css("height", "1.5em") - Css("background", "#bfd5ff") + Css("background-color", Palette.BlueLight) Css("mask", "url(\"${Asset("static/images/fullscreen.0b4547f5.svg")}\") center / contain no-repeat") Css("-webkit-mask", "url(\"${Asset("static/images/fullscreen.0b4547f5.svg")}\") center / contain no-repeat") } -private val FullscreenTextStyle: PropertiesBuilder.() -> Unit = { - Css("font", "600 0.75em/1 BaseFontMedium, sans-serif") - Css("color", "rgba(255, 255, 255, 0.65)") -} - private val LogoutStyle: PropertiesBuilder.() -> Unit = { Css("display", "flex") Css("align-items", "center") Css("justify-content", "center") Css("width", "6em") Css("height", "6em") + Css("margin-left", "0") Css("border", "0") - Css("border-left", Divider) Css("background", "transparent") Css("cursor", "pointer") + HoverBackgroundAndIcon() } private val LogoutIconStyle: PropertiesBuilder.() -> Unit = { Css("width", "1.5em") Css("height", "1.5em") - Css("background", "#bfd5ff") + Css("background-color", Palette.BlueLight) Css("mask", "url(\"${Asset("static/images/iconBack.62869951.svg")}\") center / contain no-repeat") Css("-webkit-mask", "url(\"${Asset("static/images/iconBack.62869951.svg")}\") center / contain no-repeat") } @@ -390,22 +420,28 @@ val HeadScreen = FC { div { css(VipStyle(HeadContext.HasPremium)) Ui("head.vip") - i { css(VipIconStyle) } + div { css(VipIconStyle) } } } else { button { css(ExitStyle) Ui("head.exit") onClick = { HeadContext.OnBack() } - i { css(ExitIconStyle) } + div { css(ExitIconStyle) } } } - div { - css(GroupStyle(HeadContext.GroupActive)) + if (HeadContext.GroupActive) div { + css(GroupStyle) Ui("head.group") - i { css(GroupIconStyle("-0.8em")); Ui("head.group.g1") } - i { css(GroupIconStyle("0.8em")); Ui("head.group.g2") } + // 原版默认组队上限 2 人:commonUserIconsBlockGroup + 两个 q4 图标。 + // 3/4 人分支(commonBlockGroup + 等级图标)暂未接组队数据。 + div { + css(GroupIconsStyle) + Ui("head.group.icons") + div { css(GroupIconStyle("left", Palette.GroupMemberOffline)); Ui("head.group.g1") } + div { css(GroupIconStyle("right", Palette.GroupMemberOffline)); Ui("head.group.g2") } + } } div { @@ -424,13 +460,13 @@ val HeadScreen = FC { div { css(XpBarStyle) Ui("head.user.xp") - i { css(XpFillStyle(Ratio)); Ui("head.user.xp.fill") } + div { css(XpFillStyle(Ratio)); Ui("head.user.xp.fill") } } } div { css(XpTextStyle) Ui("head.user.xp.text") - i { css(XpIconStyle) } + div { css(XpIconStyle) } +"${HeadContext.Score}" span { css(XpMaxStyle) @@ -473,14 +509,13 @@ val HeadScreen = FC { css(FullscreenStyle) Ui("head.fullscreen") onClick = { HeadContext.OnFullscreen() } - i { css(FullscreenIconStyle) } - b { css(FullscreenTextStyle); +"F11" } + div { css(FullscreenIconStyle) } } button { css(LogoutStyle) Ui("head.logout") onClick = { HeadContext.OnLogout() } - i { css(LogoutIconStyle) } + div { css(LogoutIconStyle) } } } } diff --git a/TankiOffline/app/src/jsMain/kotlin/App/Browser/Ui/Palette.kt b/TankiOffline/app/src/jsMain/kotlin/App/Browser/Ui/Palette.kt index 3667ea0..80266c4 100644 --- a/TankiOffline/app/src/jsMain/kotlin/App/Browser/Ui/Palette.kt +++ b/TankiOffline/app/src/jsMain/kotlin/App/Browser/Ui/Palette.kt @@ -45,6 +45,12 @@ object Palette { const val Purple = "rgb(175, 115, 225)" const val Teal = "rgb(48, 213, 200)" + // 组队成员状态色:module_82347 的 p4(w4() 单例),不是 C9i 主题 + const val GroupMemberOffline = "rgba(191, 212, 255, 0.5)" // x1ih_1 = #BFD4FF @ 0.5 + const val GroupMemberSelfPremium = "rgb(255, 204, 0)" // y1ih_1 = #FFCC00 + const val GroupMemberOnline = "rgb(118, 255, 51)" // z1ih_1 = #76FF33 + const val GroupMemberFriend = "rgb(0, 212, 255)" // a1ii_1 = #00D4FF + // 面板 / 边框 / 文本 const val Panel = White10 const val PanelSoft = White05