From 7151d3f91c68eaf261ba67c0f3c3efa6a00b8902 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Thu, 24 Sep 2026 11:02:05 +0800 Subject: [PATCH] =?UTF-8?q?=E9=B8=BF=E8=92=99=EF=BD=9C=E5=8A=A8=E7=94=BB?= =?UTF-8?q?=E5=AF=B9=E9=BD=90=20all=5Ffive=20=E8=90=BD=E5=9C=B0=20+=20?= =?UTF-8?q?=E6=94=B6=E6=95=9B=20pageEnter=20=E6=AD=BB=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户裁定「动画对齐 = 五条逐个对照」(all_five, 2026-09-23)。 本轮把五条核对完并把结果**沉淀成常驻判据**(本仓做法:审计不落判据就会漂)。 核对结果(WebUI 侧剥注释后实测,不是靠记忆): rise-in 定义✓ 使用✓ → Theme.paneRiseIn() ×6 + Motion.pageEnter() ×3 pane-in 定义✗ 使用✗ → 9aa702b 删掉的死规则(碑文 index.css:1239) 用户 09-14 明确否掉「整屏一起淡」,两侧都不得复活 menu-in 定义✓ 使用✓ → Theme.menuIn() ×2 cal-in-next 定义✓ 使用✓ → Theme.calendarSlide(true) cal-in-prev 定义✓ 使用✓ → Theme.calendarSlide(false) ⇒ 五条全部落地;无缺口需要新写动画(避免了"自己发明一条")。 顺带修一处真问题: Motion.pageEnter() 定义了、返回的正是三个 @Entry 页各自手写的 那份 {duration, curve} 字面量,却**一个调用点都没有**(死方法)。 三个页面(AdminUsersPage/ComposePage/MailDetailPage)改为走它。 这正是本仓反复出现的形状:一处定义 + 三处同源各自演化。 判据(animation-audit.test.mjs 12 → 15): ① WebUI 每个**在用**的 keyframe 都有鸿蒙实现,且实现**真的有人穿** —— 名单从 CSS 动态取(liveKeyframes),不是写死,将来加删会跟着动。 「有调用点」是关键:本仓的失败形状是"定义了却没人用"(menuIn 一度如此), "方法存在"是弱断言 —— 删掉最后一个调用点它照样绿。 ② pane-in 不得在**任一侧**复活(只查鸿蒙不够,WebUI 复活同样会两端不一致)。 负面断言走剥注释版,碑文里的引用不会让它假红。 ③ 一般化:**任何**返回 TransitionEffect 的动画辅助方法都必须有调用点 —— 防的是"下一条",pageEnter 就是这里被抓出来的。 变异验证(三条新判据逐条打红,还原后回绿): · 删掉 calendarSlide 调用点 → ①③ 红(cal-in-next/prev 无调用点) · 鸿蒙复活 paneIn() → ② 红 · WebUI 复活 @keyframes pane-in + 使用 → ①② 红 ⇒ 判据有齿,不是橡皮图章。 套件:animation-audit 15/15、harmony-logic 34/34、harmony-nav 22/22、 harmony-appearance 27/27。hvigorw BUILD SUCCESSFUL。 --- client/electron/test/animation-audit.test.mjs | 92 +++++++++++++++++-- .../src/main/ets/pages/AdminUsersPage.ets | 10 +- .../entry/src/main/ets/pages/ComposePage.ets | 5 +- .../src/main/ets/pages/MailDetailPage.ets | 5 +- 4 files changed, 100 insertions(+), 12 deletions(-) diff --git a/client/electron/test/animation-audit.test.mjs b/client/electron/test/animation-audit.test.mjs index 4056f29..7a4b6dd 100644 --- a/client/electron/test/animation-audit.test.mjs +++ b/client/electron/test/animation-audit.test.mjs @@ -331,13 +331,93 @@ check( ); /* - * ★★ 2026-09-21 删除两条陈旧断言: - * · 「页面里不再直接出现 `Theme.durMorph`」 - * · 「`Theme.durMorph` 确实存在且 = 220」 + * ════════════════════════════════════════════════════════════════ + * 鸿蒙侧:五个 `@keyframes` 的**逐条对照**(用户裁定 `all_five`,2026-09-23) + * ════════════════════════════════════════════════════════════════ * - * 令牌**已被删除**(morph 改用 `responsiveSpringMotion`,弹簧曲线下 - * duration 不生效,保留那是误导)⇒ 这两条现在守的是一个不存在的东西。 - * 上面那条改为钉**曲线令牌**的"不得下沉到页面",与原来的意图同一件事。 + * 用户裁定:动画对齐 = **五条逐个对照补齐**,不是"整体观感差不多"。 + * 盘点( 2026-09-24)结果 —— WebUI 侧五个 keyframe 的**实况**(剥注释后实测): + * + * rise-in 定义✓ 使用✓ → 鸿蒙 `Theme.paneRiseIn()` / `Motion.pageEnter()` + * pane-in 定义✗ 使用✗ → 9aa702b 删掉的**死规则**(碑文 index.css:1239) + * 用户 09-14 明确否掉"整屏一起淡",两侧都不得复活 + * menu-in 定义✓ 使用✓ → 鸿蒙 `Theme.menuIn()` + * cal-in-next 定义✓ 使用✓ → 鸿蒙 `Theme.calendarSlide(true)` + * cal-in-prev 定义✓ 使用✓ → 鸿蒙 `Theme.calendarSlide(false)` + * + * ★ 为什么判据要盯"**有调用点**",而不只是"方法存在": + * 本仓反复出现的失败形状是**定义了却没人用** —— 盘点当场抓到两个: + * · `Motion.pageEnter()` 定义了、返回的正是三个 `@Entry` 页各自手写的 + * 那份字面量,却**一个调用点都没有**(改前实测); + * · `Theme.menuIn()` 一度"只剩定义、没有调用点"(账号选择器换成官方 + * `bindMenu` 后),当时靠人肉发现"候选列表还没挂"才没变成死方法。 + * "方法存在"是弱断言:删掉最后一个调用点它照样绿 —— 而那正是死动画。 + * + * ★ 对照表用 **WebUI 的 CSS 动态取**(`liveKeyframes`),不是抄一份名单: + * 将来谁在 WebUI 加/删一个 keyframe,这里会跟着动;写死名单就会漂。 */ +const liveKeyframes = keyframes.filter( + k => new RegExp(`animation:\\s*${k}\\b`).test(css) +); + +/* WebUI keyframe → 鸿蒙实现方法(可多个备选,任一满足即可) */ +const KMAP = { + 'rise-in': ['paneRiseIn', 'pageEnter'], + 'menu-in': ['menuIn'], + 'cal-in-next': ['calendarSlide'], + 'cal-in-prev': ['calendarSlide'] +}; + +const harmonyPageSrc = hs.map(h => h.src).join('\n'); +const harmonyAnimSrc = themeSrc + '\n' + MOTION; + +const unmapped = []; +for (const k of liveKeyframes) { + const impls = KMAP[k]; + if (!impls) { + unmapped.push(`${k}(WebUI 在用,但鸿蒙没有对照)`); + continue; + } + const defined = impls.some(m => new RegExp(`static\\s+${m}\\(`).test(harmonyAnimSrc)); + const consumed = impls.some(m => new RegExp(`\\.${m}\\(`).test(harmonyPageSrc)); + if (!defined) unmapped.push(`${k}→${impls.join('/')}(未定义)`); + else if (!consumed) unmapped.push(`${k}→${impls.join('/')}(**无调用点** = 死动画)`); +} +check( + '鸿蒙|WebUI 每个**在用**的 `@keyframes` 都有鸿蒙实现,且实现**真的有人穿**', + unmapped.length === 0, + '这些 keyframe 在鸿蒙侧没有落地或落地了没人用(看着有、永远不播):' + unmapped.join(';') + + '\n用户裁定 `all_five`:五条逐个对照,不是"整体观感差不多"' +); + +/* + * ★ `pane-in` 的负面断言:它是**两边都不得复活**的那一条。 + * 只查"鸿蒙有没有"不够 —— WebUI 侧复活了同样会让两端不一致。 + * (`css` 是剥注释版,所以碑文里的引用不会让它假红。) + */ +check( + '鸿蒙|已删除的 `pane-in` 不得在任一侧复活(用户 09-14 否掉"整屏一起淡")', + !/@keyframes\s+pane-in/.test(css) && !/paneIn\s*\(/.test(harmonyAnimSrc), + '`pane-in` 是 9aa702b 删掉的**死规则**(碑文 index.css:1239):它让"已经在那儿的框架"' + + '也一起暗一下,用户明确否掉过。复活它 = 把"闪"请回来' +); + +/* + * ★ 同类失败形状的一般化:**任何**返回 `TransitionEffect` 的动画辅助方法 + * 都必须有调用点。上面是用户点名的五条,这一条防的是**下一条**。 + * (`Motion.pageEnter()` 就是这里被抓出来的:定义了、没人用。) + */ +const animHelpers = [ + ...themeSrc.matchAll(/static\s+([A-Za-z][A-Za-z0-9]*)\([^)]*\)\s*:\s*TransitionEffect/g) +].map(m => m[1]); +const deadHelpers = animHelpers.filter( + m => !new RegExp(`\\.${m}\\(`).test(harmonyPageSrc) +); +check( + '鸿蒙|不得有"定义了却没调用点"的动画辅助方法(死动画的固定来源)', + deadHelpers.length === 0, + '这些动画方法定义了但全仓没有调用点(删掉最后一个调用点它就静默失效):' + + deadHelpers.join(' ') +); finish('动画盘点'); diff --git a/client/harmony/entry/src/main/ets/pages/AdminUsersPage.ets b/client/harmony/entry/src/main/ets/pages/AdminUsersPage.ets index 06ff9cf..fc08e29 100644 --- a/client/harmony/entry/src/main/ets/pages/AdminUsersPage.ets +++ b/client/harmony/entry/src/main/ets/pages/AdminUsersPage.ets @@ -299,10 +299,16 @@ struct AdminUsersPage { * ★ 退场只做**淡出、不做位移**:两端都位移会看起来互相推挤。 */ pageTransition() { - PageTransitionEnter({ duration: Motion.dur(Theme.durRise), curve: Theme.easeRise }) + /* + * ★ 2026-09-24:改走 `Motion.pageEnter()` 统一入口。 + * 原先三个 `@Entry` 页各自手写同一份 `{duration, curve}` 字面量, + * 而 `Motion.pageEnter()` 返回的**正是**这段字面量、却一直**没有调用点** + * (定义了没人用的死方法)—— 两处同源各自演化正是本仓反复出现的形状。 + */ + PageTransitionEnter(Motion.pageEnter()) .opacity(0) .translate({ y: Theme.riseInOffset }) - PageTransitionExit({ duration: Motion.dur(Theme.durRise), curve: Theme.easeRise }) + PageTransitionExit(Motion.pageEnter()) .opacity(0) } diff --git a/client/harmony/entry/src/main/ets/pages/ComposePage.ets b/client/harmony/entry/src/main/ets/pages/ComposePage.ets index 56eda99..97eab90 100644 --- a/client/harmony/entry/src/main/ets/pages/ComposePage.ets +++ b/client/harmony/entry/src/main/ets/pages/ComposePage.ets @@ -950,10 +950,11 @@ struct ComposePage { * ★ 退场只做**淡出、不做位移**:两端都位移会看起来互相推挤。 */ pageTransition() { - PageTransitionEnter({ duration: Motion.dur(Theme.durRise), curve: Theme.easeRise }) + /* 走统一入口(三个 `@Entry` 页原先各自手写同一份时长/曲线,见 `Motion.pageEnter`)*/ + PageTransitionEnter(Motion.pageEnter()) .opacity(0) .translate({ y: Theme.riseInOffset }) - PageTransitionExit({ duration: Motion.dur(Theme.durRise), curve: Theme.easeRise }) + PageTransitionExit(Motion.pageEnter()) .opacity(0) } diff --git a/client/harmony/entry/src/main/ets/pages/MailDetailPage.ets b/client/harmony/entry/src/main/ets/pages/MailDetailPage.ets index d2f3fb1..8d2f2f1 100644 --- a/client/harmony/entry/src/main/ets/pages/MailDetailPage.ets +++ b/client/harmony/entry/src/main/ets/pages/MailDetailPage.ets @@ -2017,10 +2017,11 @@ struct MailDetailPage { * ★ 退场只做**淡出、不做位移**:两端都位移会看起来互相推挤。 */ pageTransition() { - PageTransitionEnter({ duration: Motion.dur(Theme.durRise), curve: Theme.easeRise }) + /* 走统一入口(三个 `@Entry` 页原先各自手写同一份时长/曲线,见 `Motion.pageEnter`)*/ + PageTransitionEnter(Motion.pageEnter()) .opacity(0) .translate({ y: Theme.riseInOffset }) - PageTransitionExit({ duration: Motion.dur(Theme.durRise), curve: Theme.easeRise }) + PageTransitionExit(Motion.pageEnter()) .opacity(0) }