跨端: 鸿蒙动画补齐 —— 并且发现原来的「逐字一致」是假的(令牌存在 ≠ 动画用了它)
用户:「A,同时把鸿蒙app的动画补齐」。 ## 先纠一条错的前提(这是本轮最有价值的发现) `Theme.ets` 的注释与 `harmony-nav` 的判据**都**写着:「三个数与 WebUI **逐字一致**: `--ease-out-soft: cubic-bezier(0.22,1,0.36,1)`、`--dur-fast: 120ms`、`--dur-base: 180ms`」, `paneRiseIn()` 就按 `durBase(180)` + `easeOutSoft` 做。 三个令牌**确实存在**(`index.css:310-312`)—— 但这句话把「令牌存在」当成了「动画用了它」: | WebUI 里 | 真实用途 | |---|---| | `--dur-base: 180ms` | **只**用在壁纸淡入(`:747`) | | `--ease-out-soft (0.22,1,0.36,1)` | **只**用在 transition(壁纸、控件变色) | | **所有 @keyframes 动画** | 硬编码 **150ms / 200ms** + `cubic-bezier(0.22, 0.61, 0.36, 1)` | 全仓 `(0.22,0.61,0.36,1)` 出现 **5 次**(rise-in×3 / cal-in×2),`(0.22,1,0.36,1)` 只出现 **1 次**(令牌定义处)。**是两根不同的曲线** —— 旧代码的面板入场比 WebUI 慢 30ms 且曲线偏软。 所以令牌拆成两组,各对齐各的:控件类 `durFast + easeOutSoft`;动画类 `durRise(150)/durMenu(140)/durCal(200) + easeRise(0.22,0.61,0.36,1)`。 ## 补的动画(对齐 WebUI 三个 @keyframes) - `menuIn()` —— 弹层:下移 4vp + 缩到 0.985 + 淡入(`@keyframes menu-in`)。 ★ 适用范围照搬 WebUI 注释那条窄口径(「只给真正是弹层的东西」):那条规则曾挂着 `glass-control`,于是每次切视图**所有按钮与输入框一起淡入位移**,09-15 被摘掉。 挂到写邮件页的账号候选列表上。 - `calendarSlide(forward)` —— 日历翻月:从 ±12% 横向滑入(`cal-in-next/prev`)。 方向由新增 `@State slideForward` 带进 `animateTo` 闭包;网格键加 `monthKey()` 前缀 保证月份一变所有键全变(否则"跨年同名月"那类边角会静默不播)。 - 写信页整页 `rise-in`、回复框 `rise-in`(WebUI 挂在回复框本身,不是外层遮罩 —— 挂遮罩上会让整个屏幕一起位移,看起来是"页面在动"而不是"框弹出来")。 **实测确认真的会播**(不是"编译过了"):按本仓记录的手法把 `durCal` 临时改成 8000 做慢动作,连拍三帧 —— 截图硬证**两张月历同时在屏**(九月淡出、十月从右侧 12% 滑入), 验完还原成 200ms。 ## 判据:从「令牌存在」改成「动画真的用了那个令牌」 `harmony-nav` 那条判据原文锚在令牌上,所以它对上面那个 bug **一辈子全绿**。 重写为: - 从 WebUI `index.css` **读出** `rise-in` 的真实时长与曲线(`150ms` + 那条 bezier), 再断言鸿蒙的 `durRise` 与曲线字面量与之逐字一致 —— 而不是"仓库里有没有 180 这个数"; - ★ 把 `paneRiseIn()` 的**函数体抠出来**单独断言它引的是 `durRise/easeRise`, 且**不得出现** `durBase/easeOutSoft`。 **这一步不能省 —— 我第一版就漏了它**:断言了令牌存在、也断言了曲线字面量存在, 但没断言函数用了它们;于是把函数体换回旧的错值后判据**仍然全绿**。 变异自检抓住了这一点,补上函数体断言后同一个变异 ⇒ 判红 ✓。 与今天修的另一处同源:**判据要锚在"这个东西被用在哪",不是"它存在"**。
This commit is contained in:
@ -257,6 +257,19 @@ struct ComposePage {
|
||||
this.selectedAccountId = acct.id;
|
||||
this.showAccountPicker = false;
|
||||
})
|
||||
/*
|
||||
* 弹层入场(对齐 WebUI `@keyframes menu-in`:下移 4vp + 缩到 0.985 + 淡入)。
|
||||
*
|
||||
* ★ 只给**弹层**挂 —— WebUI 那条 `.animate-menu-in` 的注释把适用范围
|
||||
* 钉得很窄("只给真正是弹层的东西"),因为它曾经挂着 `glass-control`,
|
||||
* 于是每次切视图页面上**所有**按钮与输入框一起淡入位移(几十个元素同时动),
|
||||
* 2026-09-15 被摘掉。别把这个放到常驻控件上。
|
||||
*
|
||||
* 挂在 `Row` 上(即 `ForEach` 的每一项):整张候选列表逐项轻落,
|
||||
* 与 WebUI 里"整块列表一起动"略有差别 —— 但 ArkUI 的 `ForEach` 每项
|
||||
* 是独立节点,逐项入场反而更接近"列表展开"的观感,且不会让整层不可交互。
|
||||
*/
|
||||
.transition(Theme.menuIn())
|
||||
}, (acct: AccountInfo) => acct.id)
|
||||
}
|
||||
|
||||
@ -341,5 +354,14 @@ struct ComposePage {
|
||||
}
|
||||
.width('100%').height('100%')
|
||||
.backgroundColor(Theme.pageBg)
|
||||
/*
|
||||
* 整页入场(对齐 WebUI 写信页的 `rise-in`:4vp 上浮 + 淡入)。
|
||||
*
|
||||
* WebUI 实测(`ComposePage.tsx:174`):`fromRect ? '' : 'rise-in …'` ——
|
||||
* 没有动画起点时(例如刷新后直接进写信页)才挂 `rise-in`;
|
||||
* 有"从 FAB 长出来"的起点时改走另一条(两条都动 transform/opacity,同挂会打架)。
|
||||
* 本仓没有"从 FAB 长出来"那条,所以直接挂就是它的"无起点"分支。
|
||||
*/
|
||||
.transition(Theme.paneRiseIn())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user