Merge pull request #187 from imsyy/dev

feat: 同步开发分支
This commit is contained in:
底层用户 2023-08-17 13:42:13 +08:00 committed by GitHub
commit 8ca5343c5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 1043 additions and 4706 deletions

21
.env
View File

@ -1,15 +1,12 @@
# 站点名称 # 站点信息
VITE_SITE_NAME = "無名の主页" VITE_SITE_NAME = "無名の主页" # 名称
VITE_SITE_ANTHOR = "無名" VITE_SITE_ANTHOR = "無名" # 作者
VITE_SITE_KEYWORDS = "無名,个人主页" VITE_SITE_KEYWORDS = "無名,个人主页" # 关键词
VITE_SITE_DES = "一个默默无闻的主页" VITE_SITE_DES = "一个默默无闻的主页" # 站点简介
VITE_SITE_URL = "imsyy.top" VITE_SITE_URL = "imsyy.top" # 作者地址
VITE_SITE_LOGO = "/images/icon/favicon.ico" VITE_SITE_LOGO = "/images/icon/favicon.ico" # 站点主图标
VITE_SITE_APPLE_LOGO = "/images/logo/apple-touch-icon.png" VITE_SITE_MAIN_LOGO = "/images/icon/logo.png" # 主页图标
VITE_SITE_APPLE_LOGO = "/images/logo/apple-touch-icon.png" # Apple 端图标
# 百度统计
## 若不需要,请设为空即可
VITE_SITE_BAIDUTONGJI = "14e9f35ff8bc67fd4bcb5f07a6e6655a"
# 简介文本 # 简介文本
VITE_DESC_HELLO = "Hello World !" VITE_DESC_HELLO = "Hello World !"

View File

@ -6,57 +6,28 @@
<meta http-equiv="Access-Control-Allow-Origin" content="*"> <meta http-equiv="Access-Control-Allow-Origin" content="*">
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> --> <!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="<%- logo %>"> <link rel="icon" href="%VITE_SITE_LOGO%">
<link rel="apple-touch-icon" href="<%- appleLogo %>" /> <link rel="apple-touch-icon" href="%VITE_SITE_APPLE_LOGO%" />
<link rel="bookmark" href="<%- appleLogo %>" /> <link rel="bookmark" href="%VITE_SITE_APPLE_LOGO%" />
<link rel="apple-touch-icon-precomposed" sizes="200x200" href="<%- appleLogo %>" /> <link rel="apple-touch-icon-precomposed" sizes="200x200" href="%VITE_SITE_APPLE_LOGO%" />
<meta name="description" content="<%- description %>" /> <meta name="description" content="%VITE_SITE_DES%" />
<meta name="keywords" content="<%- keywords %>" /> <meta name="keywords" content="%VITE_SITE_KEYWORDS%" />
<meta name="author" content="<%- author %>" /> <meta name="author" content="%VITE_SITE_ANTHOR%" />
<meta name="theme-color" content="#424242" /> <meta name="theme-color" content="#424242" />
<title><%- title %></title> <title>%VITE_SITE_NAME%</title>
<!-- HarmonyOS Sans --> <!-- HarmonyOS Sans -->
<!-- 本站 CDN 已开启防盗链,非本站域名不可访问,请更改链接为下方内容,否则自定义字体将失效 --> <!-- 本站 CDN 已开启防盗链,非本站域名不可访问,请更改链接为下方内容,否则自定义字体将失效 -->
<!-- https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css --> <link rel="stylesheet" href="https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css" />
<link rel="stylesheet" href="https://cdn.imsyy.top/gh/imsyy/file/font/HarmonyOS_Sans/regular.min.css" /> <!-- <link rel="stylesheet" href="https://cdn.imsyy.top/gh/imsyy/file/font/HarmonyOS_Sans/regular.min.css" /> -->
<link rel="stylesheet" href="/loading/loading.min.css">
<!-- IE Out --> <!-- IE Out -->
<script> <script>
if ( /*@cc_on!@*/ false || (!!window.MSInputMethodContext && !!document.documentMode)) if ( /*@cc_on!@*/ false || (!!window.MSInputMethodContext && !!document.documentMode))
window.location.href = window.location.href =
"https://support.dmeng.net/upgrade-your-browser.html?referrer=" + encodeURIComponent(window.location.href) "https://support.dmeng.net/upgrade-your-browser.html?referrer=" + encodeURIComponent(window.location.href)
</script> </script>
<% if (tongji) { %>
<!-- 百度统计 -->
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?<%- tongji %>";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<% } %>
</head> </head>
<body class="loading"> <body>
<!--加载动画-->
<div id="loading-box">
<div class="loading-left-bg"></div>
<div class="loading-right-bg"></div>
<div class="spinner-box">
<div class="loader">
<div class="inner one"></div>
<div class="inner two"></div>
<div class="inner three"></div>
</div>
<div class="loading-word">
<p class="loading-title" id="loading-title"><%- title %></p>
<span id="loading-text">加载中</span>
</div>
</div>
</div>
<!-- 主体内容 --> <!-- 主体内容 -->
<div id="app"></div> <div id="app"></div>
<!-- noscript --> <!-- noscript -->

View File

@ -4,7 +4,7 @@
"github": "https://github.com/imsyy/home", "github": "https://github.com/imsyy/home",
"home": "https://imsyy.top", "home": "https://imsyy.top",
"private": true, "private": true,
"version": "4.0.5", "version": "4.1.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite --host", "dev": "vite --host",
@ -12,7 +12,6 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@icon-park/vue-next": "^1.4.2",
"aplayer": "^1.10.1", "aplayer": "^1.10.1",
"axios": "^1.1.3", "axios": "^1.1.3",
"element-plus": "^2.2.18", "element-plus": "^2.2.18",
@ -20,20 +19,20 @@
"pinia": "^2.0.23", "pinia": "^2.0.23",
"pinia-plugin-persistedstate": "^3.0.0", "pinia-plugin-persistedstate": "^3.0.0",
"swiper": "^9.3.2", "swiper": "^9.3.2",
"terser": "^5.16.1", "vue": "^3.3.4",
"vue": "^3.2.37",
"vue3-aplayer": "^1.7.3" "vue3-aplayer": "^1.7.3"
}, },
"devDependencies": { "devDependencies": {
"@icon-park/vue-next": "^1.4.2",
"@vicons/fa": "^0.12.0", "@vicons/fa": "^0.12.0",
"@vicons/material": "^0.12.0",
"@vicons/utils": "^0.1.4", "@vicons/utils": "^0.1.4",
"@vitejs/plugin-vue": "^3.1.0", "@vitejs/plugin-vue": "^4.2.3",
"sass": "^1.55.0", "sass": "^1.55.0",
"terser": "^5.16.1",
"unplugin-auto-import": "^0.11.2", "unplugin-auto-import": "^0.11.2",
"unplugin-vue-components": "^0.22.8", "unplugin-vue-components": "^0.22.8",
"vite": "^3.1.0", "vite": "^4.4.5",
"vite-plugin-html": "^3.2.0", "vite-plugin-compression": "^0.5.1",
"vite-plugin-pwa": "^0.14.1" "vite-plugin-pwa": "^0.14.1"
} }
} }

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

View File

@ -1,141 +0,0 @@
* {
margin: 0;
padding: 0;
}
#loading-box .loading-left-bg,
#loading-box .loading-right-bg {
position: fixed;
z-index: 999;
width: 50%;
height: 100%;
background-color: #515151e0;
transition: all 0.75s cubic-bezier(0.42, 0, 0, 1.01);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
}
#loading-box .loading-right-bg {
right: 0;
}
#loading-box > .spinner-box {
position: fixed;
z-index: 999999;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
#loading-box .spinner-box .loading-word {
position: absolute;
color: #ffffff;
font-size: 0.95rem;
transform: translateY(64px);
text-align: center;
}
.loading-title {
font-size: 1.25rem;
margin: 20px 10px 4px 10px;
}
#loading-box .spinner-box .configure-core {
width: 100%;
height: 100%;
background-color: #37474f;
}
/* 加载完成 */
.loaded .loading-left-bg {
transform: translate(-100%, 0);
}
.loaded .loading-right-bg {
transform: translate(100%, 0);
}
.loaded .spinner-box {
display: none !important;
}
.loader {
position: absolute;
top: calc(50% - 32px);
left: calc(50% - 32px);
width: 64px;
height: 64px;
border-radius: 50%;
perspective: 800px;
transition: all 0.7s cubic-bezier(0.42, 0, 0, 1.01);
}
.inner {
position: absolute;
box-sizing: border-box;
width: 100%;
height: 100%;
border-radius: 50%;
}
.inner.one {
left: 0%;
top: 0%;
animation: rotate-one 1s linear infinite;
border-bottom: 3px solid #efeffa;
}
.inner.two {
right: 0%;
top: 0%;
animation: rotate-two 1s linear infinite;
border-right: 3px solid #efeffa;
}
.inner.three {
right: 0%;
bottom: 0%;
animation: rotate-three 1s linear infinite;
border-top: 3px solid #efeffa;
}
noscript {
z-index: 1000;
position: absolute;
display: flex;
justify-content: center;
width: 100%;
margin-top: 26px;
}
@keyframes rotate-one {
0% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(-45deg) rotateZ(360deg);
}
}
@keyframes rotate-two {
0% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(0deg);
}
100% {
transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
}
}
@keyframes rotate-three {
0% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(0deg);
}
100% {
transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
}
}

View File

@ -1 +0,0 @@
*{margin:0;padding:0}#loading-box .loading-left-bg,#loading-box .loading-right-bg{position:fixed;z-index:999;width:50%;height:100%;background-color:#515151e0;transition:all .75s cubic-bezier(.42,0,0,1.01);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}#loading-box .loading-right-bg{right:0}#loading-box>.spinner-box{position:fixed;z-index:999999;display:flex;justify-content:center;align-items:center;width:100%;height:100vh}#loading-box .spinner-box .loading-word{position:absolute;color:#fff;font-size:.95rem;transform:translateY(64px);text-align:center}.loading-title{font-size:1.25rem;margin:20px 10px 4px 10px}#loading-box .spinner-box .configure-core{width:100%;height:100%;background-color:#37474f}.loaded .loading-left-bg{transform:translate(-100%,0)}.loaded .loading-right-bg{transform:translate(100%,0)}.loaded .spinner-box{display:none!important}.loader{position:absolute;top:calc(50% - 32px);left:calc(50% - 32px);width:64px;height:64px;border-radius:50%;perspective:800px;transition:all .7s cubic-bezier(.42,0,0,1.01)}.inner{position:absolute;box-sizing:border-box;width:100%;height:100%;border-radius:50%}.inner.one{left:0;top:0;animation:rotate-one 1s linear infinite;border-bottom:3px solid #efeffa}.inner.two{right:0;top:0;animation:rotate-two 1s linear infinite;border-right:3px solid #efeffa}.inner.three{right:0;bottom:0;animation:rotate-three 1s linear infinite;border-top:3px solid #efeffa}noscript{z-index:1000;position:absolute;display:flex;justify-content:center;width:100%;margin-top:26px}@keyframes rotate-one{0%{transform:rotateX(35deg) rotateY(-45deg) rotateZ(0)}100%{transform:rotateX(35deg) rotateY(-45deg) rotateZ(360deg)}}@keyframes rotate-two{0%{transform:rotateX(50deg) rotateY(10deg) rotateZ(0)}100%{transform:rotateX(50deg) rotateY(10deg) rotateZ(360deg)}}@keyframes rotate-three{0%{transform:rotateX(35deg) rotateY(55deg) rotateZ(0)}100%{transform:rotateX(35deg) rotateY(55deg) rotateZ(360deg)}}

View File

@ -1,9 +1,13 @@
<template> <template>
<div class="animate"> <!-- 加载 -->
<Background /> <Loading />
<main> <!-- 壁纸 -->
<Background @loadComplete="loadComplete" />
<!-- 主界面 -->
<Transition name="fade" mode="out-in">
<main id="main" v-if="store.imgLoadStatus">
<div class="container" v-show="!store.backgroundShow"> <div class="container" v-show="!store.backgroundShow">
<section class="main" v-show="!store.setOpenState"> <section class="all" v-show="!store.setOpenState">
<MainLeft /> <MainLeft />
<MainRight v-show="!store.boxOpenState" /> <MainRight v-show="!store.boxOpenState" />
<Box v-show="store.boxOpenState" /> <Box v-show="store.boxOpenState" />
@ -24,26 +28,27 @@
> >
<component :is="store.mobileOpenState ? CloseSmall : HamburgerButton" /> <component :is="store.mobileOpenState ? CloseSmall : HamburgerButton" />
</Icon> </Icon>
</main> <!-- 页脚 -->
<Transition name="fade" mode="out-in">
<Footer v-show="!store.backgroundShow && !store.setOpenState" /> <Footer v-show="!store.backgroundShow && !store.setOpenState" />
</div> </Transition>
</main>
</Transition>
</template> </template>
<script setup> <script setup>
import { onMounted, onBeforeUnmount, watch } from "vue";
import { helloInit, checkDays } from "@/utils/getTime.js"; import { helloInit, checkDays } from "@/utils/getTime.js";
import { HamburgerButton, CloseSmall } from "@icon-park/vue-next";
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import { Icon } from "@vicons/utils"; import { Icon } from "@vicons/utils";
import { HamburgerButton, CloseSmall } from "@icon-park/vue-next"; import Loading from "@/components/Loading.vue";
import MainLeft from "@/views/Main/Left.vue"; import MainLeft from "@/views/Main/Left.vue";
import MainRight from "@/views/Main/Right.vue"; import MainRight from "@/views/Main/Right.vue";
import Background from "@/components/Background/index.vue"; import Background from "@/components/Background.vue";
import Footer from "@/components/Footer/index.vue"; import Footer from "@/components/Footer.vue";
import Box from "@/views/Box/index.vue"; import Box from "@/views/Box/index.vue";
import MoreSet from "@/views/MoreSet/index.vue"; import MoreSet from "@/views/MoreSet/index.vue";
import cursorInit from "@/utils/cursor.js"; import cursorInit from "@/utils/cursor.js";
import config from "@/../package.json"; import config from "@/../package.json";
//
// import "@/utils/lantern.js";
const store = mainStore(); const store = mainStore();
@ -52,22 +57,29 @@ const getWidth = () => {
store.setInnerWidth(window.innerWidth); store.setInnerWidth(window.innerWidth);
}; };
onMounted(() => { //
// const loadComplete = () => {
cursorInit(); nextTick(() => {
//
window.addEventListener("load", () => {
console.log("加载完成");
//
document.getElementsByTagName("body")[0].className = "";
//
const loadingBox = document.getElementById("loading-box");
loadingBox.classList.add("loaded");
// //
helloInit(); helloInit();
// //
checkDays(); checkDays();
}); });
};
//
watch(
() => store.innerWidth,
(value) => {
if (value < 990) {
store.boxOpenState = false;
}
}
);
onMounted(() => {
//
cursorInit();
// //
document.oncontextmenu = () => { document.oncontextmenu = () => {
@ -116,31 +128,28 @@ onMounted(() => {
); );
}); });
//
watch(
() => store.innerWidth,
(value) => {
if (value < 990) {
store.boxOpenState = false;
}
}
);
onBeforeUnmount(() => { onBeforeUnmount(() => {
window.removeEventListener("resize", getWidth); window.removeEventListener("resize", getWidth);
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
main { #main {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: scale(1.2);
transition: transform 0.3s;
animation: fade-blur-main-in 0.65s cubic-bezier(0.25, 0.46, 0.45, 0.94)
forwards;
animation-delay: 0.5s;
.container { .container {
width: 100%; width: 100%;
height: 100vh; height: 100vh;
margin: 0 auto; margin: 0 auto;
@media (max-width: 1200px) { .all {
padding: 0 2vw;
}
.main {
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: 0 0.75rem; padding: 0 0.75rem;
@ -158,8 +167,10 @@ main {
background-color: #00000080; background-color: #00000080;
backdrop-filter: blur(20px); backdrop-filter: blur(20px);
z-index: 2; z-index: 2;
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s; }
@media (max-width: 1200px) {
padding: 0 2vw;
} }
} }
.menu { .menu {
@ -174,9 +185,8 @@ main {
background: rgb(0 0 0 / 20%); background: rgb(0 0 0 / 20%);
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
border-radius: 6px; border-radius: 6px;
transition: all 0.3s; transition: transform 0.3s;
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s;
&:active { &:active {
transform: scale(0.95); transform: scale(0.95);
} }
@ -188,23 +198,4 @@ main {
} }
} }
} }
//
.animate {
transform: scale(1);
transition: all ease 1.25s;
opacity: 1;
filter: blur(0);
width: 100%;
height: 100%;
}
.loading {
.animate {
transform: scale(1.2);
transition: all ease 1.25s;
opacity: 0;
filter: blur(10px);
}
}
</style> </style>

View File

@ -1,33 +1,45 @@
<template> <template>
<div class="cover"> <div class="cover">
<img class="bg" :src="bgUrl" alt="cover" /> <img
<div :class="store.backgroundShow ? 'gray sm' : 'gray'" /> v-show="store.imgLoadStatus"
<transition name="el-fade-in-linear"> class="bg"
alt="cover"
:src="bgUrl"
@load="imgLoadComplete"
@error.once="imgLoadError"
@animationend="imgAnimationEnd"
/>
<div :class="store.backgroundShow ? 'gray hidden' : 'gray'" />
<Transition name="fade" mode="out-in">
<a <a
v-if="store.backgroundShow && store.coverType != '3'"
class="down" class="down"
:href="bgUrl" :href="bgUrl"
target="_blank" target="_blank"
v-show="store.backgroundShow && store.coverType != '3'"
>下载壁纸</a
> >
</transition> 下载壁纸
</a>
</Transition>
</div> </div>
</template> </template>
<script setup> <script setup>
import { onMounted, ref, watch, h } from "vue";
import { SuccessPicture } from "@icon-park/vue-next";
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import { Error } from "@icon-park/vue-next";
const store = mainStore(); const store = mainStore();
const bgUrl = ref(null); // const bgUrl = ref(null);
const imgTimeout = ref(null);
const emit = defineEmits(["loadComplete"]);
//
// Math.random()
const bgRandom = Math.floor(Math.random() * 10 + 1);
// //
const changeBg = (type) => { const changeBg = (type) => {
if (type == 0) { if (type == 0) {
bgUrl.value = `/images/background${Math.floor( bgUrl.value = `/images/background${bgRandom}.jpg`;
Math.random() * 10 + 1
)}.webp`;
} else if (type == 1) { } else if (type == 1) {
bgUrl.value = "https://api.dujin.org/bing/1920.php"; bgUrl.value = "https://api.dujin.org/bing/1920.php";
} else if (type == 2) { } else if (type == 2) {
@ -37,25 +49,41 @@ const changeBg = (type) => {
} }
}; };
//
const imgLoadComplete = () => {
imgTimeout.value = setTimeout(() => {
store.setImgLoadStatus(true);
}, Math.floor(Math.random() * (600 - 300 + 1)) + 300);
};
//
const imgAnimationEnd = () => {
console.log("壁纸加载且动画完成");
//
emit("loadComplete");
};
//
const imgLoadError = () => {
console.error("壁纸加载失败:", bgUrl.value);
ElMessage({
message: "壁纸加载失败,已临时切换回默认",
icon: h(Error, {
theme: "filled",
fill: "#efefef",
}),
});
bgUrl.value = `/images/background${bgRandom}.jpg`;
};
onMounted(() => { onMounted(() => {
// //
changeBg(store.coverType); changeBg(store.coverType);
}); });
// onBeforeUnmount(() => {
watch( clearTimeout(imgTimeout.value);
() => store.coverType, });
(value) => {
changeBg(value);
ElMessage({
message: "壁纸设置成功",
icon: h(SuccessPicture, {
theme: "filled",
fill: "#efefef",
}),
});
}
);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -69,16 +97,17 @@ watch(
z-index: -1; z-index: -1;
.bg { .bg {
transform: scale(1);
filter: blur(0);
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover; object-fit: cover;
transition: all 1.5s ease 0s;
backface-visibility: hidden; backface-visibility: hidden;
filter: blur(20px) brightness(0.3);
transition: filter 0.3s, transform 0.3s;
animation: fade-blur-in 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
animation-delay: 0.45s;
} }
.gray { .gray {
opacity: 1; opacity: 1;
@ -94,7 +123,7 @@ watch(
radial-gradient(rgba(0, 0, 0, 0) 33%, rgba(0, 0, 0, 0.3) 166%); radial-gradient(rgba(0, 0, 0, 0) 33%, rgba(0, 0, 0, 0.3) 166%);
transition: 1.5s; transition: 1.5s;
&.sm { &.hidden {
opacity: 0; opacity: 0;
transition: 1.5s; transition: 1.5s;
} }
@ -125,20 +154,4 @@ watch(
} }
} }
} }
//
.loading {
.cover {
.bg {
transition: 1.5s;
transform: scale(1.1);
filter: blur(10px);
}
.gray {
transition: 1.5s;
opacity: 0;
}
}
}
</style> </style>

112
src/components/Footer.vue Normal file
View File

@ -0,0 +1,112 @@
<template>
<footer id="footer" :class="store.footerBlur ? 'blur' : null">
<Transition name="fade" mode="out-in">
<div v-if="!store.playerState || !store.playerLrcShow" class="power">
<span>
Copyright&nbsp;&copy;
<span v-if="siteStartDate?.length >= 4" class="site-start">
{{ siteStartDate.substring(0, 4) }}
-
</span>
{{ fullYear }}
<a :href="SiteUrl">{{ SiteAnthor }}</a>
</span>
<!-- 以下信息请不要修改哦 -->
<span class="hidden">
&amp;&nbsp;Made&nbsp;by
<a :href="config.github" target="_blank">
{{ config.author }}
</a>
</span>
<!-- 站点备案 -->
<a v-if="siteIcp" href="https://beian.miit.gov.cn" target="_blank">
&amp;
{{ siteIcp }}
</a>
</div>
<div v-else class="lrc">
<Transition name="fade" mode="out-in">
<div class="lrc-all" :key="store.getPlayerLrc">
<music-one theme="filled" size="18" fill="#efefef" />
<span class="lrc-text text-hidden" v-html="store.getPlayerLrc" />
<music-one theme="filled" size="18" fill="#efefef" />
</div>
</Transition>
</div>
</Transition>
</footer>
</template>
<script setup>
import { MusicOne } from "@icon-park/vue-next";
import { mainStore } from "@/store";
import config from "@/../package.json";
const store = mainStore();
const fullYear = new Date().getFullYear();
//
const siteStartDate = ref(import.meta.env.VITE_SITE_START);
const siteIcp = ref(import.meta.env.VITE_SITE_ICP);
const SiteAnthor = ref(import.meta.env.VITE_SITE_ANTHOR);
const SiteUrl = ref(import.meta.env.VITE_SITE_URL);
</script>
<style lang="scss" scoped>
#footer {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
height: 46px;
line-height: 46px;
text-align: center;
z-index: 0;
font-size: 14px;
.power {
animation: fade 0.3s;
}
.lrc {
padding: 0 20px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
.lrc-all {
width: 98%;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
.lrc-text {
margin: 0 8px;
}
.i-icon {
width: 18px;
height: 18px;
display: inherit;
}
}
}
&.blur {
backdrop-filter: blur(10px);
background: rgb(0 0 0 / 25%);
font-size: 16px;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.15s ease-in-out;
}
@media (max-width: 720px) {
font-size: 0.85rem;
&.blur {
font-size: 0.85rem;
}
}
@media (max-width: 480px) {
.hidden {
display: none;
}
}
}
</style>

View File

@ -1,101 +0,0 @@
<template>
<footer>
<div class="power" v-show="!store.playerState">
<span>
Copyright&nbsp;&copy;
<span v-if="siteStartDate?.length >= 4" class="site-start">
{{ siteStartDate.substring(0, 4) }}
-
</span>
{{ fullYear }}
<a :href="SiteUrl">{{ SiteAnthor }}</a>
</span>
<!-- 以下信息请不要修改哦 -->
<span class="hidden">
&amp;&nbsp;Made&nbsp;by
<a :href="config.github" target="_blank">
{{ config.author }}
</a>
</span>
<!-- 站点备案 -->
<a v-if="siteIcp" href="https://beian.miit.gov.cn" target="_blank">
&amp;
{{ siteIcp }}
</a>
</div>
<div class="lrc" v-show="store.playerState">
<music-one theme="filled" size="18" fill="#efefef" />
<span class="lrc-text">
{{ store.getPlayerLrc ? store.getPlayerLrc : "这句没有歌词" }}
</span>
<music-one theme="filled" size="18" fill="#efefef" />
</div>
</footer>
</template>
<script setup>
import { ref } from "vue";
import { MusicOne } from "@icon-park/vue-next";
import { mainStore } from "@/store";
import config from "@/../package.json";
const store = mainStore();
const fullYear = new Date().getFullYear();
//
const siteStartDate = ref(import.meta.env.VITE_SITE_START);
const siteIcp = ref(import.meta.env.VITE_SITE_ICP);
const SiteAnthor = ref(import.meta.env.VITE_SITE_ANTHOR);
const SiteUrl = ref(import.meta.env.VITE_SITE_URL);
</script>
<style lang="scss" scoped>
footer {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
height: 46px;
line-height: 46px;
text-align: center;
backdrop-filter: blur(10px);
background: rgb(0 0 0 / 25%);
z-index: 0;
animation: fade;
-webkit-animation: fade 0.5s;
@media (max-width: 720px) {
font-size: 0.85rem;
}
@media (max-width: 480px) {
.hidden {
display: none;
}
}
.power {
animation: fade;
-webkit-animation: fade 0.3s;
}
.lrc {
padding: 0 20px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
animation: fade;
-webkit-animation: fade 0.3s;
.lrc-text {
margin: 0 8px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
word-break: break-all;
}
.i-icon {
width: 18px;
height: 18px;
display: inherit;
}
}
}
</style>

View File

@ -26,11 +26,11 @@
</template> </template>
<script setup> <script setup>
import { reactive, ref, onMounted, h } from "vue";
import { MusicMenu, Error } from "@icon-park/vue-next"; import { MusicMenu, Error } from "@icon-park/vue-next";
import { getHitokoto } from "@/api"; import { getHitokoto } from "@/api";
import debounce from "@/utils/debounce.js";
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import debounce from "@/utils/debounce.js";
const store = mainStore(); const store = mainStore();
// //
@ -80,8 +80,7 @@ onMounted(() => {
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: 20px; padding: 20px;
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s;
.open-music { .open-music {
width: 100%; width: 100%;
position: absolute; position: absolute;

View File

@ -21,20 +21,16 @@
> >
<SwiperSlide v-for="site in siteLinksList" :key="site"> <SwiperSlide v-for="site in siteLinksList" :key="site">
<el-row class="link-all" :gutter="20"> <el-row class="link-all" :gutter="20">
<el-col <el-col v-for="(item, index) in site" :span="8" :key="item">
v-for="(item, index) in site"
:span="8"
:key="item"
@click="jumpLink(item)"
>
<div <div
class="item cards" class="item cards"
:style="index < 3 ? 'margin-bottom: 20px' : null" :style="index < 3 ? 'margin-bottom: 20px' : null"
@click="jumpLink(item)"
> >
<Icon size="26"> <Icon size="26">
<component :is="siteIcon[item.icon]" /> <component :is="siteIcon[item.icon]" />
</Icon> </Icon>
<span class="name">{{ item.name }}</span> <span class="name text-hidden">{{ item.name }}</span>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -45,7 +41,6 @@
</template> </template>
<script setup> <script setup>
import { onMounted, computed } from "vue";
import { Icon } from "@vicons/utils"; import { Icon } from "@vicons/utils";
// https://www.xicons.org // https://www.xicons.org
import { import {
@ -57,7 +52,7 @@ import {
Book, Book,
Fire, Fire,
LaptopCode, LaptopCode,
} from "@vicons/fa"; } from "@vicons/fa"; // 使
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import { Swiper, SwiperSlide } from "swiper/vue"; import { Swiper, SwiperSlide } from "swiper/vue";
import { Pagination, Mousewheel } from "swiper"; import { Pagination, Mousewheel } from "swiper";
@ -109,8 +104,7 @@ onMounted(() => {
font-size: 1.1rem; font-size: 1.1rem;
display: flex; display: flex;
align-items: center; align-items: center;
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s;
.title { .title {
margin-left: 8px; margin-left: 8px;
font-size: 1.15rem; font-size: 1.15rem;
@ -149,8 +143,8 @@ onMounted(() => {
align-items: center; align-items: center;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
animation: fade; padding: 0 10px;
-webkit-animation: fade 0.5s; animation: fade 0.5s;
&:hover { &:hover {
transform: scale(1.02); transform: scale(1.02);
@ -183,6 +177,9 @@ onMounted(() => {
} }
} }
} }
@media (max-width: 720px) {
height: 180px;
}
} }
} }
</style> </style>

150
src/components/Loading.vue Normal file
View File

@ -0,0 +1,150 @@
<template>
<div id="loader-wrapper" :class="store.imgLoadStatus ? 'loaded' : null">
<div class="loader">
<div class="loader-circle" />
<div class="loader-text">
<span class="name">
{{ siteName }}
</span>
<span class="tip"> 加载中 </span>
</div>
</div>
<div class="loader-section section-left" />
<div class="loader-section section-right" />
</div>
</template>
<script setup>
import { mainStore } from "@/store";
const store = mainStore();
//
const siteName = import.meta.env.VITE_SITE_NAME;
</script>
<style lang="scss" scoped>
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999;
overflow: hidden;
.loader {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.loader-circle {
width: 150px;
height: 150px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #fff;
animation: spin 1.8s linear infinite;
z-index: 2;
&:before {
content: "";
position: absolute;
top: 5px;
left: 5px;
right: 5px;
bottom: 5px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #a4a4a4;
animation: spin-reverse 0.6s linear infinite;
}
&:after {
content: "";
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #d3d3d3;
animation: spin 1s linear infinite;
}
}
.loader-text {
display: flex;
flex-direction: column;
align-items: center;
color: #fff;
z-index: 2;
margin-top: 40px;
font-size: 24px;
.tip {
margin-top: 6px;
font-size: 18px;
opacity: 0.6;
}
}
}
.loader-section {
position: fixed;
top: 0;
width: 51%;
height: 100%;
background: #333;
z-index: 1;
&.section-left {
left: 0;
}
&.section-right {
right: 0;
}
}
&.loaded {
visibility: hidden;
transform: translateY(-100%);
transition: transform 0.3s 1s ease-out, visibility 0.3s 1s ease-out;
.loader {
.loader-circle,
.loader-text {
opacity: 0;
transition: opacity 0.3s ease-out;
}
}
.loader-section {
&.section-left {
transform: translateX(-100%);
transition: transform 0.5s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}
&.section-right {
transform: translateX(100%);
transition: transform 0.5s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}
}
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes spin-reverse {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(-360deg);
}
}
</style>

View File

@ -28,7 +28,6 @@
</template> </template>
<script setup> <script setup>
import { reactive, watch, h } from "vue";
import { Icon } from "@vicons/utils"; import { Icon } from "@vicons/utils";
import { QuoteLeft, QuoteRight } from "@vicons/fa"; import { QuoteLeft, QuoteRight } from "@vicons/fa";
import { Error } from "@icon-park/vue-next"; import { Error } from "@icon-park/vue-next";
@ -36,7 +35,7 @@ import { mainStore } from "@/store";
const store = mainStore(); const store = mainStore();
// logo // logo
const siteLogo = import.meta.env.VITE_SITE_LOGO; const siteLogo = import.meta.env.VITE_SITE_MAIN_LOGO;
// //
const siteUrl = import.meta.env.VITE_SITE_URL.split("."); const siteUrl = import.meta.env.VITE_SITE_URL.split(".");
@ -83,8 +82,7 @@ watch(
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s;
.logo-img { .logo-img {
border-radius: 50%; border-radius: 50%;
width: 120px; width: 120px;
@ -125,8 +123,7 @@ watch(
padding: 1rem; padding: 1rem;
margin-top: 3.5rem; margin-top: 3.5rem;
max-width: 460px; max-width: 460px;
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s;
.content { .content {
display: flex; display: flex;

View File

@ -93,7 +93,7 @@
:songType="playerData.type" :songType="playerData.type"
:songId="playerData.id" :songId="playerData.id"
:volume="volumeNum" :volume="volumeNum"
:shuffle="true" :shuffle="false"
ref="playerRef" ref="playerRef"
/> />
</div> </div>
@ -103,7 +103,6 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive, watch, onMounted } from "vue";
import { import {
GoStart, GoStart,
PlayOne, PlayOne,
@ -114,7 +113,7 @@ import {
VolumeSmall, VolumeSmall,
VolumeNotice, VolumeNotice,
} from "@icon-park/vue-next"; } from "@icon-park/vue-next";
import Player from "@/components/Player/index.vue"; import Player from "@/components/Player.vue";
import { mainStore } from "@/store"; import { mainStore } from "@/store";
const store = mainStore(); const store = mainStore();
@ -179,8 +178,7 @@ watch(
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
flex-direction: column; flex-direction: column;
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s;
.btns { .btns {
display: flex; display: flex;
align-items: center; align-items: center;
@ -242,8 +240,7 @@ watch(
text-overflow: ellipsis; text-overflow: ellipsis;
overflow-x: hidden; overflow-x: hidden;
white-space: nowrap; white-space: nowrap;
animation: fade; animation: fade 0.3s;
-webkit-animation: fade 0.3s;
} }
.volume { .volume {
width: 100%; width: 100%;
@ -251,8 +248,7 @@ watch(
display: flex; display: flex;
align-items: center; align-items: center;
flex-direction: row; flex-direction: row;
animation: fade; animation: fade 0.3s;
-webkit-animation: fade 0.3s;
.icon { .icon {
margin-right: 12px; margin-right: 12px;
span { span {

View File

@ -20,12 +20,10 @@
</template> </template>
<script setup> <script setup>
import aplayer from "vue3-aplayer";
import fetchJsonp from "fetch-jsonp";
import { h, ref, nextTick, onMounted } from "vue";
import { MusicOne, PlayWrong } from "@icon-park/vue-next"; import { MusicOne, PlayWrong } from "@icon-park/vue-next";
import { getPlayerList } from "@/api"; import { getPlayerList } from "@/api";
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import aplayer from "vue3-aplayer";
const store = mainStore(); const store = mainStore();
@ -34,7 +32,6 @@ const player = ref(null);
// //
const playList = ref([]); const playList = ref([]);
const playerLrc = ref("");
// //
const playIndex = ref(0); const playIndex = ref(0);
@ -70,10 +67,10 @@ const props = defineProps({
return value >= 0 && value <= 1; return value >= 0 && value <= 1;
}, },
}, },
// ( netease-, tencent-qq, kugou-, xiami-, baidu- ) // ( netease-, tencent-qq )
songServer: { songServer: {
type: String, type: String,
default: "netease", //'netease' | 'tencent' | 'kugou' | 'xiami' | 'baidu' default: "netease", //'netease' | 'tencent'
}, },
// ( song-, playlist-, album-, search-, artist- ) // ( song-, playlist-, album-, search-, artist- )
songType: { songType: {
@ -143,7 +140,7 @@ onMounted(() => {
}); });
}); });
// //
const onPlay = () => { const onPlay = () => {
console.log("播放"); console.log("播放");
// //
@ -162,6 +159,8 @@ const onPlay = () => {
}), }),
}); });
}; };
//
const onPause = () => { const onPause = () => {
store.setPlayerState(player.value.audio.paused); store.setPlayerState(player.value.audio.paused);
}; };
@ -170,10 +169,13 @@ const onPause = () => {
const onTimeUp = () => { const onTimeUp = () => {
let playerRef = player.value.$.vnode.el; let playerRef = player.value.$.vnode.el;
if (playerRef) { if (playerRef) {
playerLrc.value = playerRef.getElementsByClassName( const currentLrcElement = playerRef.querySelector(".aplayer-lrc-current");
"aplayer-lrc-current" const previousLrcElement = currentLrcElement?.previousElementSibling;
)[0].innerHTML; const lrcContent =
store.setPlayerLrc(playerLrc.value); currentLrcElement?.innerHTML ||
previousLrcElement?.innerHTML ||
"这句没有歌词";
store.setPlayerLrc(lrcContent);
} }
}; };

View File

@ -1,9 +1,13 @@
<template> <template>
<div class="setting"> <div class="setting">
<el-collapse class="collapse" v-model="activeName" accordion> <el-collapse class="collapse" v-model="activeName" accordion>
<el-collapse-item title="壁纸设置" name="1"> <el-collapse-item title="个性壁纸" name="1">
<div class="bg-set"> <div class="bg-set">
<el-radio-group v-model="bgSet" text-color="#ffffff"> <el-radio-group
v-model="coverType"
text-color="#ffffff"
@change="radioChange"
>
<el-radio label="0" size="large" border>默认壁纸</el-radio> <el-radio label="0" size="large" border>默认壁纸</el-radio>
<el-radio label="1" size="large" border>每日一图</el-radio> <el-radio label="1" size="large" border>每日一图</el-radio>
<el-radio label="2" size="large" border>随机风景</el-radio> <el-radio label="2" size="large" border>随机风景</el-radio>
@ -11,7 +15,7 @@
</el-radio-group> </el-radio-group>
</div> </div>
</el-collapse-item> </el-collapse-item>
<el-collapse-item title="其他设置" name="2"> <el-collapse-item title="个性化调整" name="2">
<div class="item"> <div class="item">
<span class="text">建站日期显示</span> <span class="text">建站日期显示</span>
<el-switch <el-switch
@ -30,8 +34,26 @@
:inactive-icon="CloseSmall" :inactive-icon="CloseSmall"
/> />
</div> </div>
<div class="item">
<span class="text">底栏歌词显示</span>
<el-switch
v-model="playerLrcShow"
inline-prompt
:active-icon="CheckSmall"
:inactive-icon="CloseSmall"
/>
</div>
<div class="item">
<span class="text">底栏背景模糊</span>
<el-switch
v-model="footerBlur"
inline-prompt
:active-icon="CheckSmall"
:inactive-icon="CloseSmall"
/>
</div>
</el-collapse-item> </el-collapse-item>
<el-collapse-item title="其他设置" name="3"> <el-collapse-item title="播放器配置" name="3">
<div>设置内容待增加</div> <div>设置内容待增加</div>
</el-collapse-item> </el-collapse-item>
<el-collapse-item title="其他设置" name="4"> <el-collapse-item title="其他设置" name="4">
@ -42,29 +64,27 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, watch } from "vue"; import { CheckSmall, CloseSmall, SuccessPicture } from "@icon-park/vue-next";
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import { CheckSmall, CloseSmall } from "@icon-park/vue-next";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
const store = mainStore(); const store = mainStore();
const { siteStartShow, musicClick } = storeToRefs(store); const { coverType, siteStartShow, musicClick, playerLrcShow, footerBlur } =
storeToRefs(store);
// //
const activeName = ref("1"); const activeName = ref("1");
const bgSet = ref("0");
onMounted(() => { //
bgSet.value = store.coverType.toString(); const radioChange = () => {
}); ElMessage({
message: "壁纸设置成功,刷新后生效",
// icon: h(SuccessPicture, {
watch( theme: "filled",
() => bgSet.value, fill: "#efefef",
(value) => { }),
store.coverType = value; });
} };
);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -18,7 +18,6 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue";
import socialLinks from "@/assets/socialLinks.json"; import socialLinks from "@/assets/socialLinks.json";
// //
@ -37,9 +36,8 @@ const socialTip = ref("通过这里联系我吧");
background-color: transparent; background-color: transparent;
border-radius: 6px; border-radius: 6px;
backdrop-filter: blur(0); backdrop-filter: blur(0);
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s; transition: background-color 0.3s, backdrop-filter 0.3s;
transition: all 0.5s;
@media (max-width: 840px) { @media (max-width: 840px) {
max-width: 100%; max-width: 100%;
justify-content: center; justify-content: center;
@ -60,9 +58,12 @@ const socialTip = ref("通过这里联系我吧");
display: inherit; display: inherit;
.icon { .icon {
margin: 0 12px; margin: 0 12px;
transition: all 0.3s; transition: transform 0.3s;
&:hover {
transform: scale(1.1);
}
&:active { &:active {
transform: scale(0.9); transform: scale(1);
} }
} }
} }
@ -70,8 +71,7 @@ const socialTip = ref("通过这里联系我吧");
.tip { .tip {
display: none; display: none;
margin-right: 12px; margin-right: 12px;
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s;
} }
@media (min-width: 768px) { @media (min-width: 768px) {
&:hover { &:hover {

View File

@ -54,7 +54,6 @@
</template> </template>
<script setup> <script setup>
import { onMounted, onBeforeUnmount, ref } from "vue";
import { HourglassFull } from "@icon-park/vue-next"; import { HourglassFull } from "@icon-park/vue-next";
import { getTimeCapsule, siteDateStatistics } from "@/utils/getTime.js"; import { getTimeCapsule, siteDateStatistics } from "@/utils/getTime.js";
import { mainStore } from "@/store"; import { mainStore } from "@/store";

View File

@ -18,7 +18,6 @@
</template> </template>
<script setup> <script setup>
import { onMounted, reactive, h } from "vue";
import { getAdcode, getWeather, getOtherWeather } from "@/api"; import { getAdcode, getWeather, getOtherWeather } from "@/api";
import { Error } from "@icon-park/vue-next"; import { Error } from "@icon-park/vue-next";

View File

@ -3,9 +3,11 @@ import { defineStore } from "pinia";
export const mainStore = defineStore("main", { export const mainStore = defineStore("main", {
state: () => { state: () => {
return { return {
imgLoadStatus: false, // 壁纸加载状态
innerWidth: null, // 当前窗口宽度 innerWidth: null, // 当前窗口宽度
coverType: "0", // 壁纸种类 coverType: "0", // 壁纸种类
siteStartShow: true, // 建站日期显示 siteStartShow: false, // 建站日期显示
musicClick: false, // 音乐链接是否跳转
musicIsOk: false, // 音乐是否加载完成 musicIsOk: false, // 音乐是否加载完成
musicVolume: 0, // 音乐音量; musicVolume: 0, // 音乐音量;
musicOpenState: false, // 音乐面板开启状态 musicOpenState: false, // 音乐面板开启状态
@ -18,7 +20,8 @@ export const mainStore = defineStore("main", {
playerTitle: null, // 当前播放歌曲名 playerTitle: null, // 当前播放歌曲名
playerArtist: null, // 当前播放歌手名 playerArtist: null, // 当前播放歌手名
playerLrc: "歌词加载中", // 当前播放歌词 playerLrc: "歌词加载中", // 当前播放歌词
musicClick: false, // 音乐链接是否跳转 playerLrcShow: true, // 是否显示底栏歌词
footerBlur: true, // 底栏模糊
}; };
}, },
getters: { getters: {
@ -64,10 +67,21 @@ export const mainStore = defineStore("main", {
this.playerTitle = title; this.playerTitle = title;
this.playerArtist = artist; this.playerArtist = artist;
}, },
// 更改壁纸加载状态
setImgLoadStatus(value) {
this.imgLoadStatus = value;
},
}, },
persist: { persist: {
key: "data", key: "data",
storage: window.localStorage, storage: window.localStorage,
paths: ["coverType", "musicVolume", "siteStartShow", "musicClick"], paths: [
"coverType",
"musicVolume",
"siteStartShow",
"musicClick",
"playerLrcShow",
"footerBlur",
],
}, },
}); });

View File

@ -17,9 +17,9 @@
} }
} }
/* 小于1200px时 */ /* 小于1280px时 */
@media (max-width: 1200px) { @media (max-width: 1280px) {
@include changeWidth($maxWidth:1000px); @include changeWidth($maxWidth:1100px);
} }
/* 小于992px时 */ /* 小于992px时 */

View File

@ -13,6 +13,8 @@ html,
body { body {
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0;
padding: 0;
background-color: #333; background-color: #333;
overflow: hidden; overflow: hidden;
font-family: "HarmonyOS_Regular", sans-serif; font-family: "HarmonyOS_Regular", sans-serif;
@ -23,8 +25,6 @@ a,
p { p {
margin: 0; margin: 0;
padding: 0; padding: 0;
-webkit-user-select: none;
-webkit-user-drag: none;
user-select: none; user-select: none;
text-decoration: none; text-decoration: none;
color: #fff; color: #fff;
@ -59,19 +59,16 @@ p {
// 卡片样式 // 卡片样式
.cards { .cards {
border-radius: 6px; border-radius: 6px;
background: #00000040; background-color: #00000040;
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
transform: scale(1); transform: scale(1);
transition: all 0.3s; transition: backdrop-filter 0.3s, transform 0.3s;
} &:hover {
.cards:hover {
transform: scale(1.01); transform: scale(1.01);
} }
&:active {
.cards:active {
transform: scale(0.98); transform: scale(0.98);
}
} }
// 文字超出 // 文字超出
@ -103,13 +100,11 @@ p {
.el-progress-bar__outer { .el-progress-bar__outer {
border-radius: 6px; border-radius: 6px;
background-color: #00000020; background-color: #00000020;
.el-progress-bar__inner { .el-progress-bar__inner {
background-color: #efefef; background-color: #efefef;
border-radius: 6px; border-radius: 6px;
text-align: center; text-align: center;
font-family: "UnidreamLED"; font-family: "UnidreamLED";
span { span {
color: #564d59; color: #564d59;
font-size: 0.9rem; font-size: 0.9rem;
@ -129,31 +124,59 @@ p {
border-radius: 8px !important; border-radius: 8px !important;
border: 1px solid transparent !important; border: 1px solid transparent !important;
background-color: transparent !important; background-color: transparent !important;
.el-card__header { .el-card__header {
font-weight: bold; font-weight: bold;
padding: 16px 20px !important; padding: 16px 20px !important;
background-color: #ffffff30 !important; background-color: #ffffff30 !important;
border-bottom: 1px solid transparent !important; border-bottom: 1px solid transparent !important;
} }
.el-card__body { .el-card__body {
padding: 0 !important; padding: 0 !important;
background-color: #ffffff10 !important; background-color: #ffffff10 !important;
} }
} }
// 渐入动画 // Transition 动画
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease-in-out;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
// keyframes 动画
@keyframes fade { @keyframes fade {
0% { from {
opacity: 0; opacity: 0;
} }
to {
100% {
opacity: 1; opacity: 1;
} }
} }
@keyframes fade-blur-in {
from {
filter: blur(20px) brightness(0.3);
transform: scale(1.6);
}
to {
filter: blur(0) brightness(1);
transform: scale(1.2);
}
}
@keyframes fade-blur-main-in {
from {
transform: scale(1.2);
}
to {
transform: scale(1);
}
}
// 隐藏元素 // 隐藏元素
@media (min-width: 910px) and (max-width: 1200px) { @media (min-width: 910px) and (max-width: 1200px) {
.sm-hidden { .sm-hidden {

View File

@ -1,6 +0,0 @@
/*!
* china-lantern v1.6.0
* (c) 2020-2021 fz6m
* Released under the MIT License.
*/
!function(t){"function"==typeof define&&define.amd?define(t):t()}((function(){"use strict";!function(t,e){void 0===e&&(e={});var n=e.insertAt;if(t&&"undefined"!=typeof document){var r=document.head||document.getElementsByTagName("head")[0],a=document.createElement("style");a.type="text/css","top"===n&&r.firstChild?r.insertBefore(a,r.firstChild):r.appendChild(a),a.styleSheet?a.styleSheet.cssText=t:a.appendChild(document.createTextNode(t))}}('@charset "UTF-8";.lantern__warpper{position:fixed;top:12px;left:40px;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:999}.lantern__warpper.lantern__secondary{left:calc(100% - 130px)}.lantern__warpper.lantern__secondary .lantern__box{-webkit-animation-duration:3s;animation-duration:3s;animation-delay:1s;}.lantern__box{position:relative;display:inline-block;width:90px;height:70px;background:rgba(216,0,15,.8);border-radius:50% 50%;animation:lantern-swing 3s ease-in-out infinite alternate-reverse;-webkit-transform-origin:50% -70px;-ms-transform-origin:50% -70px;transform-origin:50% -70px;-webkit-box-shadow:-5px 5px 50px 4px #fa6c00;box-shadow:-5px 5px 50px 4px #fa6c00}.lantern__box:after,.lantern__box:before{content:"";position:absolute;height:8px;width:45px;left:50%;border:1px solid #dc8f03;background:-webkit-gradient(linear,left top,right top,from(#dc8f03),color-stop(orange),color-stop(#dc8f03),color-stop(orange),to(#dc8f03));background:-o-linear-gradient(left,#dc8f03,orange,#dc8f03,orange,#dc8f03);background:linear-gradient(90deg,#dc8f03,orange,#dc8f03,orange,#dc8f03)}.lantern__box:before{top:0;border-radius:5px 5px 0 0;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.lantern__box:after{bottom:0;border-radius:0 0 5px 5px;-webkit-transform:translate(-50%,50%);-ms-transform:translate(-50%,50%);transform:translate(-50%,50%)}.lantern__line{position:absolute;width:2px;height:12px;top:0;left:50%;-webkit-transform:translate(-50%,-100%);-ms-transform:translate(-50%,-100%);transform:translate(-50%,-100%);background:#dc8f03}.lantern__circle{width:80%;-webkit-box-sizing:border-box;box-sizing:border-box}.lantern__circle,.lantern__circle .lantern__ellipse{height:100%;margin:0 auto;border-radius:50%;border:2px solid #dc8f03}.lantern__circle .lantern__ellipse{width:50%}.lantern__circle .lantern__text{font-family:华文行楷,Microsoft YaHei,sans-serif;font-size:24.3px;color:#dc8f03;font-weight:700;line-height:66px;text-align:center}.lantern__tail{position:relative;width:4px;height:12px;margin:0 auto;animation:lantern-swing 4s ease-in-out infinite alternate-reverse;background:orange;border-radius:0 0 5px 5px}.lantern__tail .lantern__junction{position:absolute;top:0;left:50%;width:8px;height:8px;-webkit-transform:translate(-50%,8.4px);-ms-transform:translate(-50%,8.4px);transform:translate(-50%,8.4px);background:#e69603;border-radius:50%}.lantern__tail .lantern__rect{position:absolute;top:0;left:50%;-webkit-transform:translate(-50%,10.8px);-ms-transform:translate(-50%,10.8px);transform:translate(-50%,10.8px);width:8px;height:24px;background:orange;border-radius:5px 5px 0 5px}@-webkit-keyframes lantern-swing{0%{-webkit-transform:rotate(-8deg);transform:rotate(-8deg)}to{-webkit-transform:rotate(8deg);transform:rotate(8deg)}}@keyframes lantern-swing{0%{-webkit-transform:rotate(-8deg);transform:rotate(-8deg)}to{-webkit-transform:rotate(8deg);transform:rotate(8deg)}}@media (max-width:520px){.j-china-lantern{display: none;}');var t;(t=document.createElement("div")).className="j-china-lantern",t.innerHTML='<div class="lantern__warpper"><div class="lantern__box"><div class="lantern__line"></div><div class="lantern__circle"><div class="lantern__ellipse"><div class="lantern__text">新</div></div></div><div class="lantern__tail"><div class="lantern__rect"></div><div class="lantern__junction"></div></div></div></div><div class="lantern__warpper lantern__secondary"><div class="lantern__box"><div class="lantern__line"></div><div class="lantern__circle"><div class="lantern__ellipse"><div class="lantern__text">年</div></div></div><div class="lantern__tail"><div class="lantern__rect"></div><div class="lantern__junction"></div></div></div></div>',document.body.appendChild(t)}));

View File

@ -31,10 +31,9 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue";
import { CloseOne, SettingTwo } from "@icon-park/vue-next"; import { CloseOne, SettingTwo } from "@icon-park/vue-next";
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import TimeCapsule from "@/components/TimeCapsule/index.vue"; import TimeCapsule from "@/components/TimeCapsule.vue";
const store = mainStore(); const store = mainStore();
const closeShow = ref(false); const closeShow = ref(false);
@ -46,8 +45,7 @@ const closeShow = ref(false);
margin-left: 0.75rem; margin-left: 0.75rem;
height: 80%; height: 80%;
position: relative; position: relative;
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s;
&:hover { &:hover {
transform: scale(1); transform: scale(1);

View File

@ -33,12 +33,11 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import { getCurrentTime } from "@/utils/getTime"; import { getCurrentTime } from "@/utils/getTime";
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import Music from "@/components/Music/index.vue"; import Music from "@/components/Music.vue";
import Hitokoto from "@/components/Hitokoto/index.vue"; import Hitokoto from "@/components/Hitokoto.vue";
import Weather from "@/components/Weather/index.vue"; import Weather from "@/components/Weather.vue";
const store = mainStore(); const store = mainStore();
@ -114,8 +113,7 @@ onBeforeUnmount(() => {
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s;
.time { .time {
font-size: 1.1rem; font-size: 1.1rem;
text-align: center; text-align: center;

View File

@ -7,8 +7,8 @@
<script setup> <script setup>
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import Message from "@/components/Message/index.vue"; import Message from "@/components/Message.vue";
import SocialLinks from "@/components/SocialLinks/index.vue"; import SocialLinks from "@/components/SocialLinks.vue";
const store = mainStore(); const store = mainStore();
</script> </script>

View File

@ -15,7 +15,7 @@
<script setup> <script setup>
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import Func from "@/views/Func/index.vue"; import Func from "@/views/Func/index.vue";
import Link from "@/components/Links/index.vue"; import Link from "@/components/Links.vue";
const store = mainStore(); const store = mainStore();
// //
@ -36,9 +36,8 @@ const siteUrl = import.meta.env.VITE_SITE_URL.split(".");
top: 6%; top: 6%;
left: 0; left: 0;
text-align: center; text-align: center;
transition: all 0.3s; transition: transform 0.3s;
animation: fade; animation: fade 0.5s;
-webkit-animation: fade 0.5s;
&:active { &:active {
transform: scale(0.95); transform: scale(0.95);
} }

View File

@ -66,7 +66,6 @@
</template> </template>
<script setup> <script setup>
import { reactive, ref } from "vue";
import { import {
CloseOne, CloseOne,
SettingTwo, SettingTwo,
@ -75,10 +74,10 @@ import {
Bug, Bug,
} from "@icon-park/vue-next"; } from "@icon-park/vue-next";
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import Set from "@/components/Set/index.vue"; import Set from "@/components/Set.vue";
import config from "@/../package.json"; import config from "@/../package.json";
const store = mainStore();
const store = mainStore();
const closeShow = ref(false); const closeShow = ref(false);
// //

View File

@ -1,135 +1,121 @@
import { import { defineConfig, loadEnv } from "vite";
defineConfig, import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
loadEnv import { resolve } from "path";
} from 'vite'; import { VitePWA } from "vite-plugin-pwa";
import vue from '@vitejs/plugin-vue'; import vue from "@vitejs/plugin-vue";
import AutoImport from 'unplugin-auto-import/vite' import AutoImport from "unplugin-auto-import/vite";
import Components from 'unplugin-vue-components/vite' import Components from "unplugin-vue-components/vite";
import { import viteCompression from "vite-plugin-compression";
ElementPlusResolver
} from 'unplugin-vue-components/resolvers'
import {
createHtmlPlugin
} from 'vite-plugin-html';
import {
resolve
} from 'path';
import {
VitePWA
} from 'vite-plugin-pwa';
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default ({ export default ({ mode }) =>
mode defineConfig({
}) => defineConfig({
plugins: [ plugins: [
vue(), vue(),
AutoImport({ AutoImport({
imports: ["vue"],
resolvers: [ElementPlusResolver()], resolvers: [ElementPlusResolver()],
}), }),
Components({ Components({
resolvers: [ElementPlusResolver()], resolvers: [ElementPlusResolver()],
}), }),
createHtmlPlugin({
minify: true,
inject: {
data: {
logo: loadEnv(mode, process.cwd()).VITE_SITE_LOGO,
appleLogo: loadEnv(mode, process.cwd()).VITE_SITE_APPLE_LOGO,
title: loadEnv(mode, process.cwd()).VITE_SITE_NAME,
author: loadEnv(mode, process.cwd()).VITE_SITE_ANTHOR,
keywords: loadEnv(mode, process.cwd()).VITE_SITE_KEYWORDS,
description: loadEnv(mode, process.cwd()).VITE_SITE_DES,
tongji: loadEnv(mode, process.cwd()).VITE_SITE_BAIDUTONGJI,
},
},
}),
VitePWA({ VitePWA({
registerType: 'autoUpdate', registerType: "autoUpdate",
workbox: { workbox: {
skipWaiting: true, skipWaiting: true,
clientsClaim: true, clientsClaim: true,
runtimeCaching: [{ runtimeCaching: [
{
urlPattern: /(.*?)\.(js|css|woff2|woff|ttf)/, // js / css 静态资源缓存 urlPattern: /(.*?)\.(js|css|woff2|woff|ttf)/, // js / css 静态资源缓存
handler: 'CacheFirst', handler: "CacheFirst",
options: { options: {
cacheName: 'js-css-cache', cacheName: "js-css-cache",
}, },
}, },
{ {
urlPattern: /(.*?)\.(png|jpe?g|svg|gif|bmp|psd|tiff|tga|eps)/, // 图片缓存 urlPattern: /(.*?)\.(png|jpe?g|svg|gif|bmp|psd|tiff|tga|eps)/, // 图片缓存
handler: 'CacheFirst', handler: "CacheFirst",
options: { options: {
cacheName: 'image-cache', cacheName: "image-cache",
}, },
}, },
], ],
}, },
manifest: { manifest: {
"name": loadEnv(mode, process.cwd()).VITE_SITE_NAME, name: loadEnv(mode, process.cwd()).VITE_SITE_NAME,
"short_name": loadEnv(mode, process.cwd()).VITE_SITE_NAME, short_name: loadEnv(mode, process.cwd()).VITE_SITE_NAME,
"description": loadEnv(mode, process.cwd()).VITE_SITE_DES, description: loadEnv(mode, process.cwd()).VITE_SITE_DES,
"display": "standalone", display: "standalone",
"start_url": "/", start_url: "/",
"theme_color": "#424242", theme_color: "#424242",
"background_color": "#424242", background_color: "#424242",
"icons": [{ icons: [
"src": "/images/icon/48.png", {
"sizes": "48x48", src: "/images/icon/48.png",
"type": "image/png" sizes: "48x48",
}, { type: "image/png",
"src": "/images/icon/72.png", },
"sizes": "72x72", {
"type": "image/png" src: "/images/icon/72.png",
}, { sizes: "72x72",
"src": "/images/icon/96.png", type: "image/png",
"sizes": "96x96", },
"type": "image/png" {
}, { src: "/images/icon/96.png",
"src": "/images/icon/128.png", sizes: "96x96",
"sizes": "128x128", type: "image/png",
"type": "image/png" },
}, { {
"src": "/images/icon/144.png", src: "/images/icon/128.png",
"sizes": "144x144", sizes: "128x128",
"type": "image/png" type: "image/png",
}, { },
"src": "/images/icon/192.png", {
"sizes": "192x192", src: "/images/icon/144.png",
"type": "image/png" sizes: "144x144",
}, { type: "image/png",
"src": "/images/icon/512.png", },
"sizes": "512x512", {
"type": "image/png" src: "/images/icon/192.png",
}] sizes: "192x192",
} type: "image/png",
},
{
src: "/images/icon/512.png",
sizes: "512x512",
type: "image/png",
},
],
},
}), }),
viteCompression(),
], ],
server: { server: {
port: "3000", port: "3000",
hmr: true, open: true,
}, },
resolve: { resolve: {
alias: [{ alias: [
find: '@', {
find: "@",
replacement: resolve(__dirname, "src"), replacement: resolve(__dirname, "src"),
}, ] },
],
}, },
css: { css: {
preprocessorOptions: { preprocessorOptions: {
scss: { scss: {
charset: false, charset: false,
additionalData: `@import "./src/style/global.scss";` additionalData: `@import "./src/style/global.scss";`,
} },
} },
}, },
build: { build: {
minify: 'terser', minify: "terser",
terserOptions: { terserOptions: {
compress: { compress: {
// 生产环境时移除 console pure_funcs: ["console.log"],
pure_funcs: ['console.log'],
}, },
}, },
}, },
}) });

3515
yarn.lock

File diff suppressed because it is too large Load Diff