Skip to content

View Transitions

视图转换提供一种简单的方式创建一个过渡动画。

使用 document.startViewTransition(callback) 并传入一个回调函数,并在回调函数中变更 DOM,浏览器会自动为 DOM 元素添加过渡动画。

js
function updateView(event) {
  const target = event.target;

  const move = () => {
    // TODO...
  };

  // 不支持 View Transitions 时,直接调用 move()
  if (!document.startViewTransition) {
    move();
    return;
  }

  // 使用 View Transitions
  const transition = document.startViewTransition(() => move());
}

深色模式过渡

ViewTransitions.vue
vue
<script lang="ts" setup>
import { ref } from 'vue'
import Button from '../Button.vue'

const dark = ref(true)

function handleClick (e: MouseEvent) {
  const { clientX, clientY } = e

  document.documentElement.style.setProperty('--x', clientX + 'px')
  document.documentElement.style.setProperty('--y', clientY + 'px')
  if (document.startViewTransition) document.startViewTransition(() => {
    dark.value = !dark.value
  })
  else dark.value = !dark.value
}

</script>

<template>
  <div :class="{ 'view-transitions-dark': dark }">
    <div class="view-transitions-container b-1 b-solid b-rd-2 p-4">
      <div class="flex justify-center items-center m8">
        <Button @click="handleClick">切换</Button>
      </div>

      <div class="flex justify-center m8 flex-wrap gap8">
        <div v-for="i in 6" :key="i" class="w-1/4 aspect-video bg-blue-600 rd-2"></div>
      </div>
    </div>
  </div>
</template>

<style>
@keyframes view-transitions-clip {
  from {
    clip-path: circle(0% at var(--x) var(--y));
  }

  to {
    clip-path: circle(100% at var(--x) var(--y));
  }
}

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

::view-transition-new(root) {
  mix-blend-mode: normal;
  animation: view-transitions-clip .5s ease-in;
}

.view-transitions-container {
  background-color: white;
}

.view-transitions-dark .view-transitions-container {
  background-color: black;
}
</style>

参考资料