fix(theme): lock VT pseudo-element opacity/blend via CSS !important
Gray expanding circle was caused by UA default animations (fade-in/out) and mix-blend-mode: plus-lighter not being fully overridden by WAAPI opacity animations alone. Fix: use CSS with !important to hard-lock the VT pseudo-elements: - animation: none !important — kills UA fade-in/out - opacity: 1 !important — both layers stay fully opaque - mix-blend-mode: normal !important — no color addition WAAPI now only controls clip-path on ::view-transition-new(root), which doesn't conflict with any CSS property (no CSS clip-path exists). This cleanly separates concerns: CSS handles static properties, WAAPI handles the dynamic circle expansion.
This commit is contained in:
parent
f0ea1a294f
commit
0f9c8fb8a3
@ -1,11 +1,14 @@
|
|||||||
/* ========== 主题切换圆形展开(View Transitions API) ========== */
|
/* ========== 主题切换圆形展开(View Transitions API) ========== */
|
||||||
|
|
||||||
/* mix-blend-mode 不可通过 Web Animations API 设置,只能用 CSS。
|
/* 硬锁 VT 伪元素样式:禁用 UA 默认的 fade-in/out,
|
||||||
UA 默认 plus-lighter 会导致新旧层颜色叠加发亮,需覆盖为 normal。
|
强制两层都保持完全不透明 + 正常混合模式。
|
||||||
author 样式天然覆盖 UA 样式,无需 !important。 */
|
WAAPI 仅控制 ::view-transition-new 的 clip-path 展开,不涉及 opacity。
|
||||||
|
!important 确保覆盖 UA origin。 */
|
||||||
::view-transition-old(root),
|
::view-transition-old(root),
|
||||||
::view-transition-new(root) {
|
::view-transition-new(root) {
|
||||||
mix-blend-mode: normal;
|
animation: none !important;
|
||||||
|
opacity: 1 !important;
|
||||||
|
mix-blend-mode: normal !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 在 View Transition 期间强制禁用所有 CSS 过渡,
|
/* 在 View Transition 期间强制禁用所有 CSS 过渡,
|
||||||
|
|||||||
@ -71,11 +71,11 @@ describe('startThemeTransition', () => {
|
|||||||
// ready 后通过 Web Animations API 控制动画
|
// ready 后通过 Web Animations API 控制动画
|
||||||
await readyP;
|
await readyP;
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
// animate 应被调用两次:一次 old(opacity),一次 new(clipPath + opacity)
|
// animate 应被调用一次:clip-path 展开 on new
|
||||||
expect(animateSpy).toHaveBeenCalledTimes(2);
|
expect(animateSpy).toHaveBeenCalledTimes(1);
|
||||||
// 第二次调用(new)应包含 clipPath
|
// 调用应包含 clipPath + pseudoElement
|
||||||
const calls = animateSpy.mock.calls as unknown[][];
|
const calls = animateSpy.mock.calls as unknown[][];
|
||||||
const newCall = calls[1];
|
const newCall = calls[0];
|
||||||
expect(newCall[0]).toHaveProperty('clipPath');
|
expect(newCall[0]).toHaveProperty('clipPath');
|
||||||
expect(newCall[1]).toHaveProperty('pseudoElement', '::view-transition-new(root)');
|
expect(newCall[1]).toHaveProperty('pseudoElement', '::view-transition-new(root)');
|
||||||
|
|
||||||
|
|||||||
@ -82,28 +82,18 @@ export function startThemeTransition(x: number, y: number): void {
|
|||||||
|
|
||||||
vt.ready
|
vt.ready
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log('[tt] ready, animating via WAAPI');
|
console.log('[tt] ready, animating clip-path via WAAPI');
|
||||||
// ── Web Animations API ──
|
// CSS 已通过 animation:none + opacity:1 (!important) 锁定两层:
|
||||||
// script-created 动画优先级高于 CSS 动画(含 UA 默认 fade-in/out),
|
// OLD 保持完全可见(暗色底图),NEW 保持完全不透明。
|
||||||
// 天然覆盖,无需 !important,无残留样式问题。
|
// WAAPI 只需控制 NEW 的 clip-path 实现圆形展开。
|
||||||
|
// script-created Animation 优先级高于 CSS animation(已被 none 禁用),
|
||||||
// OLD: 覆盖 UA 默认的 fade-out,保持完全可见作为底图
|
// 只添加 clip-path 动画,不与 CSS 冲突。
|
||||||
document.documentElement.animate(
|
|
||||||
{ opacity: [1, 1] },
|
|
||||||
{
|
|
||||||
duration: 400,
|
|
||||||
pseudoElement: '::view-transition-old(root)',
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// NEW: 覆盖 UA 默认的 fade-in,改为 clip-path 圆形展开
|
|
||||||
document.documentElement.animate(
|
document.documentElement.animate(
|
||||||
{
|
{
|
||||||
clipPath: [
|
clipPath: [
|
||||||
`circle(0px at ${x}px ${y}px)`,
|
`circle(0px at ${x}px ${y}px)`,
|
||||||
`circle(${maxR}px at ${x}px ${y}px)`,
|
`circle(${maxR}px at ${x}px ${y}px)`,
|
||||||
],
|
],
|
||||||
opacity: [1, 1],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
duration: 400,
|
duration: 400,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user