使用两段代码,通过 View Transitions API 为主题切换添加平滑过渡动画

😀 在 Web 开发中,主题切换通常是即时生效的,但这种方式会导致用户视觉上的突兀感。通过 View Transitions API,我们可以实现更流畅的切换动画,让深色模式和浅色模式的过渡更加自然。

功能描述

点击 Switch 组件切换主题时,页面会从点击位置向外扩散,形成类似"水波扩散"的动画效果,使切换过程更具视觉吸引力。

Demo 仓库

核心代码

  1. 主题切换逻辑 在主题切换处理函数中:
ts 复制代码
const handleThemeChange: SwitchProps["onChange"] = (checked: boolean, event) => {
  // 必须加这句
  document.documentElement.className = checked ? "dark" : "light";

  // 获取点击位置,或者回退到页面中间
  const x = event instanceof MouseEvent ? event?.clientX / 2 : innerWidth;
  console.log(x);
  const y = event instanceof MouseEvent ? event?.clientY / 2 : innerHeight;
  // 获取到最远角的距离
  const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
  const circlePath = [`circle(0 at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`];

  // 执行主题切换
  const transition = document.startViewTransition(() => {
    setIsDarkMode(checked);
  });

  // 监听过渡动画的就绪状态
  transition.ready.then(() => {
    document.documentElement.animate(
      {
        clipPath: checked ? circlePath : [...circlePath].reverse(),
      },
      {
        duration: 1000,
        easing: "ease-in",
        pseudoElement: checked ? "::view-transition-new(root)" : "::view-transition-old(root)",
      }
    );
  });
};

document.startViewTransition:执行 dom 更改代码,在 React 中则为发起渲染更新。

transition.ready.then:前后两张快照之间的过渡动画。

  1. 配置全局样式

为了确保 View Transitions 正常工作,需要添加一些 CSS 规则:

css 复制代码
/** Animated Theme Toggle */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

.dark::view-transition-old(root) {
  z-index: 1;
}

.dark::view-transition-new(root) {
  z-index: 999;
}

::view-transition-old(root) {
  z-index: 999;
}

::view-transition-new(root) {
  z-index: 1;
}

总结

  • 核心思路:利用 View Transitions API,通过 clipPath 创建动态扩散动画。
  • 动画细节:根据鼠标点击位置,计算扩散路径,使视觉效果更自然。
  • 兼容性:目前 View Transitions 主要支持 Chrome 111+,其他浏览器支持情况可参考 Can I Use。

这种方式不仅提升了用户体验,还让主题切换更加流畅和现代化。🚀

参考资料

developer.mozilla.org/zh-CN/docs/...

ant.design/index-cn/

相关推荐
Anlici33 分钟前
跨域解决方案还有优劣!?
前端·面试
庸俗今天不摸鱼38 分钟前
【万字总结】构建现代Web应用的全方位性能优化体系学习指南(二)
前端·性能优化·webp
追寻光1 小时前
Java 绘制图形验证码
java·前端
前端snow1 小时前
爬取数据利用node也行,你知道吗?
前端·javascript·后端
村头一颗草1 小时前
高德爬取瓦片和vue2使用
前端·javascript·vue.js
远山无期1 小时前
vue3+vite项目接入qiankun微前端关键点
前端·vue.js
陈随易1 小时前
告别Node.js:2025年,我为何全面拥抱Bun
前端·后端·程序员
还是鼠鼠1 小时前
Node.js--exports 对象详解:用法、示例与最佳实践
前端·javascript·vscode·node.js·web
CQU_JIAKE1 小时前
2.5[frontEnd]
前端
Moment1 小时前
前端性能指标 —— FMP
前端·javascript·面试