feat: 优化消息通知效果

This commit is contained in:
imsyy 2023-07-31 14:12:31 +08:00
parent 82d822d8a6
commit 855c313fec
9 changed files with 172 additions and 42 deletions

3
.env
View File

@ -1,2 +1,5 @@
# 搜索框提示词
VITE_INPUT_TIP = "想要搜点什么"
# 进入欢迎词
VITE_WELCOME_TEXT = "欢迎访问本站"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 138 KiB

View File

@ -1,6 +1,6 @@
<template>
<!-- 壁纸 -->
<Cover />
<Cover @loadComplete="loadComplete" />
<!-- 主界面 -->
<Transition name="fade" mode="out-in">
<main v-if="status.imgLoadStatus" id="main" @click="mainClick">
@ -20,19 +20,36 @@
</template>
<script setup>
import { nextTick } from "vue";
import { statusStore } from "@/stores";
import { Notivue, Notifications } from "notivue";
import { Notivue, Notifications, usePush } from "notivue";
import { getGreeting } from "@/utils/timeTools";
import Cover from "@/components/Cover.vue";
import WeatherTime from "@/components/WeatherTime.vue";
import SearchInp from "@/components/SearchInp.vue";
import Footer from "@/components/Footer.vue";
const status = statusStore();
const push = usePush();
//
const welcomeText = import.meta.env.VITE_WELCOME_TEXT ?? "欢迎访问本站";
//
const mainClick = () => {
status.setSiteStatus("normal");
};
//
const loadComplete = () => {
nextTick(() => {
push.info({
title: getGreeting(),
message: welcomeText,
duration: 2000,
});
});
};
</script>
<style lang="scss" scoped>

View File

@ -7,6 +7,7 @@
:src="bgUrl"
@load="imgLoadComplete"
@error.once="imgLoadError"
@animationend="imgAnimationEnd"
/>
<Transition name="fade">
<div v-if="set.showBackgroundGray" class="gray" />
@ -22,6 +23,7 @@ const set = setStore();
const status = statusStore();
const bgUrl = ref(null);
const imgTimeout = ref(null);
const emit = defineEmits(["loadComplete"]);
//
// Math.random()
@ -53,8 +55,14 @@ const setBgUrl = () => {
const imgLoadComplete = () => {
imgTimeout.value = setTimeout(() => {
status.setImgLoadStatus(true);
console.log("壁纸加载完成");
}, 500);
}, Math.floor(Math.random() * (600 - 300 + 1)) + 300);
};
//
const imgAnimationEnd = () => {
console.log("壁纸加载且动画完成");
//
emit("loadComplete");
};
//

View File

@ -6,9 +6,11 @@
@click="closeSearchInput"
/>
<div
ref="searchAllRef"
:class="status.siteStatus === 'focus' ? 'all focus' : 'all'"
:style="{ pointerEvents: inputClickable ? 'none' : 'auto' }"
ref="searchAllRef"
@animationstart="inputClickable = true"
@animationend="inputAnimationEnd"
>
<div class="engine" title="切换搜索引擎">
<SvgIcon iconName="icon-baidu" className="baidu" />
@ -40,9 +42,9 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { statusStore, setStore } from "@/stores";
import { ref } from "vue";
import { usePush } from "notivue";
import { statusStore, setStore } from "@/stores";
import Suggestions from "@/components/Suggestions.vue";
const set = setStore();
@ -109,26 +111,19 @@ const toSearch = (val, type = 1) => {
} else {
status.setSiteStatus("focus");
searchInputRef.value?.focus();
push.info({ message: "请输入搜索内容", duration: 1000 });
push.info({ message: "请输入搜索内容", duration: 1500 });
}
};
// Dom
const searchInputDom = (dom) => {
if (!dom) return false;
dom.addEventListener("animationstart", () => {
console.log("动画开始");
inputClickable.value = true;
});
dom.addEventListener("animationend", () => {
console.log("动画结束");
//
const inputAnimationEnd = () => {
console.log("搜索框动画结束");
inputClickable.value = false;
// focus
if (set.autoFocus) {
status.setSiteStatus("focus");
searchInputRef.value?.focus();
}
});
};
//
@ -140,10 +135,6 @@ const pressKeyboard = (event) => {
//
suggestionsRef.value?.keyboardEvents(keyCode, event);
};
onMounted(() => {
searchInputDom(searchAllRef.value);
});
</script>
<style lang="scss" scoped>

View File

@ -232,7 +232,10 @@ defineExpose({ keyboardEvents });
left: 0;
width: 100%;
max-height: 44vh;
overflow-y: auto;
overflow-y: scroll;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
color: var(--main-text-color);
background-color: var(--main-background-light-color);
backdrop-filter: blur(30px) saturate(1.25);
@ -260,12 +263,22 @@ defineExpose({ keyboardEvents });
text-overflow: ellipsis;
white-space: nowrap;
}
@media (min-width: 520px) {
&:hover,
&.focus {
background-color: var(--main-background-light-color);
padding-left: 18px;
}
}
&:active {
background-color: var(--main-background-light-color);
padding-left: 18px;
}
}
}
&::-webkit-scrollbar {
width: 0;
height: 0;
}
}
</style>

View File

@ -7,8 +7,7 @@ import SvgIcon from "@/components/SvgIcon.vue";
import "@/utils/iconfont.js";
// Notivue
import { notivue } from "notivue";
import "notivue/notifications.css"; // Only needed if using built-in notifications
import "notivue/animations.css"; // Only needed if using built-in animations
import "notivue/notifications.css";
// 主组件
import App from "@/App.vue";
@ -27,6 +26,11 @@ app.use(pinia);
app.use(notivue, {
pauseOnHover: false,
limit: 1,
animations: {
enter: "notivue-slide-in",
leave: "notivue-slide-out",
clearAll: "notivue-fade",
},
});
app.component("SvgIcon", SvgIcon);
app.mount("#app");

View File

@ -29,11 +29,6 @@ body {
height: 100vh;
}
::selection {
color: var(--main-text-color);
background-color: var(--main-text-hover-color);
}
// Transition 动画
.fade-enter-active,
.fade-leave-active {
@ -68,6 +63,12 @@ body {
}
// Notivue
.notivue-slide-in {
animation: notivue-slide-in 0.7s ease-in-out both;
}
.notivue-slide-out {
animation: notivue-slide-out 0.3s ease-in-out both;
}
.Notivue__notification {
background-color: var(--main-background-light-color);
// backdrop-filter: blur(30px) saturate(1.25);
@ -77,11 +78,27 @@ body {
display: none;
}
.Notivue__content {
padding: 0.5rem;
.Notivue__content-message {
text-align: center;
padding: 0.8rem 0.5rem;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
.Notivue__content-title {
margin: 0;
margin-right: 6px;
line-height: inherit;
color: var(--main-text-grey-color);
}
.Notivue__content-message {
line-height: inherit;
color: var(--main-text-grey-color);
}
@media (max-width: 480px) {
flex-direction: column;
.Notivue__content-title {
margin-bottom: 6px;
}
}
}
}
@ -148,3 +165,56 @@ body {
transform: scale(1);
}
}
@keyframes notivue-slide-in {
0% {
opacity: 0;
transform: translateY(-200px);
}
50% {
opacity: 1;
transform: translateY(10px);
}
70% {
transform: translateY(-5px);
}
100% {
transform: translateY(0);
}
}
@keyframes notivue-slide-out {
from {
transform: perspective(400px);
}
30% {
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
opacity: 1;
}
to {
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
opacity: 0;
}
}
// 文本选中
::selection {
color: var(--main-text-color);
background-color: var(--main-text-hover-color);
}
// 滚动条
::-webkit-scrollbar {
background-color: transparent;
width: 6px;
}
::-webkit-scrollbar-track {
display: none;
}
::-webkit-scrollbar-thumb {
border-radius: 12px;
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
background-color: var(--main-background-color);
}

View File

@ -27,3 +27,27 @@ export const getCurrentTime = () => {
};
return currentTime;
};
/**
* 根据实时时间返回不同的问候语
* @returns {string} 问候语
*/
export const getGreeting = () => {
const currentTime = new Date();
const currentHour = currentTime.getHours();
let greeting = "";
if (currentHour >= 5 && currentHour < 9) {
greeting = "早上好";
} else if (currentHour >= 9 && currentHour < 12) {
greeting = "上午好";
} else if (currentHour >= 12 && currentHour < 18) {
greeting = "下午好";
} else if (currentHour >= 18 && currentHour < 24) {
greeting = "晚上好";
} else if (currentHour >= 0 && currentHour < 5) {
greeting = "凌晨好";
} else {
greeting = "夜深了";
}
return greeting;
};