|
|
<template> <Simplebar @scroll="handleScroll"> <!-- 头部导航菜单 --> <div class="headerMenu" v-if="show_menu"> <a-menu v-model:selectedKeys="current" mode="horizontal" :items="items" style="border-bottom: none;" @click="menuClick" @select="menuSelect"/> <a-input-search v-model:value="value" placeholder="search" style="width: 200px" @search="onSearch" /> </div> <div class="author" v-if="show_author"></div>
<!-- 轮播 --> <div class="carousel" v-if="show_carousel"> <a-carousel autoplay> <div class="img"><img src="/src/assets/images/nav1.png" alt=""></div> <div class="img"><img src="/src/assets/images/nav10.png" alt=""></div> <div class="img"><img src="/src/assets/images/nav13.png" alt=""></div> </a-carousel> </div> <!-- 操作按钮滚动 --> <div class="anchorDown"> <a-button type="link" shape="circle" size="large" @click="downScroll"> <template #icon> <DownCircleOutlined style="font-size: 35px;color: aliceblue;" spin /> </template> </a-button> </div>
<!-- 主要内容区域 --> <div class="mainContainer" :style="mainCss"> <div class="leftBar"> <a-card hoverable> <template #cover> <img alt="example" :src="img" /> </template> <h1>sunfree</h1> <div class="cardText"></div> <div class="button-group"> <a-button shape="circle" size="large" @click="gravatarClick"> <GravatarLined /> </a-button> <a-button shape="circle" size="large"> <QQLined /> </a-button> <a-button shape="circle" size="large"> <WechatLined /> </a-button> <a-button shape="circle" size="large"> <MusicLined /> </a-button> <a-button shape="circle" size="large"> <GitHubLined /> </a-button> </div> <div class="fold-panel"> <a-collapse v-model:activeKey="activeKey" :bordered="false" expandIconPosition="end"> <template #expandIcon="{ isActive }"> <caret-right-outlined :rotate="isActive ? 90 : 0" /> </template> <a-collapse-panel key="1" header="内容1" :style="customStyle"> <p>{{ text }}</p> </a-collapse-panel> <a-collapse-panel key="2" header="内容2" :style="customStyle"> <p>{{ text }}</p> </a-collapse-panel> <a-collapse-panel key="3" header="内容3" :style="customStyle"> <p>{{ text }}</p> </a-collapse-panel> </a-collapse> </div> </a-card> <a-card hoverable title="常用链接"> <div class="button-group"> <a-button type="dashed">Link</a-button> <a-button type="dashed">Link</a-button> <a-button type="dashed">Link</a-button> <a-button type="dashed">Link</a-button> <a-button type="dashed">Link</a-button> <a-button type="dashed">Link</a-button> <a-button type="dashed">Link</a-button> <a-button type="dashed">Link</a-button> <a-button type="dashed">Link</a-button> <a-button type="dashed">Link</a-button> <a-button type="dashed">Link</a-button> <a-button type="dashed">Link</a-button> </div> </a-card> </div> <RouterView /> <div class="rightBar"> <a-card hoverable style="width: 400px;"> <template #cover> <div id="aplayer" style="width: 400px;"></div> <div class="heatmap" style="border-right: rgba(0, 0, 0, 0.5);"> <div ref="heat" style="height: 100%;"></div> </div> <div class="statistic"> <a-row> <a-col :span="8"> <a-statistic title="DAYS" :value="112893" /> </a-col> <a-col :span="8"> <a-statistic title="DIARYS" :value="112893" /> </a-col> <a-col :span="8"> <a-statistic title="BLOGS" :value="112893" /> </a-col> </a-row> </div> </template> </a-card> <a-card title="随机文章" :bordered="false" hoverable style="width: 400px;margin: 12px 0;"> sces </a-card>
<a-card title="标签云" :bordered="false" hoverable style="width: 400px;margin: 12px 0;"> sces </a-card> </div> </div>
</Simplebar> </template> <script lang="ts" setup> import { h, reactive, ref,nextTick } from 'vue'; import { MenuProps } from 'ant-design-vue/es/menu'; import { HomeOutlined, HighlightOutlined, ProfileOutlined, CameraOutlined, UsergroupDeleteOutlined, DownCircleOutlined } from '@ant-design/icons-vue'; import { MusicLined, EmailLined, QQLined, WechatLined, GravatarLined, GitHubLined } from "@/assets" import Typed from 'typed.js'; import { onMounted,watch } from 'vue'; import type { CSSProperties } from 'vue'; import { CaretRightOutlined } from '@ant-design/icons-vue'; import 'APlayer/dist/APlayer.min.css'; import APlayer from 'APlayer'; import { createEcharts } from "@/hooks/intex" import { SettingOutlined, EditOutlined, EllipsisOutlined } from '@ant-design/icons-vue'; import { RiLiLined, YueDuLined, YanJingLined, XieZiLined } from '@/assets'; import { useRouter, useRoute } from 'vue-router'; const random = ref(); const router = useRouter() const route = useRoute() const heat = ref(null); const activeKey = ref(['']); const text = `A dog is a type of domesticated animal.Known for its loyalty and faithfulness,it can be found as a welcome guest in many households across the world.`; const customStyle = 'background: #F5F5F5;border-radius: 4px;margin-bottom: 12px;border: 0;overflow: hidden'; const scrollbar=ref<Element | null>(null); onMounted(() => { // 定义home页的博客标题名
new Typed('.author', { strings: ['SunFree.'], typeSpeed: 200, backSpeed: 150, loop: true, loopCount: Infinity, showCursor: false }); // 定义个人座右铭
new Typed('.cardText', { strings: ['做三流测试,品瀚霖人生!'], typeSpeed: 200, backSpeed: 150, loop: true, // 开启循环
loopCount: Infinity, // 无限循环
showCursor: false // 取消光标
}); new APlayer({ container: document.getElementById('aplayer'), mini: false, autoplay: false, theme: '#FADFA3', loop: 'all', order: 'random', preload: 'auto', volume: 0.7, mutex: true, listFolded: true, listMaxHeight: 90, lrcType: 3, audio: [ { name: 'name1', artist: 'artist1', url: 'url1.mp3', cover: 'cover1.jpg', lrc: 'lrc1.lrc', theme: '#ebd0c2' }, { name: 'name2', artist: 'artist2', url: 'url2.mp3', cover: 'cover2.jpg', lrc: 'lrc2.lrc', theme: '#46718b' } ] }); function generateDates(numDays: number) { const dates = []; const currentDate = new Date(); for (let i = 0; i < numDays; i++) { const date = new Date(currentDate); date.setDate(currentDate.getDate() - i); dates.push( { date: date.toISOString().split('T')[0], blogCount: 0 } ); // 包含日期和评论数
} return dates; }
// 初始化60天的数据
const data = generateDates(60); console.log(`output->`, data) data[3].blogCount = 5; data[15].blogCount = 10; data[25].blogCount = 3;
// 重新排列数据
const newData = []; for (let i = 0; i < 60; i += 15) { // 取出每个15天的数据,并反转顺序
const chunk = data.slice(i, i + 15).reverse(); newData.push(...chunk); }
const formattedData = newData.map((value, index) => [index % 15, Math.floor(index / 15), value.blogCount]); const heatMapData = { tooltip: { position: 'top', formatter: function (params: any) { const item = newData[params.dataIndex]; if (item.blogCount > 0) { return `${item.date}<br/>COMMENTS: ${item.blogCount}`; } else { return `${item.date}`; } } }, grid: { left: '0', // 左边距
right: '0', // 右边距
top: '0', // 上边距
bottom: '0', }, xAxis: { type: 'category', data: Array.from({ length: 15 }, (_, i) => `Col ${i + 1}`), splitArea: { show: true }, show: false }, yAxis: { type: 'category', data: ['Row 1', 'Row 2', 'Row 3', 'Row 4'], splitArea: { show: false }, show: false }, visualMap: { min: 0, max: 10, calculable: true, orient: 'horizontal', left: 'center', bottom: '15%', itemGap: 5, show: false, inRange: { color: ['#ffffff', '#000000'] // 0评论是白色, 非0评论是黑色
} }, series: [{ type: 'heatmap', data: formattedData, itemStyle: { borderColor: 'rgba(0, 0, 0, 0.1)', // 设置边框颜色
borderWidth: 0.5, // 设置边框宽度
}, label: { show: false, }, emphasis: { itemStyle: { shadowBlur: 10, shadowColor: 'rgba(0, 0, 0, 0.5)', borderColor: '#fff', // 鼠标悬停时的边框颜色
borderWidth: 2 // 鼠标悬停时的边框宽度
} } }] }; createEcharts(heat, heatMapData); scrollbar.value = document.querySelector('.simplebar-content-wrapper'); // const storedShowMenu = localStorage.getItem('show_menu');
// const storedShowCarousel = localStorage.getItem('show_carousel');
// const storedScrollPosition = localStorage.getItem('scrollPosition');
// const storedMainCssMarginTop = localStorage.getItem('mainCss_marginTop');
// if (storedShowMenu !== null) {
// show_menu.value = storedShowMenu === 'true';
// }
// if (storedShowCarousel !== null) {
// show_carousel.value = storedShowCarousel === 'true';
// }
// if (storedScrollPosition !== null && scrollbar.value) {
// scrollbar.value.scrollTop = parseInt(storedScrollPosition, 10);
// }
// if (storedMainCssMarginTop !== null) {
// mainCss.marginTop = storedMainCssMarginTop;
// }
})
// 导航菜单
const show_menu = ref(false); const show_carousel = ref(true); const show_author = ref(true) const mainCss=reactive({ marginTop:"0px" })
const items = ref<MenuProps['items']>([ { key: 'home', icon: () => h(HomeOutlined), label: '首页', title: '首页', url: '/' }, { key: 'blog', icon: () => h(HighlightOutlined), label: '博客', title: '博客', url: "/blog" }, { key: 'diary', icon: () => h(ProfileOutlined), label: '日记', title: '日记', url: '/diary' }, { key: 'album', icon: () => h(CameraOutlined), label: '相册', title: '相册', children: [ { label: '相册1', key: 'album1', }, { label: '相册2', key: 'album2', }, { label: '相册3', key: 'album3', }, { label: '相册4', key: 'album4', }, ], }, { key: 'aboutme', icon: () => h(UsergroupDeleteOutlined), label: '关于sunfree', title: '关于sunfree', }, ]); const handleScrollEnabled = ref(true); // 定义滚动条滚到一半显示导航菜单
const handleScroll = () => { if (!handleScrollEnabled.value) return; if (scrollbar.value) { const scrollOffset = scrollbar.value.scrollTop; const halfViewportHeight = scrollbar.value.clientHeight / 2; show_menu.value = scrollOffset > halfViewportHeight; } };
const menuClick = ({ item }: { item: any }) => { handleScrollEnabled.value=false if (scrollbar.value) { } if (item.url=="/" || item.url=="/home") { handleScrollEnabled.value=true show_carousel.value=true }else{ show_menu.value=true show_carousel.value=false scrollbar.value!.scrollTop=0 mainCss.marginTop="48px" // localStorage.setItem('show_menu', 'true');
// localStorage.setItem('show_carousel', 'false');
// localStorage.setItem('scrollPosition', '0');
// localStorage.setItem('mainCss_marginTop', '48px');
} router.push(item.url) } const current = ref<string[]>(['mail']);
// 点击按钮,实现滚动到视窗高度距离,如果已经滚动,只需要滚动视窗高度-已经滚动的距离
const downScroll = () => { if (scrollbar.value) { const scrollTop = scrollbar.value.scrollTop; const viewportHeight = scrollbar.value.clientHeight; const scrollDistance = viewportHeight - scrollTop -48;
setTimeout(() => { scrollbar.value!.scrollBy({ top: scrollDistance, behavior: 'smooth' }); }, 300); } }; // 定义文章
// const articles=reactive({
// img:"",
// })
const value = ref<string>(''); const onSearch = (searchValue: string) => { console.log('use value', searchValue); console.log('or use this.value', value.value); };
const img = ref("https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png")
const gravatarClick = () => { window.open("https://www.baidu.com") } </script> <style scoped> .headerMenu { display: flex; justify-content: center; align-items: center; width: 100%; height: 48px; border-bottom: 1px solid rgba(5, 5, 5, 0.06); position: fixed; background-color: white; transform: translateX(-50%); top: 0; left: 50%; z-index: 999; }
/* 作者名称 */ .author { position: absolute; display: inline-block; font-size: 100px; font-family: 'Courier New', Courier, monospace; background: linear-gradient(270deg, #f5f4f2, #d6cdc7, #4b4949); background-size: 400% 400%; -webkit-background-clip: text; color: transparent; background-clip: text; animation: salon-light-animation 3s ease infinite; top: 50%; left: 50%; transform: translateX(-50%); z-index: 999; }
@keyframes salon-light-animation { 0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; } }
.carousel img{ height: 100vh; width: 100vw; } .anchorDown { position: absolute; bottom: 100px; left: 50%; border-style: hidden; transform: translateX(-50%); }
.mainContainer { display: flex; justify-content: center; padding-top: 48px; background-color: rgba(5, 5, 5, 0.08); }
.leftBar { width: 15%; }
.leftBar img { /* 图片自适应容器并保持宽高比例 */ aspect-ratio: 1/1; }
.leftBar>* { margin-bottom: 24px; }
.leftBar h1 { text-align: center; font-family: Georgia, 'Times New Roman', Times, serif; }
.leftBar .cardText { min-height: 60px; text-align: center; }
.leftBar>:first-child .button-group { display: flex; margin: 0 12px 24px 12px; justify-content: space-between; }
.leftBar>:nth-child(2) .button-group { display: flex; flex-wrap: wrap; justify-content: space-between; }
.leftBar>:nth-child(2) .button-group>* { width: 40%; margin: 12px; }
.rightBar { width: 20%; }
.aplayer { margin: 0 0 24px 0; }
.heatmap { margin: 24px 0; }
.statistic { text-align: center; }
.sitebar { width: 400px; } </style>
|