JavaScript is required
Blog About

圆形路径页面过渡的代码整理

2024/05/21
3 mins read
See this issue
# Javascript
# CSS
Back

记录一下本站点的圆形过渡动画的实现代码,该功能参考自antfu.me 有略微修改

export const isDark = useDark()

export function toggleDark(event: MouseEvent) {
  // @ts-expect-error experimental API
  const isAppearanceTransition = document.startViewTransition
    && !window.matchMedia('(prefers-reduced-motion: reduce)').matches

  if (!isAppearanceTransition) {
    isDark.value = !isDark.value
    return
  }

  // @ts-expect-error: Transition API
  const transition = document.startViewTransition(async () => {
    isDark.value = !isDark.value
  })
  transition.ready
      .then(() => {
        const isDark = document.documentElement.classList.contains("dark");

        const x = event.clientX
        const y = event.clientY
        const radius = Math.hypot(
          Math.max(x, innerWidth - x),
          Math.max(y, innerHeight - y),
        )

        const clipPath = [
          `circle(0px at ${x}px ${y}px)`,
          `circle(${radius}px at ${x}px ${y}px)`,
        ]
        document.documentElement.animate(
          {
            clipPath: isDark
              ? [...clipPath].reverse()
              : clipPath,
          },
          {
            duration: 400,
            easing: 'ease-out',
            pseudoElement: isDark
              ? '::view-transition-old(root)'
              : '::view-transition-new(root)',
          },
        )
      })
}

需要设置::view-transition伪元素层级样式

::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
}

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