11<template >
2- <div class =" theme-toggle" @click.stop =" switchTheme" @keydown.enter.stop =" resolve(true)" >
3- <theme-switch v-model =" isDark" :before-change =" beforeChange" />
4- </div >
2+ <theme-switch ref =" switch" v-model =" isDark" class =" theme-toggle" :before-change =" beforeChange" />
53</template >
64
75<script >
@@ -13,55 +11,44 @@ export default {
1311 name: ' ThemeToggle' ,
1412 components: { ThemeSwitch },
1513 mixins: [dark],
16- data () {
17- return {
18- resolve: null ,
19- beforeChange : () =>
20- new Promise (resolve => {
21- this .resolve = resolve
22- }),
23- }
24- },
2514 methods: {
26- switchTheme (event ) {
27- if (! document .startViewTransition ) {
28- return this .resolve (true )
29- }
30-
31- const x = event .clientX
32- const y = event .clientY
33- const endRadius = Math .hypot (Math .max (x, innerWidth - x), Math .max (y, innerHeight - y))
34-
35- const transition = document .startViewTransition (async () => {
36- this .resolve (true )
37- await this .$nextTick ()
38- })
39-
40- transition .ready .then (() => {
41- const clipPath = [` circle(0px at ${ x} px ${ y} px)` , ` circle(${ endRadius} px at ${ x} px ${ y} px)` ]
42-
43- document .documentElement .animate (
44- {
45- clipPath: this .isDark ? [... clipPath].reverse () : clipPath,
46- },
47- {
48- duration: 400 ,
49- easing: ' ease-in' ,
50- pseudoElement: this .isDark ? ' ::view-transition-old(root)' : ' ::view-transition-new(root)' ,
51- }
52- )
15+ beforeChange () {
16+ return new Promise (resolve => {
17+ if (! document .startViewTransition ) {
18+ return resolve (true )
19+ }
20+
21+ const switchElement = this .$refs .switch ? .$el
22+ const rect = switchElement .getBoundingClientRect ()
23+ const x = rect .left + rect .width / 2
24+ const y = rect .top + rect .height / 2
25+ const endRadius = Math .hypot (Math .max (x, innerWidth - x), Math .max (y, innerHeight - y))
26+
27+ const transition = document .startViewTransition (async () => {
28+ resolve (true )
29+ await this .$nextTick ()
30+ })
31+
32+ transition .ready .then (() => {
33+ const clipPath = [` circle(0px at ${ x} px ${ y} px)` , ` circle(${ endRadius} px at ${ x} px ${ y} px)` ]
34+
35+ document .documentElement .animate (
36+ {
37+ clipPath: this .isDark ? [... clipPath].reverse () : clipPath,
38+ },
39+ {
40+ duration: 400 ,
41+ easing: ' ease-in' ,
42+ pseudoElement: this .isDark ? ' ::view-transition-old(root)' : ' ::view-transition-new(root)' ,
43+ }
44+ )
45+ })
5346 })
5447 },
5548 },
5649}
5750< / script>
5851
59- <style scoped>
60- .theme-toggle {
61- display : inline-block ;
62- }
63- </style >
64-
6552< style>
6653: : view- transition- new (root),
6754:: view- transition- old (root ) {
0 commit comments