跨端: 玻璃走基础组件(透明度/磨砂/投影)+ 判据去芜存菁(修 4 个判据自身缺陷)
用户两条:「玻璃不透明/不够磨砂炫酷,要更基础组件化」+「判据去掉无意义的、保留有用的」。
★ 玻璃的透明度与质感(逐层调出来的,不是拍的)
· 透明度:`BlurStyle` 是固定档、没有 saturate 旋钮 ⇒ 观感偏灰。
改用参数化 `backgroundEffect({ radius, saturation })`,字段与 CSS `backdrop-filter`
一一对应,于是可以**照抄 WebUI 的数**:`blur(18px) saturate(1.5)`
(WebUI `.narrow-nav`,那里最"玻璃"的一档)。**saturate 才是玻璃感的主要来源**。
· 质感:只模糊+饱和仍然"像一块平的白方块" —— 玻璃板之所以像板靠的是**边缘**。
WebUI 的完整配方是 `box-shadow: 0 8px 28px rgb(0 0 0 / 0.16)` + 发丝描边。
只有模糊没有投影 ⇒ 一片雾;加上投影 ⇒ 一块板。**这是"不够炫酷"的主因**
(我先前两个方向都调了模糊与饱和,方向就偏了)。
· 投影用**系统预置档** `ShadowStyle.OUTER_FLOATING_SM`("浮起的小面板"),
不是手写 `{radius, color, offsetY}` —— 手写色要么是 `#AARRGGBB`、
要么是 `rgba()`,两者都被判据明令禁止,而那条禁令**是对的**:
手写阴影色在深色下看不见(深底叠深影 = 无变化),WebUI 在 `.dark` 里
要把同一处从 0.16 加重到 0.55 —— 那正是"替系统猜深浅"。
★ 基础组件(用户:「定义一个基础玻璃容器给各个组件引用」)
· `GlassCardModifier` / `PaneModifier`(`AttributeModifier<CommonAttribute>`):
**一处定义、处处引用**。页面里的玻璃从 15 处内联三连收敛成
`.attributeModifier(...of(this.bgActive))`。
★ 为什么不是 `@Styles`:全局 `@Styles` 读不到 `this`(而玻璃要知道 `bgActive`);
成员级 `@Styles` 能读 `this` 但**每个 struct 各一份**,MainPage 有 7 个 struct
⇒ 只是把"每处抄 3 行"换成"每 struct 抄 1 份",没解决问题。
· `Motion.dur()`:接系统「减弱动态效果」(`isAnimationReduceEnabledSync()`,API 23)。
WebUI 有 `prefers-reduced-motion` 硬约束,鸿蒙这边**改造前一次都没调过**。
★ 途中撞出并修掉的**真 bug**(都是我自己的)
· 把 `@Styles glassCard()` 里也替换成 `attributeModifier` ⇒
「我的」页 ProfileSection/AppearanceSection/PushSection **整块不渲染**
(设备实测:Scroll 直接跳到「客户端连接密钥」)。删掉那个死 `@Styles` 即恢复。
· `Theme.shadowColor/hairline` 用了 `rgba()` + `#AARRGGBB` ⇒ 违反本仓两条既有禁令
("鸿蒙侧不写 CSS 颜色函数"、"半透明属于系统材质/职责")。改用系统阴影档。
★ 判据去芜存菁:修了 4 个**判据自身的缺陷**(都是它声称在管、实际漏判/误判)
· 材质来源只扫 `backgroundBlurStyle` —— 玻璃改成 `backgroundEffect` 后**整类漏判**。
实测:往 Modifier 里塞 `backgroundEffect({radius:99,saturation:9.9})` 照样全绿。
⇒ 补上这一类,并加"参数必须引 Theme 令牌"(否则只是换个旋钮写死)。
· 参数抽取用 `[^)]*` —— 对 `this.materialOf()` 与 `{...}` 对象字面量都提前截断,
**误伤合法写法**(本次被它误红两次)。改成配对括号 + 去外层花括号。
· 嵌套判定**没比文件**:拿 A 文件的字符偏移去比 B 文件 ⇒ 判出
"MainPage 内含 SettingsPage 的玻璃"这种物理上不可能的红。
假红比漏报更坏 —— 会让人去改本来对的代码(本次差一点)。
· `harmony-appearance` 数的是**内联字面量**("三元出现 ≥5 次"),
收敛成组件后写法变了、行为没变却变红 ⇒ 改成判不变式
(让位只有一条路径 + 每个窗格都收到开关)。
· 顺带:设备判据找「背景」时只在首屏可见节点里找(而 dumpLayout 只给可见节点),
且我的第一版只朝一个方向滑(越滑越远)⇒ 改成"先回顶、再逐屏向下扫"。
判据:files=32 ran=32 checks=518 pass=518 fail=0 red=0;baseline 7/7✓(第 7 次,逐个取证)。
This commit is contained in:
@ -10,6 +10,7 @@
|
||||
*/
|
||||
import { ApiClient, ApiError } from '../api/ApiClient';
|
||||
import { Theme } from '../common/Theme';
|
||||
import { GlassCardModifier, PaneModifier } from '../common/Surface';
|
||||
import { AuthApi } from '../api/AuthApi';
|
||||
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||
import { common } from '@kit.AbilityKit';
|
||||
@ -32,6 +33,7 @@ import { PushTokenList } from '../model/PushContract';
|
||||
|
||||
@Component
|
||||
export struct SettingsPane {
|
||||
|
||||
/** 背景开关(与其它窗格同一约定:开着就让出页面底) */
|
||||
@Prop bgActive: boolean = false;
|
||||
/** 底部悬浮条高度(窄屏非 0)—— 本页滚动容器的内容末尾要让出它 */
|
||||
@ -667,8 +669,7 @@ export struct SettingsPane {
|
||||
}
|
||||
.width('100%').alignItems(HorizontalAlign.Start)
|
||||
.padding(16).margin({ top: 8 })
|
||||
.backgroundColor(this.bgActive ? Color.Transparent : Theme.surface)
|
||||
.backgroundBlurStyle(this.bgActive ? Theme.cardMaterial : BlurStyle.NONE)
|
||||
.attributeModifier(GlassCardModifier.of(this.bgActive))
|
||||
.borderRadius(Theme.radiusCard)
|
||||
|
||||
/* 外观(主题 / 壁纸) */
|
||||
@ -739,8 +740,7 @@ export struct SettingsPane {
|
||||
.width('100%')
|
||||
}
|
||||
.width('100%').height('68%')
|
||||
.padding(16).backgroundColor(this.bgActive ? Color.Transparent : Theme.surface)
|
||||
.backgroundBlurStyle(this.bgActive ? Theme.cardMaterial : BlurStyle.NONE)
|
||||
.padding(16).attributeModifier(GlassCardModifier.of(this.bgActive))
|
||||
.borderRadius({ topLeft: 12, topRight: 12 })
|
||||
/*
|
||||
* ★ 2026-09-19 补(用户:「元素的出现消失动画呢?」)。
|
||||
@ -759,7 +759,7 @@ export struct SettingsPane {
|
||||
}
|
||||
.width('100%').height('100%')
|
||||
/* 与其它窗格同一约定:背景开着时让出页面底,壁纸才透得过 */
|
||||
.backgroundColor(this.bgActive ? Color.Transparent : Theme.pageBg)
|
||||
.attributeModifier(PaneModifier.of(this.bgActive))
|
||||
}
|
||||
|
||||
/** 分区标题(与 WebUI `AccountPage` 的 `<h3>` 同形:小字、灰、上间距) */
|
||||
@ -826,8 +826,7 @@ export struct SettingsPane {
|
||||
}
|
||||
.width('100%').alignItems(HorizontalAlign.Start)
|
||||
.padding(16).margin({ top: 10 })
|
||||
.backgroundColor(this.bgActive ? Color.Transparent : Theme.surface)
|
||||
.backgroundBlurStyle(this.bgActive ? Theme.cardMaterial : BlurStyle.NONE)
|
||||
.attributeModifier(GlassCardModifier.of(this.bgActive))
|
||||
.borderRadius(Theme.radiusCard)
|
||||
}
|
||||
|
||||
@ -898,8 +897,7 @@ export struct SettingsPane {
|
||||
}
|
||||
.width('100%').alignItems(HorizontalAlign.Start)
|
||||
.padding(16).margin({ top: 8 })
|
||||
.backgroundColor(this.bgActive ? Color.Transparent : Theme.surface)
|
||||
.backgroundBlurStyle(this.bgActive ? Theme.cardMaterial : BlurStyle.NONE)
|
||||
.attributeModifier(GlassCardModifier.of(this.bgActive))
|
||||
.borderRadius(Theme.radiusCard)
|
||||
}
|
||||
|
||||
@ -936,8 +934,7 @@ export struct SettingsPane {
|
||||
}
|
||||
.width('100%').alignItems(HorizontalAlign.Start)
|
||||
.padding(16).margin({ top: 8 })
|
||||
.backgroundColor(this.bgActive ? Color.Transparent : Theme.surface)
|
||||
.backgroundBlurStyle(this.bgActive ? Theme.cardMaterial : BlurStyle.NONE)
|
||||
.attributeModifier(GlassCardModifier.of(this.bgActive))
|
||||
.borderRadius(Theme.radiusCard)
|
||||
}
|
||||
|
||||
@ -1022,8 +1019,7 @@ export struct SettingsPane {
|
||||
}
|
||||
.width('100%').alignItems(HorizontalAlign.Start)
|
||||
.padding(16).margin({ top: 8 })
|
||||
.backgroundColor(this.bgActive ? Color.Transparent : Theme.surface)
|
||||
.backgroundBlurStyle(this.bgActive ? Theme.cardMaterial : BlurStyle.NONE)
|
||||
.attributeModifier(GlassCardModifier.of(this.bgActive))
|
||||
.borderRadius(Theme.radiusCard)
|
||||
}
|
||||
|
||||
@ -1160,8 +1156,7 @@ export struct SettingsPane {
|
||||
}
|
||||
.width('100%').alignItems(HorizontalAlign.Start)
|
||||
.padding(16).margin({ top: 8 })
|
||||
.backgroundColor(this.bgActive ? Color.Transparent : Theme.surface)
|
||||
.backgroundBlurStyle(this.bgActive ? Theme.cardMaterial : BlurStyle.NONE)
|
||||
.attributeModifier(GlassCardModifier.of(this.bgActive))
|
||||
.borderRadius(Theme.radiusCard)
|
||||
}
|
||||
|
||||
@ -1188,8 +1183,7 @@ export struct SettingsPane {
|
||||
}
|
||||
.width('100%').alignItems(HorizontalAlign.Start)
|
||||
.padding(16).margin({ top: 8 })
|
||||
.backgroundColor(this.bgActive ? Color.Transparent : Theme.surface)
|
||||
.backgroundBlurStyle(this.bgActive ? Theme.cardMaterial : BlurStyle.NONE)
|
||||
.attributeModifier(GlassCardModifier.of(this.bgActive))
|
||||
.borderRadius(Theme.radiusCard)
|
||||
.onClick(() => {
|
||||
this.getUIContext().getRouter().pushUrl({ url: 'pages/AdminUsersPage' });
|
||||
|
||||
Reference in New Issue
Block a user