This commit is contained in:
parent
e84a897619
commit
a90997d12d
@ -43,6 +43,7 @@
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^6.4.0",
|
||||
"eslint-plugin-vue": "^9.27.0",
|
||||
"less": "^4.2.0",
|
||||
"naive-ui": "^2.39.0",
|
||||
"postcss": "^8.4.45",
|
||||
"prettier": "^3.3.3",
|
||||
|
91
src/App.vue
91
src/App.vue
@ -49,9 +49,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import hljs from 'highlight.js/lib/core'
|
||||
import ini from 'highlight.js/lib/languages/ini'
|
||||
import { computed } from "vue";
|
||||
import hljs from "highlight.js/lib/core";
|
||||
import ini from "highlight.js/lib/languages/ini";
|
||||
|
||||
import {
|
||||
darkTheme,
|
||||
@ -63,14 +63,78 @@ import {
|
||||
NMessageProvider,
|
||||
NNotificationProvider,
|
||||
useOsTheme,
|
||||
zhCN
|
||||
} from 'naive-ui'
|
||||
zhCN,
|
||||
} from "naive-ui";
|
||||
// import Lottie from "./components/Lottie.vue";
|
||||
import DefaultLayout from './layouts/DefaultLayout.vue'
|
||||
import { useUserStore } from './stores/user'
|
||||
import DefaultLayout from "./layouts/DefaultLayout.vue";
|
||||
import { useUserStore } from "./stores/user";
|
||||
import { useAppStore } from "./stores/app";
|
||||
|
||||
const osThemeRef = useOsTheme()
|
||||
const theme = computed(() => (osThemeRef.value === 'dark' ? darkTheme : null))
|
||||
const appStore = useAppStore();
|
||||
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)
|
||||
//
|
||||
@ -87,7 +151,7 @@ const theme = computed(() => (osThemeRef.value === 'dark' ? darkTheme : null))
|
||||
// load_step.value = 2
|
||||
// }
|
||||
|
||||
hljs.registerLanguage('ini', ini)
|
||||
hljs.registerLanguage("ini", ini);
|
||||
|
||||
// 主题调整
|
||||
/**
|
||||
@ -109,13 +173,10 @@ const themeOverrides = {
|
||||
common: {
|
||||
fontFamily: "Noto Sans SC, sans-serif",
|
||||
fontFamilyMono: "JetBrains Mono, monospace",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
// UserStore
|
||||
const userStore = useUserStore();
|
||||
userStore.setupTimer();
|
||||
|
||||
</script>
|
||||
|
@ -37,6 +37,7 @@
|
||||
<div
|
||||
@click="showDrawer = true"
|
||||
class="cursor-pointer ml-3 flex justify-center items-center"
|
||||
ref="leftMenu"
|
||||
>
|
||||
<n-icon size="24">
|
||||
<menu-outline />
|
||||
@ -61,6 +62,7 @@
|
||||
<img
|
||||
:src="leaflowpng"
|
||||
class="w-8 cursor-pointer block select-none"
|
||||
ref="centerLogo"
|
||||
@click="toggleHomeChat"
|
||||
/>
|
||||
</div>
|
||||
@ -76,18 +78,14 @@
|
||||
</div>
|
||||
</n-grid-item>
|
||||
|
||||
<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"
|
||||
class="flex items-center">
|
||||
<div v-if="userStore.logined" class="flex items-center">
|
||||
<!-- 新对话 -->
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-icon
|
||||
class="text-2xl mr-4 cursor-pointer"
|
||||
@click="newChat"
|
||||
>
|
||||
<n-icon class="text-2xl mr-4 cursor-pointer" @click="newChat">
|
||||
<AddOutline />
|
||||
</n-icon>
|
||||
</template>
|
||||
@ -216,8 +214,10 @@ import leaflowpng from "@/assets/images/leaflow.png";
|
||||
import { useChatStore } from "@/stores/chat";
|
||||
import groupPng from "@/assets/images/group.png";
|
||||
import config from "@/config/config";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const appStore = useAppStore();
|
||||
const chatStore = useChatStore();
|
||||
const isMobile = useIsMobile();
|
||||
const showDrawer = ref(false);
|
||||
@ -253,4 +253,40 @@ const newChat = () => {
|
||||
const gotoLogin = () => {
|
||||
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>
|
||||
|
@ -2,7 +2,8 @@ const meta = document.createElement("meta");
|
||||
meta.name = "naive-ui-style";
|
||||
document.head.appendChild(meta);
|
||||
|
||||
import "./style.css";
|
||||
import "./styles/style.css";
|
||||
import "./styles/color.less";
|
||||
import "animate.css";
|
||||
import { registerPlugins } from "./plugins";
|
||||
import router from "./router";
|
||||
|
@ -9,5 +9,9 @@ export const useAppStore = defineStore("app", {
|
||||
contentScrollPosition: 0,
|
||||
contentScrollOnBottom: 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 "styles/github-markdown.css";
|
||||
@import "github-markdown.css";
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
Loading…
Reference in New Issue
Block a user