自定义开启关闭顶部封面✅
This commit is contained in:
parent
b76b59088b
commit
b6fd209b0b
@ -15,15 +15,15 @@
|
|||||||
"@astrojs/mdx": "^4.2.3",
|
"@astrojs/mdx": "^4.2.3",
|
||||||
"@astrojs/rss": "^4.0.11",
|
"@astrojs/rss": "^4.0.11",
|
||||||
"@astrojs/sitemap": "^3.3.0",
|
"@astrojs/sitemap": "^3.3.0",
|
||||||
"@swup/astro": "^1.5.0",
|
"@swup/astro": "^1.6.0",
|
||||||
"aplayer": "^1.10.1",
|
"aplayer": "^1.10.1",
|
||||||
"astro": "^5.5.6",
|
"astro": "^5.6.0",
|
||||||
"overlayscrollbars": "^2.11.1",
|
"overlayscrollbars": "^2.11.1",
|
||||||
"vanilla-lazyload": "^19.1.3",
|
"vanilla-lazyload": "^19.1.3",
|
||||||
"vh-plugin": "^1.2.2"
|
"vh-plugin": "^1.2.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playform/compress": "^0.1.8",
|
"@playform/compress": "^0.1.9",
|
||||||
"@types/dplayer": "^1.25.5",
|
"@types/dplayer": "^1.25.5",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@waline/client": "^3.5.6",
|
"@waline/client": "^3.5.6",
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 86 KiB |
@ -1,54 +1,50 @@
|
|||||||
document.addEventListener('DOMContentLoaded', () => {
|
export default (element, options) => {
|
||||||
const vhPaopaoInit = (element, options) => {
|
document.querySelectorAll('.vh-paopao').forEach(item => setTimeout(() => item.remove()));
|
||||||
const config = Object.assign({ radius: 10, density: 0.3, clearOffset: 0.2 }, options);
|
const config = Object.assign({ radius: 10, density: 0.3, clearOffset: 0.2 }, options);
|
||||||
let width, height, ctx, active = true;
|
let width, height, ctx, active = true;
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
const particles = [];
|
const particles = [];
|
||||||
// 初始化画布
|
// 初始化画布
|
||||||
const initCanvas = () => {
|
const initCanvas = () => {
|
||||||
width = element.offsetWidth;
|
width = element.offsetWidth;
|
||||||
height = element.offsetHeight;
|
height = element.offsetHeight;
|
||||||
Object.assign(canvas.style, { top: '0', zIndex: '0', position: 'absolute', 'pointer-events': 'none' });
|
Object.assign(canvas.style, { top: '0', zIndex: '0', position: 'absolute', 'pointer-events': 'none' });
|
||||||
element.append(canvas);
|
element.append(canvas);
|
||||||
element.parentElement.style.overflow = 'hidden';
|
element.parentElement.style.overflow = 'hidden';
|
||||||
canvas.width = width;
|
canvas.width = width;
|
||||||
canvas.height = height;
|
canvas.height = height;
|
||||||
ctx = canvas.getContext('2d');
|
canvas.classList.add('vh-paopao');
|
||||||
};
|
ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
// 粒子类
|
|
||||||
class Particle {
|
|
||||||
constructor() { this.reset() }
|
|
||||||
reset() {
|
|
||||||
this.x = Math.random() * width;
|
|
||||||
this.y = height + 100 * Math.random();
|
|
||||||
this.alpha = 0.1 + Math.random() * config.clearOffset;
|
|
||||||
this.scale = 0.1 + 0.3 * Math.random();
|
|
||||||
this.speed = Math.random();
|
|
||||||
this.color = config.color === "random" ? `rgba(${Math.random() * 255 | 0},0,0,${Math.random().toFixed(2)})` : config.color;
|
|
||||||
}
|
|
||||||
draw() {
|
|
||||||
if (this.alpha <= 0) this.reset();
|
|
||||||
this.y -= this.speed;
|
|
||||||
this.alpha -= 0.0005;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(this.x, this.y, this.scale * config.radius, 0, Math.PI * 2);
|
|
||||||
ctx.fillStyle = this.color;
|
|
||||||
ctx.fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 初始化
|
|
||||||
initCanvas();
|
|
||||||
// 动画循环
|
|
||||||
const animate = () => { active && ctx.clearRect(0, 0, width, height); particles.forEach(p => p.draw()); requestAnimationFrame(animate); };
|
|
||||||
Array.from({ length: width * config.density | 0 }, () => particles.push(new Particle()));
|
|
||||||
animate();
|
|
||||||
// 事件监听
|
|
||||||
window.addEventListener('scroll', () => active = document.documentElement.scrollTop <= height);
|
|
||||||
window.addEventListener('resize', () => { width = element.clientWidth; height = element.clientHeight; canvas.width = width; canvas.height = height; });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 调用
|
// 粒子类
|
||||||
const target = document.querySelector('main.main > .header-main');
|
class Particle {
|
||||||
target && vhPaopaoInit(target, { radius: 10, density: 0.2, color: "rgba(255,255,255,.4)", clearOffset: 0.99 });
|
constructor() { this.reset() }
|
||||||
});
|
reset() {
|
||||||
|
this.x = Math.random() * width;
|
||||||
|
this.y = height + 100 * Math.random();
|
||||||
|
this.alpha = 0.1 + Math.random() * config.clearOffset;
|
||||||
|
this.scale = 0.1 + 0.3 * Math.random();
|
||||||
|
this.speed = Math.random();
|
||||||
|
this.color = config.color === "random" ? `rgba(${Math.random() * 255 | 0},0,0,${Math.random().toFixed(2)})` : config.color;
|
||||||
|
}
|
||||||
|
draw() {
|
||||||
|
if (this.alpha <= 0) this.reset();
|
||||||
|
this.y -= this.speed;
|
||||||
|
this.alpha -= 0.0005;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(this.x, this.y, this.scale * config.radius, 0, Math.PI * 2);
|
||||||
|
ctx.fillStyle = this.color;
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 初始化
|
||||||
|
initCanvas();
|
||||||
|
// 动画循环
|
||||||
|
const animate = () => { active && ctx.clearRect(0, 0, width, height); particles.forEach(p => p.draw()); requestAnimationFrame(animate); };
|
||||||
|
Array.from({ length: width * config.density | 0 }, () => particles.push(new Particle()));
|
||||||
|
animate();
|
||||||
|
// 事件监听
|
||||||
|
window.addEventListener('scroll', () => active = document.documentElement.scrollTop <= height);
|
||||||
|
window.addEventListener('resize', () => { width = element.clientWidth; height = element.clientHeight; canvas.width = width; canvas.height = height; });
|
||||||
|
};
|
||||||
@ -138,7 +138,7 @@ aside.vh-aside {
|
|||||||
|
|
||||||
&>.count {
|
&>.count {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 1rem 0;
|
padding: 1rem 0 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
gap: 0.88rem;
|
gap: 0.88rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: var(--vh-main-header-height);
|
height: var(--vh-main-header-height);
|
||||||
transition: height 0.3s ease-in-out;
|
transition: height 0.58s ease-in-out;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
@ -16,8 +16,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background: var(--vh-home-banner) no-repeat top center;
|
background: var(--vh-home-banner);
|
||||||
background-size: cover;
|
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,12 @@ export default {
|
|||||||
// 顶部 Banner 配置
|
// 顶部 Banner 配置
|
||||||
HomeBanner: {
|
HomeBanner: {
|
||||||
enable: true,
|
enable: true,
|
||||||
cover: '/assets/images/home-banner.webp'
|
// 首页高度
|
||||||
|
HomeHeight: '38.88rem',
|
||||||
|
// 其他页面高度
|
||||||
|
PageHeight: '28.88rem',
|
||||||
|
// 背景
|
||||||
|
background: "url('/assets/images/home-banner.webp') no-repeat center 60%/cover",
|
||||||
},
|
},
|
||||||
// 博客主题配置
|
// 博客主题配置
|
||||||
Theme: {
|
Theme: {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
const { title, keywords, description, pagecover, activeNav } = Astro.props;
|
const { title, keywords, description, pagecover, activeNav, Home } = Astro.props;
|
||||||
// 网站配置
|
// 网站配置
|
||||||
import SITE_INFO from "@/config";
|
import SITE_INFO from "@/config";
|
||||||
const { GoogleAds, Theme, HomeBanner } = SITE_INFO;
|
const { GoogleAds, Theme, HomeBanner } = SITE_INFO;
|
||||||
@ -30,15 +30,13 @@ import "./Layout.less";
|
|||||||
<Head Title={title} Keywords={keywords} Description={description} PageCover={pagecover}>
|
<Head Title={title} Keywords={keywords} Description={description} PageCover={pagecover}>
|
||||||
<!-- 谷歌广告JS加载项 -->
|
<!-- 谷歌广告JS加载项 -->
|
||||||
{ad_Client && (asideAD_Slot || articleAD_Slot) && <script is:inline async src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${ad_Client}`} crossorigin="anonymous" />}
|
{ad_Client && (asideAD_Slot || articleAD_Slot) && <script is:inline async src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${ad_Client}`} crossorigin="anonymous" />}
|
||||||
<!-- 泡泡🫧 -->
|
|
||||||
<script is:inline src="/assets/js/vhPaopao.js" defer></script>
|
|
||||||
<!-- 彩旗🎈 -->
|
<!-- 彩旗🎈 -->
|
||||||
<script is:inline src="/assets/js/vhCaiqi.js" defer></script>
|
<script is:inline src="/assets/js/vhCaiqi.js" defer></script>
|
||||||
<!-- 设置主题颜色 -->
|
<!-- 设置主题颜色 -->
|
||||||
<Fragment
|
<Fragment
|
||||||
set:html={`<style>:root {${Object.entries(Theme)
|
set:html={`<style>:root {${Object.entries(Theme)
|
||||||
.map(([key, value]) => `${key}:${value};`)
|
.map(([key, value]) => `${key}:${value};`)
|
||||||
.join("")}--vh-home-banner:url('${HomeBanner.cover}')}</style>`}
|
.join("")}--vh-main-header-height:${Home ? HomeBanner.HomeHeight : HomeBanner.PageHeight};--vh-home-banner:${HomeBanner.background}}</style>`}
|
||||||
/>
|
/>
|
||||||
</Head>
|
</Head>
|
||||||
<body>
|
<body>
|
||||||
@ -46,7 +44,7 @@ import "./Layout.less";
|
|||||||
<Header activeNav={activeNav} />
|
<Header activeNav={activeNav} />
|
||||||
<main class="main">
|
<main class="main">
|
||||||
{HomeBanner.enable && <MainHeader />}
|
{HomeBanner.enable && <MainHeader />}
|
||||||
<section class="main-inner" style={`padding-top:${HomeBanner.enable ? "2rem" : "calc(66px + 0.68rem)"}`}>
|
<section class="main-inner" style={`padding-top:${HomeBanner.enable ? "0.88rem" : "calc(66px + 0.68rem)"}`}>
|
||||||
<section class="main-inner-content">
|
<section class="main-inner-content">
|
||||||
<slot />
|
<slot />
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -31,7 +31,7 @@ import Pagination from "@/components/Pagination/Pagination.astro";
|
|||||||
const currentPage = page_data.url.current.replace("/", "");
|
const currentPage = page_data.url.current.replace("/", "");
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title={currentPage ? `第${currentPage}页文章` : ""} description={Description}>
|
<Layout title={currentPage ? `第${currentPage}页文章` : ""} description={Description} Home={true}>
|
||||||
<section class="article-list-main">
|
<section class="article-list-main">
|
||||||
<section class="article-list">
|
<section class="article-list">
|
||||||
<!-- 文章列表 -->
|
<!-- 文章列表 -->
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import { inRouter, outRouter } from "@/utils/updateRouter";
|
import { inRouter, outRouter } from "@/utils/updateRouter";
|
||||||
// Banner 打字效果
|
// Banner 打字效果
|
||||||
import TypeWriteInit from "@/scripts/TypeWrite";
|
import TypeWriteInit from "@/scripts/TypeWrite";
|
||||||
|
// 泡泡🫧效果
|
||||||
|
import PaoPaoInit from "@/scripts/PaoPao";
|
||||||
// 初始化文章代码块
|
// 初始化文章代码块
|
||||||
import codeInit from "@/scripts/Code";
|
import codeInit from "@/scripts/Code";
|
||||||
// 初始化视频播放器
|
// 初始化视频播放器
|
||||||
@ -45,8 +47,6 @@ const videoList: any[] = [];
|
|||||||
const MusicList: any[] = [];
|
const MusicList: any[] = [];
|
||||||
let commentLIst: any = { walineInit: null };
|
let commentLIst: any = { walineInit: null };
|
||||||
const indexInit = async (only: boolean = true) => {
|
const indexInit = async (only: boolean = true) => {
|
||||||
// 打字效果
|
|
||||||
only && TypeWriteInit();
|
|
||||||
// 初始化网站运行时间
|
// 初始化网站运行时间
|
||||||
only && initWebSiteTime();
|
only && initWebSiteTime();
|
||||||
// 初始化BackTop组件
|
// 初始化BackTop组件
|
||||||
@ -79,6 +79,10 @@ const indexInit = async (only: boolean = true) => {
|
|||||||
checkComment() && commentInit(checkComment(), commentLIst)
|
checkComment() && commentInit(checkComment(), commentLIst)
|
||||||
// Han Analytics 统计
|
// Han Analytics 统计
|
||||||
HanAnalyticsInit();
|
HanAnalyticsInit();
|
||||||
|
// 打字效果
|
||||||
|
only && TypeWriteInit();
|
||||||
|
// 泡泡🫧效果
|
||||||
|
PaoPaoInit();
|
||||||
// 预加载搜索数据
|
// 预加载搜索数据
|
||||||
only && searchFn("");
|
only && searchFn("");
|
||||||
// 初始化搜索功能
|
// 初始化搜索功能
|
||||||
|
|||||||
12
src/scripts/PaoPao.ts
Normal file
12
src/scripts/PaoPao.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import vhPaopaoInit from '../../public/assets/js/vhPaopao.js';
|
||||||
|
let headerMainHeight = 0;
|
||||||
|
export default async () => {
|
||||||
|
// 调用
|
||||||
|
const target = document.querySelector('main.main > .header-main');
|
||||||
|
if (!target) return;
|
||||||
|
setTimeout(() => {
|
||||||
|
if (headerMainHeight == target.clientHeight) return;
|
||||||
|
headerMainHeight = target.clientHeight;
|
||||||
|
vhPaopaoInit(target, { radius: 10, density: 0.2, color: "rgba(255,255,255,.4)", clearOffset: 0.99 });
|
||||||
|
}, 688);
|
||||||
|
}
|
||||||
@ -201,6 +201,9 @@
|
|||||||
|
|
||||||
// :::note
|
// :::note
|
||||||
&.vh-note {
|
&.vh-note {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.688rem;
|
||||||
padding: 0.888rem;
|
padding: 0.888rem;
|
||||||
border-left: 5px solid #eee;
|
border-left: 5px solid #eee;
|
||||||
border-left-color: #777;
|
border-left-color: #777;
|
||||||
@ -242,9 +245,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
padding: 0.38rem 0;
|
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
line-height: 1.388rem;
|
line-height: 1.58rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,9 +8,7 @@
|
|||||||
// Body 背景颜色
|
// Body 背景颜色
|
||||||
--vh-body-bg: #F8F8F8;
|
--vh-body-bg: #F8F8F8;
|
||||||
// Back Top 按钮位置
|
// Back Top 按钮位置
|
||||||
--vh-back-top: calc((calc(100vw - 2rem) - min((100vw - 2rem), var(--vh-main-max-width))) / 2);
|
--vh-back-top: calc((calc(100vw - 2rem) - min((100vw - 2rem), var(--vh-main-max-width))) / 2 + 1rem);
|
||||||
// Main Header 封面高度
|
|
||||||
--vh-main-header-height: 38.88rem;
|
|
||||||
// 字体颜色
|
// 字体颜色
|
||||||
--vh-font-88: rgb(from var(--vh-font-color) r g b / 88%);
|
--vh-font-88: rgb(from var(--vh-font-color) r g b / 88%);
|
||||||
--vh-font-66: rgb(from var(--vh-font-color) r g b / 66%);
|
--vh-font-66: rgb(from var(--vh-font-color) r g b / 66%);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user