新增设置页面

This commit is contained in:
底层用户 2022-11-27 00:11:51 +08:00
parent 48afe35097
commit 8c6dc91075
12 changed files with 541 additions and 41 deletions

1
.env
View File

@ -1,5 +1,6 @@
# 站点名称
VITE_SITE_NAME = "無名の主页"
VITE_SITE_URL = "imsyy.top"
# 简介文本
VITE_DESC_HELLO = "Hello World !"

View File

@ -3,9 +3,18 @@
<Background />
<main>
<div class="container">
<MainLeft />
<MainRight v-show="!store.boxOpenState" />
<Box v-show="store.boxOpenState" />
<transition name="el-fade-in-linear">
<section class="main" v-show="!store.setOpenState">
<MainLeft />
<MainRight v-show="!store.boxOpenState" />
<Box v-show="store.boxOpenState" />
</section>
</transition>
<transition name="el-fade-in-linear">
<section class="more" v-show="store.setOpenState" @click="store.setOpenState = false">
<MoreSet />
</section>
</transition>
</div>
</main>
<Footer />
@ -19,7 +28,9 @@ import MainRight from "@/views/Main/Right.vue";
import Background from "@/components/Background/index.vue";
import Footer from "@/components/Footer/index.vue";
import Box from "@/views/Box/index.vue";
import MoreSet from "@/views/MoreSet/index.vue";
import cursorInit from "@/utils/cursor.js";
import { helloInit, checkDays } from "@/utils/getTime.js";
import { mainStore } from "@/store";
const store = mainStore();
@ -31,6 +42,10 @@ const getWidth = () => {
onMounted(() => {
//
cursorInit();
//
helloInit();
//
checkDays();
//
window.addEventListener("load", () => {
console.log("加载完成");
@ -55,14 +70,30 @@ onBeforeUnmount(() => {
<style lang="scss" scoped>
main {
.container {
margin: 0 auto;
padding: 0 0.75rem;
width: 100%;
height: 100vh;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin: 0 auto;
.main {
width: 100%;
height: 100%;
padding: 0 0.75rem;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.more {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #00000080;
backdrop-filter: blur(20px);
z-index: 2;
}
}
}

View File

@ -6,20 +6,38 @@
</template>
<script setup>
import { onMounted, ref } from "vue";
import { onMounted, ref, watch } from "vue";
import { mainStore } from "@/store";
const store = mainStore();
let bgUrl = ref(null); //
onMounted(() => {
//
if (store.coverType == 0) {
const changeBg = (type) => {
if (type == 0) {
bgUrl.value = `/images/background${Math.floor(
Math.random() * 10 + 1
)}.webp`;
} else if (type == 1) {
bgUrl.value = "https://api.dujin.org/bing/1920.php";
} else if (type == 2) {
bgUrl.value = "https://api.ixiaowai.cn/gqapi/gqapi.php";
} else if (type == 3) {
bgUrl.value = "https://api.ixiaowai.cn/api/api.php";
}
}
onMounted(() => {
//
changeBg(store.coverType);
});
//
watch(
() => store.coverType,
(value) => {
changeBg(value);
}
);
</script>
<style lang="scss" scoped>
@ -31,6 +49,7 @@ onMounted(() => {
height: 100%;
transition: 0.25s;
z-index: -1;
.bg {
transform: scale(1);
filter: blur(0);
@ -43,6 +62,7 @@ onMounted(() => {
transition: all 1.5s ease 0s;
backface-visibility: hidden;
}
.gray {
opacity: 1;
position: absolute;
@ -50,10 +70,8 @@ onMounted(() => {
top: 0;
width: 100%;
height: 100%;
background-image: radial-gradient(
rgba(0, 0, 0, 0) 0,
rgba(0, 0, 0, 0.5) 100%
),
background-image: radial-gradient(rgba(0, 0, 0, 0) 0,
rgba(0, 0, 0, 0.5) 100%),
radial-gradient(rgba(0, 0, 0, 0) 33%, rgba(0, 0, 0, 0.3) 166%);
transition: 1.5s;
@ -68,6 +86,7 @@ onMounted(() => {
transform: scale(1.1);
filter: blur(10px);
}
.gray {
transition: 1.5s;
opacity: 0;

View File

@ -5,8 +5,8 @@
<div class="logo">
<img class="logo-img" src="/images/icon/logo.png" alt="logo" />
<div class="name">
<span class="bg">imsyy</span>
<span class="sm">.top</span>
<span class="bg">{{ siteUrl[0] }}</span>
<span class="sm">.{{ siteUrl[1] }}</span>
</div>
</div>
<!-- 简介 -->
@ -35,6 +35,9 @@ import { Error } from "@icon-park/vue-next";
import { mainStore } from "@/store";
const store = mainStore();
//
let siteUrl = import.meta.env.VITE_SITE_URL.split(".");
//
let descriptionText = reactive({
hello: import.meta.env.VITE_DESC_HELLO,
@ -48,6 +51,7 @@ const changeBox = () => {
} else {
ElMessage({
message: "当前页面宽度不足以开启盒子",
grouping: true,
icon: h(Error, {
theme: "filled",
fill: "#efefef",
@ -77,41 +81,50 @@ watch(
display: flex;
flex-direction: row;
align-items: center;
.logo-img {
border-radius: 50%;
width: 120px;
}
.name {
width: 100%;
margin-left: 12px;
transform: translateY(-8px);
font-family: "Pacifico-Regular";
.bg {
font-size: 5rem;
}
.sm {
margin-left: 6px;
font-size: 2rem;
}
}
}
.description {
padding: 1rem;
margin-top: 3.5rem;
max-width: 460px;
.content {
display: flex;
justify-content: space-between;
.text {
margin: 0.75rem auto;
line-height: 2rem;
margin-right: auto;
p {
&:nth-of-type(1) {
font-family: "Pacifico-Regular";
}
}
}
.xicon:nth-of-type(2) {
align-self: flex-end;
}

View File

@ -0,0 +1,139 @@
<template>
<div class="setting">
<el-collapse class="collapse" v-model="activeName" accordion>
<el-collapse-item title="壁纸设置" name="1">
<div class="bg-set">
<el-radio-group v-model="bgSet" text-color="#ffffff">
<el-radio label="0" 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="3" size="large" border>随机动漫</el-radio>
</el-radio-group>
</div>
</el-collapse-item>
<el-collapse-item title="Feedback" name="2">
<div>
Operation feedback: enable the users to clearly perceive their
operations by style updates and interactive effects;
</div>
<div>
Visual feedback: reflect current state by updating or rearranging
elements of the page.
</div>
</el-collapse-item>
<el-collapse-item title="Efficiency" name="3">
<div>
Simplify the process: keep operating process simple and intuitive;
</div>
<div>
Definite and clear: enunciate your intentions clearly so that the
users can quickly understand and make decisions;
</div>
<div>
Easy to identify: the interface should be straightforward, which helps
the users to identify and frees them from memorizing and recalling.
</div>
</el-collapse-item>
<el-collapse-item title="Controllability" name="4">
<div>
Decision making: giving advices about operations is acceptable, but do
not make decisions for the users;
</div>
<div>
Controlled consequences: users should be granted the freedom to
operate, including canceling, aborting or terminating current
operation.
</div>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from "vue";
import { mainStore } from "@/store";
const store = mainStore();
//
let activeName = ref('1');
let bgSet = ref("0");
onMounted(() => {
bgSet.value = store.coverType.toString();
})
//
watch(
() => bgSet.value,
(value) => {
store.coverType = value;
}
);
</script>
<style lang="scss" scoped>
.setting {
.collapse {
border-radius: 8px;
--el-collapse-content-bg-color: #ffffff10;
border-color: transparent;
overflow: hidden;
:deep(.el-collapse-item__header) {
background-color: #ffffff30;
color: #fff;
font-size: 15px;
padding-left: 18px;
border-color: transparent;
}
:deep(.el-collapse-item__wrap) {
border-color: transparent;
.el-collapse-item__content {
padding: 20px;
.bg-set {
.el-radio-group {
justify-content: center;
.el-radio {
margin: 10px 16px;
.el-radio__label {
color: #fff;
}
.el-radio__inner {
background-color: #ffffff60 !important;
border-color: #fff !important;
}
&.is-checked {
background-color: #ffffff60;
border-color: #ffffff80;
}
.is-checked {
.el-radio__inner {
background-color: #ffffff30 !important;
border-color: #fff !important;
}
&+.el-radio__label {
color: #fff !important;
}
}
}
}
}
}
}
}
}
</style>

View File

@ -70,7 +70,7 @@ onBeforeUnmount(() => {
display: flex;
flex-direction: row;
align-items: center;
margin: 0.5rem 0 1.5rem;
margin: 0.2rem 0 1.5rem;
font-size: 1.1rem;
.i-icon {
display: flex;

View File

@ -6,10 +6,11 @@ export const mainStore = defineStore("main", {
state: () => {
return {
innerWidth: null, // 当前窗口宽度
coverType: 0, // 壁纸种类
coverType: "0", // 壁纸种类
musicIsOk: false, // 音乐是否加载完成
musicOpenState: false, // 音乐面板开启状态
boxOpenState: false, // 盒子开启状态
setOpenState: false, // 设置页面开启状态
playerState: false, // 当前播放状态
playerTitle: null, // 当前播放歌曲名
playerArtist: null, // 当前播放歌手名

View File

@ -23,6 +23,7 @@ p {
margin: 0;
padding: 0;
-webkit-user-select: none;
-webkit-user-drag: none;
user-select: none;
text-decoration: none;
transition: .3s;
@ -116,6 +117,31 @@ p {
}
// Tooltip 样式
.el-popper.is-dark {
background: #ffffff60 !important;
border: 1px solid transparent !important;
}
// 卡片样式
.el-card {
border-radius: 8px !important;
border: 1px solid transparent !important;
background-color: transparent !important;
.el-card__header {
font-weight: bold;
padding: 16px 20px !important;
background-color: #ffffff30 !important;
border-bottom: 1px solid transparent !important;
}
.el-card__body {
padding: 0 !important;
background-color: #ffffff10 !important;
}
}
// 渐入动画
.fade-enter-active {
animation: fade 0.3s ease-in-out;
@ -158,3 +184,15 @@ p {
}
}
// 滚动条样式
::-webkit-scrollbar {
width: 6px;
height: 6px;
background-color: transparent;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: #eeeeee;
}

View File

@ -1,3 +1,10 @@
import {
h
} from "vue";
import {
SpaCandle
} from "@icon-park/vue-next";
// 时钟
export const getCurrentTime = () => {
let time = new Date();
@ -57,3 +64,55 @@ export const getTimeCapsule = () => {
}
}
}
// 欢迎提示
export const helloInit = () => {
let hour = new Date().getHours();
let hello = null;
if (hour < 6) {
hello = "凌晨好";
} else if (hour < 9) {
hello = "早上好";
} else if (hour < 12) {
hello = "上午好";
} else if (hour < 14) {
hello = "中午好";
} else if (hour < 17) {
hello = "下午好";
} else if (hour < 19) {
hello = "傍晚好";
} else if (hour < 22) {
hello = "晚上好";
} else {
hello = "夜深了";
}
ElMessage({
dangerouslyUseHTMLString: true,
message: `<strong>${hello}</strong> 欢迎来到我的主页`,
});
}
// 默哀模式
export const checkDays = () => {
let myDate = new Date;
let mon = myDate.getMonth() + 1;
let date = myDate.getDate();
let days = ['4.4', '5.12', '7.7', '9.9', '9.18', '12.13'];
for (let day of days) {
let d = day.split('.');
if (mon == d[0] && date == d[1]) {
console.log("今天是纪念日");
let gray = document.createElement("style");
document.body.appendChild(gray);
gray.innerHTML = "html{-webkit-filter:grayscale(100%);-moz-filter:grayscale(100%);-ms-filter:grayscale(100%);-o-filter:grayscale(100%);filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);_filter:none}";
ElMessage({
message: "今天是中国国家纪念日",
duration: 14000,
icon: h(SpaCandle, {
theme: "filled",
fill: "#efefef",
}),
});
}
}
}

View File

@ -1,18 +1,12 @@
<template>
<div
class="box cards"
@mouseenter="closeShow = true"
@mouseleave="closeShow = false"
>
<div class="box cards" @mouseenter="closeShow = true" @mouseleave="closeShow = false">
<transition name="el-fade-in-linear">
<close-one
class="close"
theme="filled"
size="28"
fill="#ffffff60"
v-show="closeShow"
@click="store.boxOpenState = false"
/>
<close-one class="close" theme="filled" size="28" fill="#ffffff60" v-show="closeShow"
@click="store.boxOpenState = false" />
</transition>
<transition name="el-fade-in-linear">
<setting-two class="setting" theme="filled" size="28" fill="#ffffff60" v-show="closeShow"
@click="store.setOpenState = true" />
</transition>
<div class="content">
<TimeCapsule />
@ -22,7 +16,7 @@
<script setup>
import { ref, watch } from "vue";
import { CloseOne } from "@icon-park/vue-next";
import { CloseOne, SettingTwo } from "@icon-park/vue-next";
import TimeCapsule from "@/components/TimeCapsule/index.vue";
import { mainStore } from "@/store";
const store = mainStore();
@ -47,22 +41,32 @@ watch(
margin-left: 0.75rem;
height: 80%;
position: relative;
&:hover {
transform: scale(1);
}
.close {
.close,
.setting {
position: absolute;
top: 14px;
right: 14px;
width: 28px;
height: 28px;
&:hover {
transform: scale(1.2);
}
&:active {
transform: scale(1);
}
}
.setting {
right: 56px;
}
.content {
padding: 30px;
width: 100%;

View File

@ -1,5 +0,0 @@
<template>
<div class="more">
</div>
</template>

200
src/views/MoreSet/index.vue Normal file
View File

@ -0,0 +1,200 @@
<template>
<div class="set" @mouseenter="closeShow = true" @mouseleave="closeShow = false" @click.stop>
<transition name="el-fade-in-linear">
<close-one class="close" theme="filled" size="28" fill="#ffffff60" v-show="closeShow"
@click="store.setOpenState = false" />
</transition>
<el-row :gutter="20">
<el-col :span="12" class="left">
<div class="logo">
<span class="bg">{{ siteUrl[0] }}</span>
<span class="sm">.{{ siteUrl[1] }}</span>
</div>
<div class="version">
<div class="num">v&nbsp;{{ config.version }}</div>
<el-tooltip content="Github 源代码仓库" placement="right" :show-arrow="false">
<github-one class="github" theme="outline" size="24" @click="jumpTo" />
</el-tooltip>
</div>
<el-card class="update">
<template #header>
<div class="card-header">
<span>更新日志</span>
</div>
</template>
<div class="upnote">
<div v-for="item in upData.new" :key="item" class="uptext">
<add-one theme="outline" size="22" />
{{ item }}
</div>
<div v-for="item in upData.fix" :key="item" class="uptext">
<bug theme="outline" size="22" />
{{ item }}
</div>
</div>
</el-card>
</el-col>
<el-col :span="12" class="right">
<div class="title">
<setting-two theme="filled" size="28" fill="#ffffff60" />
<span class="name">全局设置</span>
</div>
<Set />
</el-col>
</el-row>
</div>
</template>
<script setup>
import { reactive, ref } from "vue";
import { CloseOne, SettingTwo, GithubOne, AddOne, Bug } from "@icon-park/vue-next";
import { mainStore } from "@/store";
import Set from "@/components/Set/index.vue";
import config from '@/../package.json';
const store = mainStore();
let closeShow = ref(false);
//
let siteUrl = import.meta.env.VITE_SITE_URL.split(".");
//
let upData = reactive({
new: ["采用 Vue 进行重构", "音乐歌单支持快速自定义", "壁纸支持个性化设置", "音乐播放器支持音量控制"],
fix: ["修复天气 API", "时光胶囊显示错误", "移动端动画及细节", "图标更换为 IconPark"],
})
//
const jumpTo = () => {
window.open('https://github.com/imsyy/home');
};
</script>
<style lang="scss" scoped>
.set {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
width: 80%;
height: 80%;
background: rgb(255 255 255 / 40%);
border-radius: 6px;
padding: 40px;
.close {
position: absolute;
top: 14px;
right: 14px;
width: 28px;
height: 28px;
&:hover {
transform: scale(1.2);
}
&:active {
transform: scale(1);
}
}
.el-row {
height: 100%;
flex-wrap: nowrap;
.left {
height: 100%;
margin-left: 20px;
padding-bottom: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
.logo {
transform: translateY(-8%);
font-family: "Pacifico-Regular";
// line-height: 5rem;
.bg {
font-size: 5rem;
}
.sm {
margin-left: 6px;
font-size: 2rem;
}
}
.version {
display: flex;
flex-direction: row;
align-items: center;
.num {
font-size: 2rem;
font-family: 'Pacifico-Regular';
}
.github {
width: 24px;
height: 24px;
margin-left: 12px;
margin-top: 6px;
&:hover {
transform: scale(1.2);
}
}
}
.update {
margin-top: 30px;
height: 100%;
:deep(.el-card__body) {
height: 100%;
.upnote {
padding: 20px;
height: calc(100% - 56px);
overflow-y: auto;
.uptext {
display: flex;
flex-direction: row;
align-items: center;
padding-bottom: 16px;
.i-icon {
width: 22px;
height: 22px;
margin-right: 8px;
}
}
}
}
}
}
.right {
height: 100%;
padding-right: 40px !important;
.title {
display: flex;
align-items: center;
flex-direction: row;
font-size: 18px;
margin-bottom: 16px;
.i-icon {
width: 28px;
height: 28px;
margin-right: 6px;
}
}
}
}
}
</style>