Skip to content

Commit

Permalink
feat: 增加主题切换动画
Browse files Browse the repository at this point in the history
  • Loading branch information
yulimchen committed Aug 13, 2024
1 parent 508bd5f commit 930637d
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 11 deletions.
4 changes: 2 additions & 2 deletions src/components/NavBar/index.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script setup lang="ts">
import { useDarkMode, useToggleDarkMode } from "@/hooks/useToggleDarkMode";
const onClickRight = () => {
useToggleDarkMode();
const onClickRight = (event: TouchEvent | MouseEvent) => {
useToggleDarkMode(event);
};
</script>

Expand Down
4 changes: 2 additions & 2 deletions src/hooks/useToggleDarkMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ export function useDarkMode() {
return useDarkModeStoreHook().darkMode;
}

export function useToggleDarkMode() {
useDarkModeStoreHook().toggleDarkMode();
export function useToggleDarkMode(event?: TouchEvent | MouseEvent) {
useDarkModeStoreHook().toggleDarkMode(event);
}
67 changes: 60 additions & 7 deletions src/store/modules/darkMode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { defineStore } from "pinia";
import { store } from "@/store";
import { nextTick } from "vue";

const darkModeKey = "__dark_mode__";
const isDarkMode = () => {
Expand All @@ -17,15 +18,67 @@ export const useDarkModeStore = defineStore({
darkMode: isDarkMode()
}),
actions: {
toggleDarkMode() {
this.darkMode = !this.darkMode;
if (this.darkMode) {
document.documentElement.classList.add("dark");
window.localStorage.setItem(darkModeKey, "true");
toggleDarkMode(event?: TouchEvent | MouseEvent) {
const isAppearanceTransition =
"startViewTransition" in document &&
!window.matchMedia("(prefers-reduced-motion: reduce)").matches;

const toggle = () => {
this.darkMode = !this.darkMode;
if (this.darkMode) {
document.documentElement.classList.add("dark");
window.localStorage.setItem(darkModeKey, "true");
} else {
document.documentElement.classList.remove("dark");
window.localStorage.setItem(darkModeKey, "false");
}
};

if (!isAppearanceTransition) {
toggle();
return;
}

let x: number, y: number;
if (event instanceof TouchEvent) {
x = event.touches[0].clientX;
y = event.touches[0].clientY;
} else if (event instanceof MouseEvent) {
x = event.clientX;
y = event.clientY;
} else {
document.documentElement.classList.remove("dark");
window.localStorage.setItem(darkModeKey, "false");
// 如果没有事件对象,使用屏幕右上角作为默认位置
x = window.innerWidth;
y = 0;
}
const endRadius = Math.hypot(
Math.max(x, window.innerWidth - x),
Math.max(y, window.innerHeight - y)
);

const transition = (document as any).startViewTransition(async () => {
toggle();
await nextTick();
});

transition.ready.then(() => {
const clipPath = [
`circle(0px at ${x}px ${y}px)`,
`circle(${endRadius}px at ${x}px ${y}px)`
];
document.documentElement.animate(
{
clipPath: this.darkMode ? [...clipPath].reverse() : clipPath
},
{
duration: 400,
easing: "ease-out",
pseudoElement: this.darkMode
? "::view-transition-old(root)"
: "::view-transition-new(root)"
}
);
});
}
}
});
Expand Down
19 changes: 19 additions & 0 deletions src/styles/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,22 @@ a:hover {
color: inherit;
text-decoration: none;
}

// see https://github.com/vuejs/vitepress/pull/2347
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
::view-transition-old(root) {
z-index: 1;
}
::view-transition-new(root) {
z-index: 9999;
}
.dark::view-transition-old(root) {
z-index: 9999;
}
.dark::view-transition-new(root) {
z-index: 1;
}

0 comments on commit 930637d

Please sign in to comment.