使用两段代码,通过 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/

相关推荐
tuokuac29 分钟前
nginx配置前端请求转发到指定的后端ip
前端·tcp/ip·nginx
程序员爱钓鱼32 分钟前
Go语言实战案例-开发一个Markdown转HTML工具
前端·后端·go
万少1 小时前
鸿蒙创新赛 HarmonyOS 6.0.0(20) 关键特性汇总
前端
还有多远.1 小时前
jsBridge接入流程
前端·javascript·vue.js·react.js
蝶恋舞者1 小时前
web 网页数据传输处理过程
前端
非凡ghost1 小时前
FxSound:提升音频体验,让音乐更动听
前端·学习·音视频·生活·软件需求
吃饭最爱2 小时前
html的基础知识
前端·html
我没想到原来他们都是一堆坏人2 小时前
(未完待续...)如何编写一个用于构建python web项目镜像的dockerfile文件
java·前端·python
前端Hardy2 小时前
HTML&CSS:有趣的漂流瓶
前端·javascript·css
前端Hardy2 小时前
HTML&CSS :惊艳 UI 必备!卡片堆叠动画
前端·javascript·css