This commit is contained in:
parent
e84a897619
commit
a90997d12d
@ -43,6 +43,7 @@
|
|||||||
"eslint-plugin-node": "^11.1.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"eslint-plugin-promise": "^6.4.0",
|
"eslint-plugin-promise": "^6.4.0",
|
||||||
"eslint-plugin-vue": "^9.27.0",
|
"eslint-plugin-vue": "^9.27.0",
|
||||||
|
"less": "^4.2.0",
|
||||||
"naive-ui": "^2.39.0",
|
"naive-ui": "^2.39.0",
|
||||||
"postcss": "^8.4.45",
|
"postcss": "^8.4.45",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
|
91
src/App.vue
91
src/App.vue
@ -49,9 +49,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue'
|
import { computed } from "vue";
|
||||||
import hljs from 'highlight.js/lib/core'
|
import hljs from "highlight.js/lib/core";
|
||||||
import ini from 'highlight.js/lib/languages/ini'
|
import ini from "highlight.js/lib/languages/ini";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
darkTheme,
|
darkTheme,
|
||||||
@ -63,14 +63,78 @@ import {
|
|||||||
NMessageProvider,
|
NMessageProvider,
|
||||||
NNotificationProvider,
|
NNotificationProvider,
|
||||||
useOsTheme,
|
useOsTheme,
|
||||||
zhCN
|
zhCN,
|
||||||
} from 'naive-ui'
|
} from "naive-ui";
|
||||||
// import Lottie from "./components/Lottie.vue";
|
// import Lottie from "./components/Lottie.vue";
|
||||||
import DefaultLayout from './layouts/DefaultLayout.vue'
|
import DefaultLayout from "./layouts/DefaultLayout.vue";
|
||||||
import { useUserStore } from './stores/user'
|
import { useUserStore } from "./stores/user";
|
||||||
|
import { useAppStore } from "./stores/app";
|
||||||
|
|
||||||
const osThemeRef = useOsTheme()
|
const appStore = useAppStore();
|
||||||
const theme = computed(() => (osThemeRef.value === 'dark' ? darkTheme : null))
|
const osThemeRef = useOsTheme();
|
||||||
|
|
||||||
|
let switched = false;
|
||||||
|
|
||||||
|
const theme = computed(() => {
|
||||||
|
if (switched && document.startViewTransition) {
|
||||||
|
switch_appearance_with_transitions(osThemeRef.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
switched = true;
|
||||||
|
|
||||||
|
if (osThemeRef.value === "dark") {
|
||||||
|
document.documentElement.setAttribute("theme", "dark");
|
||||||
|
return darkTheme;
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute("theme", "light");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 这个函数是点击事件的回调函数,带有参数 event
|
||||||
|
const switch_appearance_with_transitions = (toColor) => {
|
||||||
|
const transition = document.startViewTransition(() => {});
|
||||||
|
|
||||||
|
// 获取点击位置,作为圆心,根据页面大小计算半径
|
||||||
|
let x = appStore.headerCenterLogoPosition.x;
|
||||||
|
let y = appStore.headerCenterLogoPosition.y;
|
||||||
|
|
||||||
|
if (toColor === "dark") {
|
||||||
|
// 获取可视区域的宽高
|
||||||
|
const innerWidth = window.innerWidth;
|
||||||
|
const innerHeight = window.innerHeight;
|
||||||
|
|
||||||
|
x = innerWidth / 2;
|
||||||
|
y = innerHeight - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(x, y);
|
||||||
|
const endRadius = Math.hypot(
|
||||||
|
Math.max(x, innerWidth - x),
|
||||||
|
Math.max(y, innerHeight - y)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 等待伪元素创建完成:
|
||||||
|
transition.ready.then(() => {
|
||||||
|
// 新视图的根元素动画:构造一个圆形作为裁切,并且半径会从0开始放大到endRadius
|
||||||
|
document.documentElement.animate(
|
||||||
|
{
|
||||||
|
clipPath: [
|
||||||
|
`circle(0 at ${x}px ${y}px)`,
|
||||||
|
`circle(${endRadius}px at ${x}px ${y}px)`,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
duration: 500,
|
||||||
|
easing: "ease-in",
|
||||||
|
// 指定要附加动画的伪元素
|
||||||
|
pseudoElement: "::view-transition-new(root)",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// watch theme change
|
||||||
|
|
||||||
// const load_step = ref(1)
|
// const load_step = ref(1)
|
||||||
//
|
//
|
||||||
@ -87,7 +151,7 @@ const theme = computed(() => (osThemeRef.value === 'dark' ? darkTheme : null))
|
|||||||
// load_step.value = 2
|
// load_step.value = 2
|
||||||
// }
|
// }
|
||||||
|
|
||||||
hljs.registerLanguage('ini', ini)
|
hljs.registerLanguage("ini", ini);
|
||||||
|
|
||||||
// 主题调整
|
// 主题调整
|
||||||
/**
|
/**
|
||||||
@ -109,13 +173,10 @@ const themeOverrides = {
|
|||||||
common: {
|
common: {
|
||||||
fontFamily: "Noto Sans SC, sans-serif",
|
fontFamily: "Noto Sans SC, sans-serif",
|
||||||
fontFamilyMono: "JetBrains Mono, monospace",
|
fontFamilyMono: "JetBrains Mono, monospace",
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// UserStore
|
// UserStore
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
userStore.setupTimer();
|
userStore.setupTimer();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
<div
|
<div
|
||||||
@click="showDrawer = true"
|
@click="showDrawer = true"
|
||||||
class="cursor-pointer ml-3 flex justify-center items-center"
|
class="cursor-pointer ml-3 flex justify-center items-center"
|
||||||
|
ref="leftMenu"
|
||||||
>
|
>
|
||||||
<n-icon size="24">
|
<n-icon size="24">
|
||||||
<menu-outline />
|
<menu-outline />
|
||||||
@ -61,6 +62,7 @@
|
|||||||
<img
|
<img
|
||||||
:src="leaflowpng"
|
:src="leaflowpng"
|
||||||
class="w-8 cursor-pointer block select-none"
|
class="w-8 cursor-pointer block select-none"
|
||||||
|
ref="centerLogo"
|
||||||
@click="toggleHomeChat"
|
@click="toggleHomeChat"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -79,15 +81,11 @@
|
|||||||
<n-grid-item class="flex items-center justify-end mr-1.5">
|
<n-grid-item class="flex items-center justify-end mr-1.5">
|
||||||
<!-- 右侧 -->
|
<!-- 右侧 -->
|
||||||
|
|
||||||
<div v-if="userStore.logined"
|
<div v-if="userStore.logined" class="flex items-center">
|
||||||
class="flex items-center">
|
|
||||||
<!-- 新对话 -->
|
<!-- 新对话 -->
|
||||||
<n-tooltip trigger="hover">
|
<n-tooltip trigger="hover">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-icon
|
<n-icon class="text-2xl mr-4 cursor-pointer" @click="newChat">
|
||||||
class="text-2xl mr-4 cursor-pointer"
|
|
||||||
@click="newChat"
|
|
||||||
>
|
|
||||||
<AddOutline />
|
<AddOutline />
|
||||||
</n-icon>
|
</n-icon>
|
||||||
</template>
|
</template>
|
||||||
@ -216,8 +214,10 @@ import leaflowpng from "@/assets/images/leaflow.png";
|
|||||||
import { useChatStore } from "@/stores/chat";
|
import { useChatStore } from "@/stores/chat";
|
||||||
import groupPng from "@/assets/images/group.png";
|
import groupPng from "@/assets/images/group.png";
|
||||||
import config from "@/config/config";
|
import config from "@/config/config";
|
||||||
|
import { useAppStore } from "@/stores/app";
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
const chatStore = useChatStore();
|
const chatStore = useChatStore();
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const showDrawer = ref(false);
|
const showDrawer = ref(false);
|
||||||
@ -253,4 +253,40 @@ const newChat = () => {
|
|||||||
const gotoLogin = () => {
|
const gotoLogin = () => {
|
||||||
router.push("/auth/login");
|
router.push("/auth/login");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const leftMenu = ref();
|
||||||
|
const centerLogo = ref();
|
||||||
|
|
||||||
|
const setCirclePosition = () => {
|
||||||
|
if (isMobile.value) {
|
||||||
|
// 获取 leftMenu 的位置
|
||||||
|
const leftMenuRect = leftMenu.value.getBoundingClientRect();
|
||||||
|
|
||||||
|
// 计算元素的正中心
|
||||||
|
const centerX = leftMenuRect.x + leftMenuRect.width / 2;
|
||||||
|
const centerY = leftMenuRect.y + leftMenuRect.height / 2;
|
||||||
|
|
||||||
|
appStore.headerCenterLogoPosition.x = centerX;
|
||||||
|
appStore.headerCenterLogoPosition.y = centerY;
|
||||||
|
} else {
|
||||||
|
// 获取 centerLogo 的位置
|
||||||
|
const centerLogoRect = centerLogo.value.getBoundingClientRect();
|
||||||
|
|
||||||
|
// 计算元素的正中心
|
||||||
|
const centerX = centerLogoRect.x + centerLogoRect.width / 2;
|
||||||
|
const centerY = centerLogoRect.y + centerLogoRect.height / 2;
|
||||||
|
appStore.headerCenterLogoPosition.x = centerX;
|
||||||
|
appStore.headerCenterLogoPosition.y = centerY;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
setCirclePosition();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("resize", setCirclePosition);
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener("resize", setCirclePosition);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -2,7 +2,8 @@ const meta = document.createElement("meta");
|
|||||||
meta.name = "naive-ui-style";
|
meta.name = "naive-ui-style";
|
||||||
document.head.appendChild(meta);
|
document.head.appendChild(meta);
|
||||||
|
|
||||||
import "./style.css";
|
import "./styles/style.css";
|
||||||
|
import "./styles/color.less";
|
||||||
import "animate.css";
|
import "animate.css";
|
||||||
import { registerPlugins } from "./plugins";
|
import { registerPlugins } from "./plugins";
|
||||||
import router from "./router";
|
import router from "./router";
|
||||||
|
@ -9,5 +9,9 @@ export const useAppStore = defineStore("app", {
|
|||||||
contentScrollPosition: 0,
|
contentScrollPosition: 0,
|
||||||
contentScrollOnBottom: false,
|
contentScrollOnBottom: false,
|
||||||
contentScrollable: false,
|
contentScrollable: false,
|
||||||
|
headerCenterLogoPosition: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
82
src/styles/color.less
Normal file
82
src/styles/color.less
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// // light-dark-8deg-animation
|
||||||
|
// @keyframes light-to-dark {
|
||||||
|
// from {
|
||||||
|
// clip-path: polygon(
|
||||||
|
// 0 0,
|
||||||
|
// 0 0,
|
||||||
|
// calc(tan(8deg) * -100vh) 100%,
|
||||||
|
// calc(tan(8deg) * -100vh) 100%
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// to {
|
||||||
|
// clip-path: polygon(
|
||||||
|
// 0 0,
|
||||||
|
// calc((tan(8deg) * 100vh) + 100%) 0,
|
||||||
|
// 100% 100%,
|
||||||
|
// calc(tan(8deg) * -100vh) 100%
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @keyframes dark-to-light {
|
||||||
|
// from {
|
||||||
|
// clip-path: polygon(
|
||||||
|
// calc((tan(8deg) * 100vh) + 100%) 0,
|
||||||
|
// calc((tan(8deg) * 100vh) + 100%) 0,
|
||||||
|
// 100% 100%,
|
||||||
|
// 100% 100%
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// to {
|
||||||
|
// clip-path: polygon(
|
||||||
|
// 0 0,
|
||||||
|
// calc((tan(8deg) * 100vh) + 100%) 0,
|
||||||
|
// 100% 100%,
|
||||||
|
// calc(tan(8deg) * -100vh) 100%
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// :root::view-transition-group(root) {
|
||||||
|
// animation-duration: 1s;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// :root::view-transition-new(root),
|
||||||
|
// :root::view-transition-old(root) {
|
||||||
|
// mix-blend-mode: normal;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// :root::view-transition-old(root),
|
||||||
|
// :root[theme="dark"]::view-transition-old(root) {
|
||||||
|
// animation: none;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// :root::view-transition-new(root) {
|
||||||
|
// animation-name: dark-to-light;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// :root[theme="dark"]::view-transition-new(root) {
|
||||||
|
// animation-name: light-to-dark;
|
||||||
|
// }
|
||||||
|
|
||||||
|
::view-transition-old(root),
|
||||||
|
::view-transition-new(root) {
|
||||||
|
animation: none;
|
||||||
|
mix-blend-mode: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[theme="dark"]::view-transition-old(root) {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
:root[theme="light"]::view-transition-new(root) {
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
::view-transition-old(root) {
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
::view-transition-new(root) {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100..900&display=swap");
|
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100..900&display=swap");
|
||||||
@import "styles/github-markdown.css";
|
@import "github-markdown.css";
|
||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
Loading…
Reference in New Issue
Block a user