<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TENGYUAN 个人博客</title>
<!-- 引入阿里巴巴图标库 -->
<link rel="stylesheet" href="https://at.alicdn.com/t/c/font_4005972_5ehi8q0b1j9.css">
<!-- 引入Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- 访客统计 -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<!-- Alpine.js 用于交互功能 -->
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
<style>
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
outline: none;
}
/* 整体页面样式 - 漫画风格 */
body {
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
background-color: #1a1a2e;
color: #e2e8f0;
line-height: 1.6;
transition: background-color 0.3s ease, color 0.3s ease;
}
/* 主容器样式 */
.container {
display: flex;
max-width: 1600px;
height: 100vh;
margin: 0 auto;
position: relative;
background-color: #16213e;
}
/* 左侧边栏样式 */
.left-side {
width: 260px;
border-right: 2px solid rgba(255, 255, 255, 0.1);
display: flex;
flex-direction: column;
transition: all 0.3s ease;
background-color: #16213e;
overflow: auto;
flex-shrink: 0;
z-index: 50;
position: relative;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
/* 右侧边栏样式 */
.right-side {
width: 280px;
flex-shrink: 0;
margin-left: auto;
overflow: auto;
background-color: rgba(22, 33, 62, 0.8);
display: flex;
flex-direction: column;
border-left: 2px solid rgba(255, 255, 255, 0.1);
z-index: 40;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
/* 主要内容区域样式 */
.main {
flex-grow: 1;
display: flex;
flex-direction: column;
background-color: #1a1a2e;
overflow: hidden;
}
/* Logo样式 - 漫画风格 */
.logo {
font-family: "PingFang SC", sans-serif;
font-size: 18px;
color: #f8fafc;
font-weight: 800; /* 加粗 */
text-align: center;
height: 68px;
line-height: 68px;
letter-spacing: 4px;
position: sticky;
top: 0;
background-color: rgba(22, 33, 62, 0.8);
z-index: 2;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
text-shadow: 2px 2px 0 #0f3460;
}
/* 侧边栏标题样式 */
.side-title {
font-family: "PingFang SC", sans-serif;
color: #94a3b8;
font-size: 14px;
font-weight: 800; /* 加粗 */
margin-bottom: 20px;
text-transform: uppercase;
letter-spacing: 1px;
border-bottom: 2px solid rgba(255, 255, 255, 0.1);
padding-bottom: 8px;
}
/* 侧边栏内容区域样式 */
.side-wrapper {
padding: 25px;
}
/* 侧边栏菜单样式 - 漫画风格 */
.side-menu {
display: flex;
flex-direction: column;
font-size: 15px;
white-space: nowrap;
}
.side-menu svg {
margin-right: 16px;
width: 16px;
color: #94a3b8;
}
.side-menu a {
text-decoration: none;
color: #94a3b8;
display: flex;
align-items: center;
padding: 10px 0;
transition: all 0.3s ease;
border-radius: 6px;
font-weight: 600;
}
.side-menu a:hover {
color: #ffffff;
background-color: rgba(255, 255, 255, 0.1);
transform: translateX(5px);
padding-left: 10px;
text-shadow: 1px 1px 0 #0f3460;
}
.side-menu a.active {
color: #ffffff;
padding-left: 10px;
font-weight: 800;
text-shadow: 1px 1px 0 #0f3460;
}
/* 底部关注区域样式 */
.follow-me {
text-decoration: none;
font-size: 14px;
display: flex;
align-items: center;
margin-top: auto;
overflow: hidden;
color: #94a3b8;
padding: 0 25px;
height: 60px;
flex-shrink: 0;
border-top: 2px solid rgba(255, 255, 255, 0.1);
position: relative;
transition: all 0.3s ease;
font-weight: 600;
}
.follow-me svg {
width: 16px;
height: 16px;
margin-right: 12px;
}
.follow-text {
display: flex;
align-items: center;
transition: 0.3s;
}
.follow-me:hover .follow-text {
transform: translateY(100%);
}
.follow-me:hover .developer {
top: 0;
}
.developer {
position: absolute;
color: #ffffff;
left: 0;
top: -100%;
display: flex;
transition: 0.3s;
padding: 0 25px;
align-items: center;
background-color: rgba(22, 33, 62, 0.9);
width: 100%;
height: 100%;
font-weight: 600;
text-shadow: 1px 1px 0 #0f3460;
}
.developer img {
border-radius: 50%;
width: 30px;
height: 30px;
object-fit: cover;
margin-right: 12px;
border: 2px solid rgba(255, 255, 255, 0.2);
}
/* 搜索栏样式*/
.search-bar {
height: 100px;
background-color: rgba(22, 33, 62, 0.8);
z-index: 3;
position: relative;
display: flex;
align-items: center;
padding: 0px;
border-bottom: 2px solid rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.search-container {
display: flex;
align-items: center;
width: 100%;
position: relative;
}
.search-bar input {
height: 50px;
width: 100%;
display: block;
background-color: rgba(255, 255, 255, 0.08);
border: 2px solid rgba(255, 255, 255, 0.2);
padding: 0 60px 0 50px;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='512' height='512'%3e%3cpath d='M508.9 478.7L360 330a201.6 201.6 0 0045.2-127.3C405.3 90.9 314.4 0 202.7 0S0 91 0 202.7s91 202.6 202.7 202.6c48.2 0 92.4-17 127.3-45.2L478.7 509c4.2 4.1 11 4.1 15 0l15.2-15.1c4.1-4.2 4.1-11 0-15zm-306.2-116c-88.3 0-160-71.8-160-160s71.7-160 160-160 160 71.7 160 160-71.8 160-160 160z' data-original='%23000000' class='active-path' data-old_color='%23000000' fill='%2394a3b8'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-size: 18px;
background-position: 20px 50%;
}
/* 主内容容器样式 */
.main-container {
padding: 30px;
flex-grow: 1;
overflow: auto;
background-color: #1a1a2e;
}
/* 个人资料区域样式 - 漫画风格 */
.profile {
position: relative;
height: 40vh;
min-height: 250px;
max-height: 350px;
z-index: 1;
border-radius: 16px;
overflow: hidden;
margin-bottom: 30px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
border: 2px solid rgba(255, 255, 255, 0.1);
}
.profile-cover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
transition: transform 0.5s ease;
}
.profile:hover .profile-cover {
transform: scale(1.05);
}
.profile:before {
content: "";
width: 100%;
height: 100%;
position: absolute;
z-index: -1;
left: 0;
top: 0;
background-image: url("https://images.unsplash.com/photo-1508247967583-7d982ea01526?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2250&q=80");
background-repeat: no-repeat;
background-size: cover;
background-position: center;
filter: blur(50px);
opacity: 0.7;
}
/* 个人资料菜单样式 */
.profile-menu {
position: absolute;
bottom: 0;
padding-left: 200px;
background: rgba(22, 33, 62, 0.7);
width: 100%;
display: flex;
border-radius: 0 0 16px 16px;
overflow-x: auto;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.profile-menu-link {
padding: 18px 20px;
color: #94a3b8;
transition: 0.3s;
cursor: pointer;
font-size: 14px;
font-weight: 600;
white-space: nowrap;
position: relative;
}
.profile-menu-link.active, .profile-menu-link:hover {
color: #ffffff;
text-shadow: 1px 1px 0 #0f3460;
}
.profile-menu-link.active:after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 30px;
height: 3px;
background: linear-gradient(90deg, #1e90ff, #00bfff);
border-radius: 3px 3px 0 0;
}
/* 头像区域样式 */
.profile-avatar {
position: absolute;
align-items: center;
display: flex;
z-index: 1;
bottom: 20px;
left: 30px;
}
.profile-img {
width: 150px;
height: 150px;
border-radius: 50%;
object-fit: cover;
border: 4px solid rgba(22, 33, 62, 0.8);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
transition: transform 0.3s ease;
}
.profile-img:hover {
transform: scale(1.05);
}
.profile-name {
margin-left: 24px;
margin-bottom: 24px;
font-size: 24px;
color: #ffffff;
font-weight: 800;
font-family: "PingFang SC", sans-serif;
text-shadow: 2px 2px 0 #0f3460;
}
/* 社交图标样式 */
.social-icons {
display: flex;
margin-left: 24px;
}
.social-icon {
color: #cbd5e1;
margin-right: 15px;
font-size: 20px;
transition: all 0.3s ease;
}
.social-icon:hover {
color: #ffffff;
transform: translateY(-2px);
text-shadow: 1px 1px 0 #0f3460;
}
/* 时间线布局 */
.timeline {
display: flex;
padding-top: 20px;
position: relative;
z-index: 2;
gap: 30px;
}
.timeline-left {
width: 310px;
flex-shrink: 0;
}
.timeline-right {
flex-grow: 1;
}
/* 通用卡片样式 - 漫画风格 */
.box {
background-color: rgba(22, 33, 62, 0.7);
border-radius: 16px;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
margin-bottom: 30px;
transition: transform 0.3s ease, box-shadow 0.3s ease;
border: 2px solid rgba(255, 255, 255, 0.1);
overflow: hidden;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.box:hover {
transform: translateY(-5px);
box-shadow: 0 12px 25px rgba(0, 0, 0, 0.3);
border-color: rgba(255, 255, 255, 0.2);
}
/* 账户按钮样式 */
.account-button {
border: 0;
background: transparent;
color: #94a3b8;
padding: 8px;
cursor: pointer;
position: relative;
border-radius: 50%;
transition: all 0.3s ease;
}
.account-button:hover {
background-color: rgba(255, 255, 255, 0.1);
color: #ffffff;
}
.account-button svg {
width: 20px;
height: 20px;
}
.account-button:not(.right-side-button) + .account-button:before {
position: absolute;
right: 5px;
top: 5px;
background-color: #1e90ff;
width: 8px;
height: 8px;
border-radius: 50%;
content: "";
border: 2px solid #16213e;
}
.account-profile {
width: 32px;
height: 32px;
border-radius: 50%;
margin: 0 10px;
object-fit: cover;
border: 2px solid rgba(255, 255, 255, 0.2);
}
.account-user {
display: inline-flex;
align-items: center;
color: #94a3b8;
font-weight: 600;
font-size: 14px;
transition: all 0.3s ease;
}
.account-user:hover {
color: #ffffff;
text-shadow: 1px 1px 0 #0f3460;
}
.account-user span {
font-size: 12px;
font-weight: normal;
margin-left: 5px;
}
/* 账户区域样式 */
.account {
height: 60px;
display: flex;
justify-content: space-between;
align-items: center;
position: sticky;
top: 0;
background-color: rgba(22, 33, 62, 0.8);
z-index: 3;
flex-shrink: 0;
padding: 0 20px;
border-bottom: 2px solid rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
/* 遮罩层样式 */
.overlay {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background-color: rgba(26, 26, 46, 0.8);
opacity: 0;
visibility: hidden;
pointer-events: none;
transition: 0.3s;
z-index: 9;
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
}
/* 右侧边栏按钮样式 - 修复与搜索框重叠问题 */
.right-side-button {
position: absolute;
right: 0;
top: 0;
height: 100%;
border: 0;
width: 52px;
background-color: rgba(22, 33, 62, 0.8);
border-left: 2px solid rgba(255, 255, 255, 0.1);
color: #ffffff;
display: none;
cursor: pointer;
transition: all 0.3s ease;
z-index: 4; /* 增加z-index确保按钮在上层 */
}
.right-side-button:hover {
background-color: rgba(22, 33, 62, 0.9);
}
.right-side-button:before {
content: "";
width: 10px;
height: 10px;
border-radius: 50%;
position: absolute;
background-color: #1e90ff;
border: 2px solid #16213e;
top: 13px;
right: 12px;
}
.right-side-button svg {
width: 22px;
}
/* 左侧边栏按钮样式 */
.left-side-button {
display: none;
}
/* 响应式设计 - 左侧边栏 */
@media screen and (max-width: 930px) {
.left-side.active {
z-index: 10;
width: 260px;
}
.left-side.active > *:not(.logo) {
opacity: 1;
transition: 0.3s 0.2s;
}
.left-side.active .left-side-button svg:first-child {
opacity: 0;
}
.left-side.active .left-side-button svg:last-child {
transform: translate(-50%, -50%);
opacity: 1;
}
.left-side:not(.active) {
width: 56px;
overflow: hidden;
}
.left-side:not(.active) > *:not(.logo):not(.left-side-button) {
opacity: 0;
}
.left-side:not(.active) .logo {
transform: rotate(90deg);
transform-origin: bottom;
display: flex;
align-items: center;
justify-content: center;
height: 100px;
padding-top: 100px;
}
.left-side-button {
display: flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
position: relative;
cursor: pointer;
height: 60px;
background-color: rgba(22, 33, 62, 0.5);
border: 0;
padding: 0;
line-height: 0;
color: #ffffff;
border-bottom: 2px solid rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
}
.left-side-button:hover {
background-color: rgba(22, 33, 62, 0.7);
}
.left-side-button svg {
transition: 0.2s;
width: 24px;
}
.left-side-button svg:last-child {
position: absolute;
left: 50%;
transform: translate(100%, -50%);
top: 50%;
opacity: 0;
}
}
/* 响应式设计 - 右侧边栏 */
@media screen and (max-width: 1210px) {
.right-side {
position: fixed;
right: 0;
top: 0;
transition: 0.3s;
height: 100%;
transform: translateX(280px);
z-index: 10;
}
.right-side.active {
transform: translatex(0);
}
.overlay.active {
z-index: 8;
opacity: 1;
visibility: visible;
pointer-events: all;
}
.right-side-button {
display: block;
}
}
/* 响应式设计 - 个人资料区域 */
@media screen and (max-width: 700px) {
.profile-avatar {
top: -25px;
left: 50%;
transform: translatex(-50%);
align-items: center;
flex-direction: column;
justify-content: center;
}
.profile-img {
height: 100px;
width: 100px;
}
.profile-name {
margin: 10px 0;
text-align: center;
}
.social-icons {
margin-left: 0;
justify-content: center;
}
.profile-menu {
padding-left: 0;
width: 100%;
overflow: auto;
justify-content: center;
}
.profile-menu-link {
padding: 16px;
font-size: 14px;
}
}
/* 响应式设计 - 时间线布局 */
@media screen and (max-width: 768px) {
.timeline {
flex-wrap: wrap;
flex-direction: column-reverse;
}
.timeline-right {
padding-left: 0;
margin-bottom: 20px;
}
.timeline-left {
width: 100%;
}
/* 修改媒体行布局,使音乐播放器和个人空间在移动端单独显示 */
.media-row {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
margin-bottom: 20px;
}
.main-container {
padding: 20px;
}
}
/* 响应式设计 - 个人资料菜单 */
@media screen and (max-width: 480px) {
.profile-menu-link:nth-last-child(1),
.profile-menu-link:nth-last-child(2) {
display: none;
}
.main-container {
padding: 15px;
}
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 8px;
border-radius: 10px;
}
::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.05);
}
::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.2);
}
/* 字体图标样式 */
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* ========== 优化后的样式 ========== */
/* 卡片标题样式 */
.card-title {
font-size: 18px;
font-weight: 800;
color: #ffffff;
margin-bottom: 15px;
padding: 15px 15px 10px;
border-bottom: 2px solid rgba(255, 255, 255, 0.1);
display: flex;
align-items: center;
text-shadow: 1px 1px 0 #0f3460;
}
.card-title i {
margin-right: 10px;
color: #1e90ff;
}
/* 卡片内容样式 */
.card-content {
padding: 15px;
}
/* 竖向轮播图样式 */
.vertical-carousel {
position: relative;
border-radius: 16px;
overflow: hidden;
height: 400px;
}
.vertical-slides {
height: 100%;
display: flex;
flex-direction: column;
transition: transform 0.5s ease;
}
.vertical-slide {
height: 100%;
width: 100%;
flex-shrink: 0;
}
.vertical-blog-card {
display: block;
height: 100%;
position: relative;
}
.vertical-blog-card img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease;
}
.vertical-blog-card:hover img {
transform: scale(1.05);
}
.vertical-text-content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
color: white;
padding: 20px;
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
}
.vertical-text-slide {
display: none;
}
.vertical-text-slide.active {
display: block;
}
.date {
font-size: 14px;
opacity: 0.8;
margin-bottom: 8px;
color: #e2e8f0;
}
.excerpt {
font-size: 15px;
margin-bottom: 10px;
color: #e2e8f0;
}
.title {
font-size: 22px;
font-weight: 800;
margin-bottom: 15px;
color: #ffffff;
text-shadow: 1px 1px 0 #0f3460;
}
.button {
display: inline-block;
padding: 8px 20px;
background-color: #1e90ff;
color: white;
border-radius: 50px;
font-size: 14px;
font-weight: 600;
transition: all 0.3s ease;
text-shadow: 1px 1px 0 #0f3460;
border: none;
cursor: pointer;
}
.button:hover {
background-color: #00bfff;
transform: translateY(-2px);
}
.vertical-dots {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: 8px;
z-index: 10;
}
.vertical-dot {
width: 12px;
height: 12px;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.5);
cursor: pointer;
transition: all 0.3s ease;
border: none;
outline: none;
}
.vertical-dot.active {
background-color: #1e90ff;
transform: scale(1.2);
}
/* 音乐播放器和个人空间布局优化 - 改为与项目板块相同的布局 */
.media-row {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
margin-bottom: 30px;
}
/* 音乐播放器 */
.music-player-container {
background: rgba(22, 33, 62, 0.7);
border-radius: 16px;
padding: 15px;
transition: all 0.3s ease;
width: 100%;
border: 2px solid rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
height: 100%;
display: flex;
flex-direction: column;
margin-bottom: 0; /* 移除底部边距,由media-row控制 */
}
.music-player {
display: flex;
align-items: center;
gap: 15px;
flex: 1;
}
.cover {
width: 80px;
height: 80px;
border-radius: 16px;
overflow: hidden;
flex-shrink: 0;
}
.cover img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.cover:hover img {
transform: scale(1.1);
}
.music-info {
flex-grow: 1;
text-align: left;
}
.music-title {
font-size: 16px;
font-weight: 800;
margin-bottom: 5px;
color: #ffffff;
text-shadow: 1px 1px 0 #0f3460;
}
.music-artist {
font-size: 14px;
color: #94a3b8;
margin-bottom: 12px;
}
.progress-container {
width: 100%;
height: 4px;
background-color: rgba(255, 255, 255, 0.1);
border-radius: 2px;
margin-bottom: 10px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.progress {
height: 100%;
background: linear-gradient(90deg, #1e90ff, #00bfff);
border-radius: 2px;
width: 0%;
transition: width 0.1s linear;
position: relative;
}
.progress::after {
content: '';
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
width: 8px;
height: 8px;
border-radius: 50%;
background: #ffffff;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
opacity: 0;
transition: opacity 0.2s;
}
.progress-container:hover .progress::after {
opacity: 1;
}
.time-info {
display: flex;
justify-content: space-between;
font-size: 12px;
color: #94a3b8;
}
.controls {
display: flex;
align-items: center;
gap: 8px;
margin-top: 10px;
}
.play-pause-btn {
width: 40px;
height: 40px;
border-radius: 50%;
background: linear-gradient(135deg, #1e90ff, #00bfff);
color: white;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
border: none;
text-shadow: 1px 1px 0 #0f3460;
}
.play-pause-btn:hover {
transform: scale(1.1);
box-shadow: 0 0 15px rgba(30, 144, 255, 0.5);
}
.control-btn {
width: 30px;
height: 30px;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.1);
color: #e2e8f0;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
border: none;
}
.control-btn:hover {
background-color: #00bfff;
color: white;
}
.pause-icon {
display: none;
}
.playing .play-icon {
display: none;
}
.playing .pause-icon {
display: block;
}
/* 个人空间卡片 - 优化为与项目板块相同的布局 */
.space-card {
background: rgba(22, 33, 62, 0.8);
border-radius: 16px;
transition: all 0.3s ease;
display: flex;
align-items: stretch;
position: relative;
overflow: hidden;
width: 100%;
border: 2px solid rgba(255, 255, 255, 0.1);
text-decoration: none;
height: 100%;
margin-bottom: 0; /* 移除底部边距,由media-row控制 */
}
.space-card:hover {
transform: translateY(-5px);
box-shadow: 0 12px 25px rgba(0, 0, 0, 0.3);
}
.space-content {
flex: 1;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: center;
}
.space-title {
font-size: 18px;
font-weight: 800;
margin-bottom: 8px;
color: #ffffff;
text-shadow: 1px 1px 0 #0f3460;
}
.space-desc {
font-size: 14px;
color: #94a3b8;
margin-bottom: 15px;
}
.space-button {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 20px;
background: linear-gradient(90deg, #1e90ff, #00bfff);
color: white;
border-radius: 50px;
font-size: 14px;
font-weight: 600;
transition: all 0.3s ease;
width: fit-content;
text-decoration: none;
text-shadow: 1px 1px 0 #0f3460;
}
.space-button:hover {
background: linear-gradient(90deg, #00bfff, #1e90ff);
transform: translateY(-2px);
}
.space-image {
width: 40%;
position: relative;
overflow: hidden;
}
.space-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: all 0.3s ease;
}
.space-card:hover .space-image img {
transform: scale(1.05);
}
/* API列表 */
.api-list {
margin-top: 30px;
}
.api-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(48%, 1fr));
gap: 20px;
}
.api-card {
position: relative;
border-radius: 16px;
overflow: hidden;
height: 180px;
transition: all 0.3s ease;
border: 2px solid rgba(255, 255, 255, 0.1);
}
.api-card img {
width: 100%;
height: 100%;
object-fit: cover;
transition: all 0.3s ease;
}
.api-card:hover {
transform: translateY(-5px);
box-shadow: 0 12px 25px rgba(0, 0, 0, 0.3);
}
.api-card:hover img {
transform: scale(1.05);
}
.card-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
color: white;
padding: 20px;
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
}
.card-overlay h3 {
font-size: 18px;
font-weight: 800;
margin-bottom: 8px;
text-shadow: 1px 1px 0 #0f3460;
}
.card-overlay p {
font-size: 14px;
opacity: 0.9;
margin-bottom: 8px;
}
/* 待办事项 */
.todo-list {
list-style: none;
}
.todo-item {
display: flex;
align-items: center;
padding: 12px 0;
border-bottom: 2px dashed rgba(255, 255, 255, 0.1);
}
.todo-checkbox {
margin-right: 12px;
accent-color: #1e90ff;
width: 18px;
height: 18px;
cursor: pointer;
}
.todo-text {
flex: 1;
color: #e2e8f0;
transition: all 0.3s ease;
font-weight: 600;
}
.todo-text.completed {
text-decoration: line-through;
opacity: 0.7;
}
.todo-delete {
color: #94a3b8;
cursor: pointer;
transition: all 0.3s ease;
padding: 5px;
}
.todo-delete:hover {
color: #1e90ff;
}
.todo-add {
display: flex;
margin-top: 15px;
}
.todo-input {
flex: 1;
padding: 12px;
border: 2px solid rgba(255, 255, 255, 0.1);
border-radius: 8px 0 0 8px;
background: rgba(255, 255, 255, 0.05);
color: #e2e8f0;
outline: none;
font-weight: 600;
}
.todo-input:focus {
border-color: #1e90ff;
}
.todo-submit {
padding: 12px 20px;
background: linear-gradient(90deg, #1e90ff, #00bfff);
color: white;
border: none;
border-radius: 0 8px 8px 0;
cursor: pointer;
transition: all 0.3s ease;
font-weight: 600;
text-shadow: 1px 1px 0 #0f3460;
}
.todo-submit:hover {
background: linear-gradient(90deg, #00bfff, #1e90ff);
}
/* 天气小部件整体样式 */
.weather-widget {
padding: 15px;
display: flex;
flex-direction: column;
gap: 15px;
}
/* 地区信息样式 - 移到标题下方 */
.weather-location {
font-size: 14px;
color: #94a3b8;
margin-bottom: 10px;
padding-bottom: 8px;
border-bottom: 1px dashed rgba(255, 255, 255, 0.1);
text-align: center;
font-weight: 600;
}
/* 今天天气样式 */
.weather-today {
background: rgba(30, 144, 255, 0.1);
border-radius: 12px;
padding: 15px;
border: 2px solid rgba(30, 144, 255, 0.2);
}
.weather-current {
display: flex;
align-items: center;
gap: 15px;
}
.weather-icon {
font-size: 2.5rem;
color: #1e90ff;
width: 60px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
}
.weather-info {
flex: 1;
}
.weather-temp {
font-size: 1.8rem;
font-weight: 800;
margin-bottom: 5px;
color: #ffffff;
text-shadow: 1px 1px 0 #0f3460;
}
.weather-desc {
font-size: 14px;
opacity: 0.9;
color: #94a3b8;
}
/* 预报天气样式 */
.weather-forecast {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
.weather-day {
background: rgba(255, 255, 255, 0.05);
border-radius: 10px;
padding: 12px;
text-align: center;
border: 2px solid rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
}
.weather-day:hover {
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.weather-day-icon {
font-size: 1.8rem;
margin: 8px 0;
color: #1e90ff;
}
.weather-day-temp {
font-weight: 800;
margin-bottom: 5px;
color: #ffffff;
text-shadow: 1px 1px 0 #0f3460;
}
/* 亮色模式样式 */
.light-mode .weather-location {
color: #4a5568;
border-color: rgba(0, 0, 0, 0.1);
}
.light-mode .weather-temp,
.light-mode .weather-day-temp {
color: #2d3748;
text-shadow: none;
}
.light-mode .weather-desc,
.light-mode .weather-day-desc {
color: #4a5568;
}
.light-mode .weather-day {
background: rgba(0, 0, 0, 0.03);
border-color: rgba(0, 0, 0, 0.1);
}
.light-mode .weather-today {
background: rgba(30, 144, 255, 0.08);
border-color: rgba(30, 144, 255, 0.15);
}
/* 公告栏 - 修复文字颜色跟随主题变化 */
.announcement {
padding: 15px;
}
.announcement-content {
font-size: 14px;
color: inherit; /* 使用继承的颜色,跟随主题变化 */
line-height: 1.7;
font-weight: 600;
}
.announcement-content a {
color: #1e90ff;
text-decoration: none;
transition: all 0.3s ease;
font-weight: 600;
}
.announcement-content a:hover {
text-decoration: underline;
color: #00bfff;
}
/* 赞赏码 */
.donate-box {
text-align: center;
padding: 15px;
}
.donate-title {
font-size: 16px;
color: #ffffff;
margin-bottom: 15px;
font-weight: 800;
text-shadow: 1px 1px 0 #0f3460;
}
.donate-image {
width: 180px;
height: 180px;
margin: 0 auto;
border-radius: 8px;
overflow: hidden;
border: 2px solid rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
cursor: pointer; /* 添加指针样式表明可点击 */
}
.donate-image:hover {
transform: scale(1.05);
border-color: rgba(255, 255, 255, 0.3);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
}
.donate-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
.donate-desc {
font-size: 14px;
color: #94a3b8;
margin-top: 10px;
font-weight: 600;
}
/* 赞赏码放大模态框 */
.donate-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
}
.donate-modal.active {
opacity: 1;
visibility: visible;
}
.donate-modal-content {
max-width: 90%;
max-height: 90%;
position: relative;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
transform: scale(0.9);
transition: all 0.3s ease;
}
.donate-modal.active .donate-modal-content {
transform: scale(1);
}
.donate-modal-content img {
display: block;
max-width: 100%;
max-height: 80vh;
object-fit: contain;
}
.donate-modal-close {
position: absolute;
top: 15px;
right: 15px;
width: 40px;
height: 40px;
border-radius: 50%;
background: rgba(0, 0, 0, 0.5);
color: white;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
border: 2px solid rgba(255, 255, 255, 0.2);
font-size: 20px;
}
.donate-modal-close:hover {
background: rgba(255, 0, 0, 0.7);
transform: rotate(90deg);
}
/* 访客统计 */
.stats-chart {
height: 200px;
margin-top: 15px;
position: relative;
width: 100%;
}
/* 最新评论 */
.comment-item {
padding: 12px 15px;
border-bottom: 2px dashed rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
}
.comment-item:hover {
background: rgba(255, 255, 255, 0.05);
transform: translateX(5px);
}
.comment-item:last-child {
border-bottom: none;
}
.comment-author {
font-weight: 800;
color: #ffffff;
text-shadow: 1px 1px 0 #0f3460;
}
.comment-text {
font-size: 14px;
color: #e2e8f0;
margin: 8px 0;
font-weight: 600;
}
.comment-date {
font-size: 12px;
color: #94a3b8;
font-weight: 600;
}
/* 日历小部件 */
.calendar-widget {
padding: 15px;
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.calendar-title {
font-weight: 800;
font-size: 16px;
color: #ffffff;
text-shadow: 1px 1px 0 #0f3460;
}
.calendar-nav {
display: flex;
gap: 8px;
}
.calendar-nav-btn {
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
background: rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
border: none;
color: #e2e8f0;
}
.calendar-nav-btn:hover {
background: #1e90ff;
color: white;
transform: scale(1.1);
}
.calendar-weekdays {
display: grid;
grid-template-columns: repeat(7, 1fr);
text-align: center;
margin-bottom: 10px;
font-size: 12px;
color: #94a3b8;
font-weight: 600;
}
.calendar-days {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 5px;
}
.calendar-day {
aspect-ratio: 1;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
color: #e2e8f0;
font-weight: 600;
}
.calendar-day:hover {
background: rgba(30, 144, 255, 0.2);
color: #ffffff;
transform: scale(1.1);
}
.calendar-day.today {
background: #1e90ff;
color: white;
font-weight: 800;
box-shadow: 0 0 10px rgba(30, 144, 255, 0.5);
}
.calendar-day.other-month {
opacity: 0.4;
}
/* 标签云 */
.tag-cloud {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 15px;
}
.tag {
display: inline-block;
padding: 6px 12px;
background: rgba(255, 255, 255, 0.1);
border-radius: 50px;
font-size: 12px;
transition: all 0.3s ease;
color: #e2e8f0;
text-decoration: none;
font-weight: 600;
border: 2px solid rgba(255, 255, 255, 0.1);
}
.tag:hover {
background: #1e90ff;
color: white;
transform: translateY(-2px) scale(1.05);
box-shadow: 0 5px 15px rgba(30, 144, 255, 0.3);
}
/* 加载动画 */
@keyframes fadeIn {
to { opacity: 1; }
}
/* 浮动按钮 */
.float-button {
position: fixed;
right: 20px;
bottom: 20px;
display: flex;
flex-direction: column;
gap: 12px;
z-index: 999;
}
.upward {
width: 48px;
height: 48px;
border-radius: 50%;
background: linear-gradient(135deg, #1e90ff, #00bfff);
color: white;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
border: none;
box-shadow: 0 4px 15px rgba(30, 144, 255, 0.3);
text-shadow: 1px 1px 0 #0f3460;
}
.upward:hover {
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(30, 144, 255, 0.4);
}
.upward i {
transition: all 0.3s ease;
}
.upward:hover i {
transform: translateY(-3px);
}
/* FPS监控 */
.comic-fps {
position: fixed;
left: 10px;
bottom: 10px;
display: flex;
align-items: center;
z-index: 999;
user-select: none;
font-family: "PingFang SC", sans-serif;
}
.fps-bubble {
position: relative;
background: rgba(22, 33, 62, 0.7);
border: 2px solid rgba(255, 255, 255, 0.1);
border-radius: 20px;
padding: 8px 15px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
display: flex;
align-items: center;
gap: 8px;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
transition: all 0.3s ease;
}
.fps-bubble:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
border-color: rgba(30, 144, 255, 0.3);
}
.fps-character {
font-size: 18px;
transform: translateY(2px);
opacity: 0.9;
transition: all 0.3s ease;
}
.fps-value {
font-weight: 800;
font-size: 16px;
margin-right: 5px;
color: #1e90ff;
transition: all 0.3s ease;
}
.fps-status {
font-size: 14px;
color: #e2e8f0;
font-weight: 600;
}
/* FPS状态颜色 */
.comic-fps.excellent {
--comic-accent: #10ac84;
}
.comic-fps.good {
--comic-accent: #feca57;
}
.comic-fps.normal {
--comic-accent: #ff9f43;
}
.comic-fps.low {
--comic-accent: #ee5253;
}
.comic-fps.critical {
--comic-accent: #ff4757;
animation: shake 0.5s infinite;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-3px); }
75% { transform: translateX(3px); }
}
/* 右侧边栏卡片间距优化 */
.right-side .box {
margin: 15px;
max-height: none;
overflow: visible;
}
/* 主内容区域优化 */
.main-container {
padding: 30px;
}
/* 时间线布局优化 */
.timeline {
gap: 30px;
}
/* 主题切换按钮 - 优化动画效果 */
.theme-toggle {
width: 40px;
height: 40px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
z-index: 10; /* 确保按钮可点击 */
}
.theme-toggle:hover {
background: rgba(255, 255, 255, 0.2);
transform: scale(1.1);
}
.theme-toggle i {
font-size: 18px;
color: #e2e8f0;
transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
position: absolute;
}
/* 主题切换动画 */
.theme-toggle .fa-moon {
opacity: 1;
transform: rotate(0deg);
}
.theme-toggle .fa-sun {
opacity: 0;
transform: rotate(180deg) scale(0);
}
.light-mode .theme-toggle .fa-moon {
opacity: 0;
transform: rotate(-180deg) scale(0);
}
.light-mode .theme-toggle .fa-sun {
opacity: 1;
transform: rotate(0deg);
}
.theme-toggle.has-update:after {
content: '';
position: absolute;
top: 5px;
right: 5px;
width: 8px;
height: 8px;
border-radius: 50%;
background: #1e90ff;
border: 2px solid #16213e;
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.2); opacity: 0.7; }
100% { transform: scale(1); opacity: 1; }
}
/* 亮色主题样式 - 漫画风格 */
body.light-mode {
background-color: #f0f4f8;
color: #2d3748;
}
.light-mode .container {
background-color: #ffffff;
}
.light-mode .left-side,
.light-mode .right-side {
background-color: rgba(255, 255, 255, 0.8);
border-color: rgba(0, 0, 0, 0.1);
}
.light-mode .main {
background-color: #f8fafc;
}
.light-mode .logo {
background-color: rgba(255, 255, 255, 0.8);
color: #2d3748;
text-shadow: 2px 2px 0 #e2e8f0;
}
.light-mode .side-title {
color: #4a5568;
border-color: rgba(0, 0, 0, 0.1);
}
.light-mode .side-menu a {
color: #4a5568;
}
.light-mode .side-menu a:hover {
color: #2d3748;
background-color: rgba(0, 0, 0, 0.05);
text-shadow: none;
}
.light-mode .side-menu a.active {
color: #2d3748;
background-color: rgba(30, 144, 255, 0.1);
text-shadow: none;
}
.light-mode .side-menu a.active::before {
background: linear-gradient(to bottom, #1e90ff, #00bfff);
}
.light-mode .follow-me {
color: #4a5568;
border-color: rgba(0, 0, 0, 0.1);
}
.light-mode .developer {
background-color: rgba(255, 255, 255, 0.9);
color: #2d3748;
text-shadow: none;
}
.light-mode .search-bar {
background-color: rgba(255, 255, 255, 0.8);
border-color: rgba(0, 0, 0, 0.1);
}
.light-mode .search-bar input {
background-color: rgba(0, 0, 0, 0.05);
border-color: rgba(0, 0, 0, 0.1);
color: #2d3748;
}
.light-mode .search-bar input::placeholder {
color: #718096;
}
.light-mode .main-container {
background-color: #f8fafc;
}
.light-mode .box {
background-color: rgba(255, 255, 255, 0.7);
border-color: rgba(0, 0, 0, 0.1);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
}
.light-mode .card-title {
color: #2d3748;
border-color: rgba(0, 0, 0, 0.1);
text-shadow: none;
}
.light-mode .todo-text {
color: #2d3748;
}
.light-mode .todo-item {
border-color: rgba(0, 0, 0, 0.1);
}
.light-mode .todo-input {
background: rgba(0, 0, 0, 0.05);
border-color: rgba(0, 0, 0, 0.1);
color: #2d3748;
}
.light-mode .weather-temp,
.light-mode .music-title,
.light-mode .space-title,
.light-mode .title,
.light-mode .calendar-title,
.light-mode .comment-author {
color: #2d3748;
text-shadow: none;
}
.light-mode .weather-desc,
.light-mode .music-artist,
.light-mode .space-desc,
.light-mode .excerpt,
.light-mode .comment-text,
.light-mode .calendar-day {
color: #4a5568;
}
.light-mode .weather-day,
.light-mode .tag {
background: rgba(0, 0, 0, 0.05);
color: #4a5568;
border-color: rgba(0, 0, 0, 0.1);
}
.light-mode .fps-bubble {
background: rgba(255, 255, 255, 0.7);
border-color: rgba(0, 0, 0, 0.1);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}
.light-mode .fps-status {
color: #4a5568;
}
.light-mode .account {
background-color: rgba(255, 255, 255, 0.8);
border-color: rgba(0, 0, 0, 0.1);
}
.light-mode .account-user {
color: #4a5568;
}
.light-mode .account-user:hover {
color: #2d3748;
}
.light-mode .overlay {
background-color: rgba(248, 250, 252, 0.8);
}
.light-mode .right-side-button {
background-color: rgba(255, 255, 255, 0.8);
border-color: rgba(0, 0, 0, 0.1);
color: #2d3748;
}
.light-mode .left-side-button {
background-color: rgba(255, 255, 255, 0.5);
border-color: rgba(0, 0, 0, 0.1);
color: #2d3748;
}
/* 修复个人介绍TENGYUAN文字颜色问题 */
.light-mode .profile-name {
color: #ffffff; /* 保持白色,因为它在深色背景上 */
text-shadow: 2px 2px 0 #0f3460;
}
/* 修复公告栏文字颜色跟随主题变化 */
.light-mode .announcement-content {
color: #2d3748;
}
.light-mode .announcement-content a {
color: #1e90ff;
}
/* 移除右侧边栏文字底部的紫色细线 */
.light-mode .announcement a,
.dark-mode .announcement a {
border-bottom: none;
text-decoration: none;
}
/* 响应式优化 */
@media screen and (max-width: 1024px) {
.api-cards {
grid-template-columns: 1fr;
}
}
@media screen and (max-width: 768px) {
/* 移动端布局优化 - 音乐播放器和个人空间一行一个 */
.media-row {
grid-template-columns: 1fr;
}
}
@media screen and (max-width: 480px) {
.vertical-carousel {
height: 300px;
}
}
/* 主题切换通知样式 */
.theme-notification {
position: fixed;
bottom: 20px;
right: 20px;
padding: 12px 20px;
border-radius: 8px;
z-index: 1000;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
transform: translateY(100px);
opacity: 0;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
.dark-mode .theme-notification {
background-color: #16213e;
color: #ffffff;
border: 2px solid rgba(255, 255, 255, 0.1);
}
.light-mode .theme-notification {
background-color: #ffffff;
color: #2d3748;
border: 2px solid rgba(0, 0, 0, 0.1);
}
</style>
</head>
<body class="dark-mode">
<!-- 主容器 - 使用Alpine.js管理状态 -->
<div class="container" x-data="{ rightSide: false, leftSide: false }">
<!-- 左侧边栏 - 导航菜单 -->
<div class="left-side" :class="{'active' : leftSide}">
<!-- 左侧边栏切换按钮 - 移动端显示 -->
<div class="left-side-button" @click="leftSide = !leftSide">
<svg viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
<svg stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
<path d="M19 12H5M12 19l-7-7 7-7"></path>
</svg>
</div>
<!-- Logo区域 -->
<div class="logo">TENGYUAN</div>
<!-- 主菜单区域 -->
<div class="side-wrapper">
<div class="side-title">菜单</div>
<div class="side-menu">
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
<path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"></path>
<path d="M9 22V12h6v10"></path>
</svg>
首页
</a>
<a href="#">
<svg stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
<path d="M2 3h6a4 4 0 0 1 4 4v10M16 7v10M3 11h18M11 3v18"></path>
</svg>
文章
</a>
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0118 0z"></path>
<circle cx="12" cy="10" r="3"></circle>
</svg>
探索
</a>
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"></path>
<path d="M14 2v6h6M16 13H8M16 17H8M10 9H8"></path>
</svg>
资源
</a>
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
<circle cx="8.5" cy="8.5" r="1.5"></circle>
<path d="M21 15l-5-5L5 21"></path>
</svg>
作品集
</a>
</div>
</div>
<!-- 分类菜单区域 -->
<div class="side-wrapper">
<div class="side-title">分类</div>
<div class="side-menu">
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"></path>
</svg>
技术
</a>
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
<path d="M16 2v4M8 2v4M3 10h18"></path>
</svg>
设计
</a>
<a href="#">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M22 12h-4l-3 9L9 3l-3 9H2"></path>
</svg>
商业
</a>
</div>
</div>
<!-- 关注我区域 -->
<a href="#" class="follow-me" target="_blank">
<span class="follow-text">
<svg viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path>
</svg>
关注我
</span>
<span class="developer">
<img src="https://pbs.twimg.com/profile_images/1253782473953157124/x56UURmt_400x400.jpg">
开发者信息
</span>
</a>
</div>
<!-- 主内容区域 -->
<div class="main">
<!-- 搜索栏 - 已调整位置 -->
<div class="search-bar">
<input type="text" placeholder="搜索文章、标签或作者...">
<button class="right-side-button" @click="rightSide = !rightSide">
<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
</svg>
</button>
</div>
<!-- 主内容容器 -->
<div class="main-container">
<!-- 个人资料区域 -->
<div class="profile">
<div class="profile-avatar">
<img src="https://a.520gexing.com/uploads/allimg/2019032616/3mltnpfys55.jpg" alt="" class="profile-img">
<div class="profile-name">TENG YUAN</div>
<div class="social-icons">
<!-- 已有图标 -->
<a href="#" class="social-icon bilibili" title="哔哩哔哩">
<i class="iconfont icon-bilibili"></i>
</a>
<a href="#" class="social-icon douyin" title="抖音">
<i class="iconfont icon-douyin"></i>
</a>
<a href="#" class="social-icon xiaohongshu" title="小红书">
<i class="iconfont icon-xiaohongshu"></i>
</a>
<a href="mailto:your@email.com" class="social-icon email" title="邮箱">
<i class="fas fa-envelope"></i>
</a>
</div>
</div>
<img src="https://api.yilx.net/img/pc" alt="" class="profile-cover">
<div class="profile-menu">
<a class="profile-menu-link active">博客</a>
<a class="profile-menu-link">关于</a>
<a class="profile-menu-link">项目</a>
<a class="profile-menu-link">联系</a>
<a class="profile-menu-link">相册</a>
<a class="profile-menu-link">收藏</a>
</div>
</div>
<!-- 时间线布局 -->
<div class="timeline">
<!-- 左侧时间线 - 个人信息和活动 -->
<div class="timeline-left">
<!-- 竖向轮播图卡片 -->
<div class="box">
<div class="vertical-carousel">
<div class="vertical-slides" style="transform: translateY(-200%);">
<div class="vertical-slide">
<a href="https://blog.tengyuan.icu" class="vertical-blog-card" target="_blank">
<img class="lazy" data-original="https://yilx.net/static/img/lxbg.jpeg" alt="MC开服教程" src="https://bicool-user-assets--small-file.oss-rg-china-mainland.aliyuncs.com/b635285ba0d56ff95d83fde0bbd0f1c2.webp">
<div class="vertical-text-content">
<div class="vertical-text-slide">
<p class="date">2025-04-21</p>
<h2 class="title">标题1</h2>
<p class="excerpt">描述</p>
</div>
</div>
</a>
</div>
<div class="vertical-slide">
<a href="https://blog.tengyuan.icu" class="vertical-blog-card" target="_blank">
<img class="lazy" data-original="https://yilx.net/static/img/lxbg.jpeg" alt="使用/give获取特殊nbt物品" src="https://yilx.net/static/img/lxbg.jpeg">
<div class="vertical-text-content">
<div class="vertical-text-slide">
<p class="date">2025-4-18</p>
<h2 class="title">标题2</h2>
<p class="excerpt">描述</p>
</div>
</div>
</a>
</div>
<div class="vertical-slide">
<a href="https://blog.tengyuan.icu" class="vertical-blog-card" target="_blank">
<img class="lazy" data-original="https://yilx.net/static/img/lxbg.jpeg" alt="标题3" src="http://localhost/static/img/tx.jpg">
<div class="vertical-text-content">
<div class="vertical-text-slide active">
<p class="date">2025-5-1</p>
<h2 class="title">标题3</h2>
<p class="excerpt">描述</p>
</div>
</div>
</a>
</div>
</div>
<div class="vertical-dots">
<button class="vertical-dot"></button>
<button class="vertical-dot"></button>
<button class="vertical-dot active"></button>
</div>
</div>
</div>
<!-- 待办事项 -->
<div class="box">
<div class="card-title">
<i class="fas fa-tasks"></i> 待办事项
</div>
<div class="card-content">
<ul class="todo-list" id="todoList">
<li class="todo-item">
<input type="checkbox" class="todo-checkbox" checked>
<span class="todo-text completed">完成首页设计</span>
<i class="fas fa-trash todo-delete"></i>
</li>
<li class="todo-item">
<input type="checkbox" class="todo-checkbox">
<span class="todo-text">添加音乐播放器</span>
<i class="fas fa-trash todo-delete"></i>
</li>
<li class="todo-item">
<input type="checkbox" class="todo-checkbox">
<span class="todo-text">优化移动端体验</span>
<i class="fas fa-trash todo-delete"></i>
</li>
</ul>
<div class="todo-add">
<input type="text" class="todo-input" placeholder="添加新任务...">
<button class="todo-submit">添加</button>
</div>
</div>
</div>
</div>
<!-- 右侧时间线 - 博客文章 -->
<div class="timeline-right">
<!-- 音乐播放器和个人空间 - 优化为两列布局 -->
<div class="media-row">
<!-- 音乐播放器 -->
<div class="box music-player-container">
<audio id="myAudio" src="https://api.yilx.net/music/Hyper-energetic-ACG"></audio>
<div class="music-player">
<div class="cover">
<img class="lazy" data-original="https://api.yilx.net/img/pm" alt="专辑封面" src="https://api.yilx.net/img/pm">
</div>
<div class="music-info">
<h3 class="music-title">随机音乐</h3>
<p class="music-artist">藤原的音乐推荐</p>
<div class="progress-container">
<div class="progress" id="progress"></div>
</div>
<div class="time-info">
<span id="current-time">0:00</span>
<span id="duration">0:00</span>
</div>
<div class="controls">
<button class="control-btn" id="prev-btn">
<i class="fas fa-step-backward"></i>
</button>
<button class="play-pause-btn" id="play-btn">
<span class="play-icon">
<i class="fas fa-play"></i>
</span>
<span class="pause-icon">
<i class="fas fa-pause"></i>
</span>
</button>
<button class="control-btn" id="next-btn">
<i class="fas fa-step-forward"></i>
</button>
</div>
</div>
</div>
</div>
<!-- 个人空间卡片 -->
<a href="https://b23.tv/pDBTVlx" class="box space-card" target="_blank">
<div class="space-content">
<h3 class="space-title">个人空间</h3>
<p class="space-desc">藤原的个人空间</p>
<span class="space-button">
前往空间
<i class="fas fa-arrow-right"></i>
</span>
</div>
<div class="space-image">
<img src="https://a.520gexing.com/uploads/allimg/2019032616/3mltnpfys55.jpg" alt="藤原的个人空间">
</div>
</a>
</div>
<!-- API列表 -->
<div class="api-list">
<h2 class="card-title"><i class="fas fa-link"></i> 我的项目</h2>
<div class="api-cards">
<a class="api-card box" target="_blank" href="http://blog.tengyuan.icu">
<img class="lazy" data-original="https://api.yilx.net/img/pc" alt="" src="http://api.yilx.net/upload/1742118988976.jpg">
<div class="card-overlay">
<h3>博客</h3>
<p>记录摆烂日常</p>
<p>site</p>
</div>
</a>
<a class="api-card box" target="_blank" href="https://api.yilx.net">
<img class="lazy" data-original="https://api.yilx.net/img/pc" alt="" src="https://api.yilx.net/img/pc">
<div class="card-overlay">
<h3>API站</h3>
<p>api站点/图床/统计</p>
<p>site</p>
</div>
</a>
<a class="api-card box" target="_blank" href="http://wp.tengyuan.icu">
<img class="lazy" data-original="https://camo.githubusercontent.com/01f699b5dd28e3fd101d0381f0c7471ed5a08210713d7663f0ad493d966be453/68747470733a2f2f666173746c792e6a7364656c6976722e6e65742f67682f7661737473612f46696c65436f64654278405631362f7374617469632f62616e6e6572732f696d675f312e706e67" alt="" src="http://api.yilx.net/upload/1742130278110.jpg">
<div class="card-overlay">
<h3>网盘</h3>
<p>开箱即用的文件快传系统</p>
<p>site</p>
</div>
</a>
<a class="api-card box" target="_blank" href="http://game.tengyuan.icu">
<img class="lazy" data-original="http://static.1heron.com/douyou8/ad/174409477289445.jpg" alt="" src="http://api.yilx.net/upload/1743067883203.jpg">
<div class="card-overlay">
<h3>TENGYUANの游戏小站</h3>
<p>游戏盛宴,一键解锁</p>
<p>project</p>
</div>
</a>
<a class="api-card box" target="_blank" href="http://tengyuan.icu">
<img class="lazy" data-original="https://api.yilx.net/img/pc" alt="" src="https://api.yilx.net/upload/1741001197606.jpg">
<div class="card-overlay">
<h3>TENGYUAN</h3>
<p>TENGYUAN</p>
<p>project</p>
</div>
</a>
<a class="api-card box" target="_blank" href="https://tengyuan.icu">
<img class="lazy" data-original="https://api.yilx.net/img/pc" alt="" src="http://api.yilx.net/upload/1741769788550.jpg">
<div class="card-overlay">
<h3>TENGYUAN1</h3>
<p>TENGYUAN1</p>
<p>project</p>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 右侧边栏 -->
<div class="right-side" :class="{ 'active': rightSide }">
<!-- 账户控制区域 - 新增主题切换按钮 -->
<div class="account">
<div class="theme-toggle" id="themeToggleBtn">
<i class="fas fa-moon"></i>
<i class="fas fa-sun"></i>
</div>
<span class="account-user">TENG YUAN
<img src="https://a.520gexing.com/uploads/allimg/2019032616/3mltnpfys55.jpg" alt="" class="account-profile">
<span>▼</span>
</span>
</div>
<!-- 天气小部件 -->
<div class="box">
<div class="card-title">
<i class="fas fa-cloud-sun"></i> 天气
</div>
<div class="weather-widget">
<!-- 地区信息移到这里,放在天气内容的顶部 -->
<div id="weather-location" class="weather-location">加载中...</div>
<div class="weather-today">
<div class="weather-current">
<div class="weather-icon">
<i class="fas fa-spinner fa-spin"></i>
</div>
<div class="weather-info">
<div class="weather-temp">--°C</div>
<div class="weather-desc">获取天气中...</div>
</div>
</div>
</div>
<div class="weather-forecast">
<div class="weather-day">
<div>明天</div>
<div class="weather-day-icon">
<i class="fas fa-spinner fa-spin"></i>
</div>
<div class="weather-day-temp">--°C</div>
</div>
<div class="weather-day">
<div>后天</div>
<div class="weather-day-icon">
<i class="fas fa-spinner fa-spin"></i>
</div>
<div class="weather-day-temp">--°C</div>
</div>
</div>
</div>
</div>
<!-- 公告栏 - 修复文字颜色跟随主题变化 -->
<div class="box">
<div class="card-title">
<i class="fas fa-bullhorn"></i> 公告栏
</div>
<div class="announcement">
<div class="announcement-content">
<center>
<b>--- 主域名 ---
<br>
<a target="_blank" rel="noopener" href="https://tengyuan.icu" title="此线路部署于腾讯云服务器">
tengyuan.icu
</a> <a target="_blank" rel="noopener" href="https://tengyuan.tech" title="此线路部署于雨云服务器">
tengyuan.tech
</a>
<br>--- 备用域名 ---
<br>
<a target="_blank" rel="noopener" href="暂无" title="暂无">
暂无
</a>
<br>
<a target="_blank" rel="noopener" href="暂无" title="暂无">
暂无
</a>
<br>--- 网站安卓APP ---
<br>🍧<a target="_blank" rel="noopener" href="暂无下载链接" title="点这里可以下载网站的安卓APP">
点此下载
</a>🍧
</b>
</center>
</div>
</div>
</div>
<!-- 赞赏码板块 -->
<div class="box">
<div class="card-title">
<i class="fas fa-heart"></i> 支持我们
</div>
<div class="donate-box">
<div class="donate-title">感谢您的支持</div>
<div class="donate-image" id="donateImage">
<img src="https://bicool-user-assets--small-file.oss-rg-china-mainland.aliyuncs.com/b3ae0df4a91e6b70286a23e34cf7f61b.jpg" alt="赞赏码">
</div>
<div class="donate-desc">点击二维码放大查看</div>
</div>
</div>
<!-- 访客统计 -->
<div class="box">
<div class="card-title">
<i class="fas fa-chart-line"></i> 访客统计
</div>
<div class="announcement">
<div class="announcement-content">
<div>本站总访客量:<strong>3253</strong>次</div>
<div>今日访客量:<strong>221</strong>次</div>
<div>项目/网站总数:<strong>6</strong></div>
<div>已经有<strong>22</strong>位小伙伴入驻本站啦!</div>
</div>
</div>
<div class="stats-chart">
<!-- 这里可以放置图表,实际项目中可以使用Chart.js等库 -->
<canvas id="visitorChart" width="100%" height="200"></canvas>
</div>
</div>
<!-- 最新评论 -->
<div class="box">
<div class="card-title">
<i class="fas fa-comments"></i> 最新评论
</div>
<div class="announcement">
<div class="comment-item">
<div class="comment-author">张三</div>
<div class="comment-text">网站设计很棒!</div>
<div class="comment-date">2025-05-07</div>
</div>
<div class="comment-item">
<div class="comment-author">李四</div>
<div class="comment-text">音乐播放器很好用</div>
<div class="comment-date">2025-05-06</div>
</div>
<div class="comment-item">
<div class="comment-author">王五</div>
<div class="comment-text">期待更多内容</div>
<div class="comment-date">2025-05-05</div>
</div>
</div>
</div>
<!-- 日历小部件 -->
<div class="box">
<div class="card-title">
<i class="far fa-calendar-alt"></i> 日历
</div>
<div class="calendar-widget">
<div class="calendar-header">
<div class="calendar-title" id="calendarMonth">2025年 五月</div>
<div class="calendar-nav">
<div class="calendar-nav-btn" id="calendarPrev">
<i class="fas fa-chevron-left"></i>
</div>
<div class="calendar-nav-btn" id="calendarNext">
<i class="fas fa-chevron-right"></i>
</div>
</div>
</div>
<div class="calendar-weekdays">
<div>日</div>
<div>一</div>
<div>二</div>
<div>三</div>
<div>四</div>
<div>五</div>
<div>六</div>
</div>
<div class="calendar-days" id="calendarDays"></div>
</div>
</div>
<!-- 标签云 -->
<div class="box">
<div class="card-title">
<i class="fas fa-tags"></i> 热门标签
</div>
<div class="announcement">
<div class="tag-cloud">
<a href="#" class="tag">前端</a>
<a href="#" class="tag">JavaScript</a>
<a href="#" class="tag">CSS</a>
<a href="#" class="tag">HTML</a>
<a href="#" class="tag">设计</a>
<a href="#" class="tag">动漫</a>
<a href="#" class="tag">游戏</a>
<a href="#" class="tag">音乐</a>
<a href="#" class="tag">摄影</a>
<a href="#" class="tag">旅行</a>
</div>
</div>
</div>
</div>
<!-- 遮罩层 - 用于移动端侧边栏弹出时覆盖主内容 -->
<div class="overlay" @click="rightSide = false; leftSide = false" :class="{ 'active': rightSide || leftSide }"></div>
<!-- 浮动按钮 -->
<div class="float-button">
<div class="upward" style="display: none;">
<i class="fas fa-arrow-up"></i>
</div>
</div>
<!-- FPS显示 -->
<div id="fpsDisplay" class="comic-fps excellent">
<div class="fps-bubble">
<span class="fps-value">60</span>
<span class="fps-status">超流畅!</span>
<span class="fps-character" style="transform: translateY(2px);">(๑•̀ㅂ•́)و✧</span>
</div>
</div>
<!-- 赞赏码放大模态框 -->
<div class="donate-modal" id="donateModal">
<div class="donate-modal-content">
<img src="https://bicool-user-assets--small-file.oss-rg-china-mainland.aliyuncs.com/b3ae0df4a91e6b70286a23e34cf7f61b.jpg" alt="赞赏码" id="donateModalImg">
<div class="donate-modal-close" id="donateModalClose">
<i class="fas fa-times"></i>
</div>
</div>
</div>
</div>
<script>
// 音乐播放器控制
const audio = document.getElementById('myAudio');
const playPauseBtn = document.getElementById('play-btn');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
const progress = document.getElementById('progress');
const currentTimeEl = document.getElementById('current-time');
const durationEl = document.getElementById('duration');
// 更新进度条
audio.addEventListener('timeupdate', () => {
const { currentTime, duration } = audio;
const progressPercent = (currentTime / duration) * 100;
progress.style.width = `${progressPercent}%`;
// 格式化时间显示
const formatTime = (time) => {
const minutes = Math.floor(time / 60);
const seconds = Math.floor(time % 60);
return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
};
currentTimeEl.textContent = formatTime(currentTime);
if (duration) {
durationEl.textContent = formatTime(duration);
}
});
// 点击进度条跳转
const progressContainer = document.querySelector('.progress-container');
progressContainer.addEventListener('click', (e) => {
const width = progressContainer.clientWidth;
const clickX = e.offsetX;
const duration = audio.duration;
audio.currentTime = (clickX / width) * duration;
});
playPauseBtn.addEventListener('click', () => {
if (audio.paused) {
audio.play();
playPauseBtn.classList.add('playing');
} else {
audio.pause();
playPauseBtn.classList.remove('playing');
}
});
// 上一首/下一首按钮
prevBtn.addEventListener('click', () => {
// 这里可以添加切换歌曲的逻辑
alert('切换到上一首歌曲');
});
nextBtn.addEventListener('click', () => {
// 这里可以添加切换歌曲的逻辑
alert('切换到下一首歌曲');
});
// 歌曲结束时自动播放下一首
audio.addEventListener('ended', () => {
// 这里可以添加自动播放下一首的逻辑
alert('歌曲播放结束,可以在这里添加自动播放下一首的逻辑');
});
// 返回顶部按钮
const upwardBtn = document.querySelector('.upward');
upwardBtn.addEventListener('click', () => {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
window.addEventListener('scroll', () => {
if (window.scrollY > 300) {
upwardBtn.style.display = 'flex';
} else {
upwardBtn.style.display = 'none';
}
});
// 竖向轮播图控制
let currentVerticalSlide = 0;
const verticalSlides = document.querySelectorAll('.vertical-slide');
const verticalTextSlides = document.querySelectorAll('.vertical-text-slide');
const verticalDots = document.querySelectorAll('.vertical-dot');
const verticalSlidesContainer = document.querySelector('.vertical-slides');
function showVerticalSlide(n) {
currentVerticalSlide = (n + verticalSlides.length) % verticalSlides.length;
// 更新轮播图位置
verticalSlidesContainer.style.transform = `translateY(-${currentVerticalSlide * 100}%)`;
// 更新文本和指示点状态
verticalTextSlides.forEach((slide, index) => {
if(index === currentVerticalSlide) {
slide.classList.add('active');
} else {
slide.classList.remove('active');
}
});
verticalDots.forEach((dot, index) => {
if(index === currentVerticalSlide) {
dot.classList.add('active');
} else {
dot.classList.remove('active');
}
});
}
verticalDots.forEach((dot, index) => {
dot.addEventListener('click', () => {
showVerticalSlide(index);
});
});
// 自动轮播
let slideInterval = setInterval(() => {
showVerticalSlide(currentVerticalSlide + 1);
}, 5000);
// 鼠标悬停时暂停轮播
const verticalCarousel = document.querySelector('.vertical-carousel');
verticalCarousel.addEventListener('mouseenter', () => {
clearInterval(slideInterval);
});
verticalCarousel.addEventListener('mouseleave', () => {
slideInterval = setInterval(() => {
showVerticalSlide(currentVerticalSlide + 1);
}, 5000);
});
showVerticalSlide(0);
// 主题切换功能
const themeToggleBtn = document.getElementById('themeToggleBtn');
const body = document.body;
// 检查本地存储中的主题设置
const currentTheme = localStorage.getItem('theme') || 'dark';
if (currentTheme === 'light') {
body.classList.remove('dark-mode');
body.classList.add('light-mode');
} else {
body.classList.remove('light-mode');
body.classList.add('dark-mode');
}
// 切换主题
themeToggleBtn.addEventListener('click', () => {
if (body.classList.contains('dark-mode')) {
body.classList.remove('dark-mode');
body.classList.add('light-mode');
localStorage.setItem('theme', 'light');
// 显示主题切换通知
showThemeNotification('已切换至亮色模式');
} else {
body.classList.remove('light-mode');
body.classList.add('dark-mode');
localStorage.setItem('theme', 'dark');
// 显示主题切换通知
showThemeNotification('已切换至暗色模式');
}
});
// 显示主题切换通知
function showThemeNotification(message) {
// 添加更新提示点
themeToggleBtn.classList.add('has-update');
// 创建通知元素
const notification = document.createElement('div');
notification.className = 'theme-notification';
notification.textContent = message;
document.body.appendChild(notification);
// 显示通知
setTimeout(() => {
notification.style.transform = 'translateY(0)';
notification.style.opacity = '1';
}, 10);
// 3秒后移除通知
setTimeout(() => {
notification.style.transform = 'translateY(100px)';
notification.style.opacity = '0';
setTimeout(() => {
notification.remove();
}, 300);
}, 3000);
// 移除更新提示点
setTimeout(() => {
themeToggleBtn.classList.remove('has-update');
}, 3000);
}
// 日历功能
function renderCalendar(year, month) {
const calendarDays = document.getElementById('calendarDays');
const calendarMonth = document.getElementById('calendarMonth');
// 设置月份标题
const monthNames = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];
calendarMonth.textContent = `${year}年 ${monthNames[month]}`;
// 获取当月第一天和最后一天
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
// 获取当月天数
const daysInMonth = lastDay.getDate();
// 获取当月第一天是星期几 (0-6, 0是星期日)
const firstDayOfWeek = firstDay.getDay();
// 获取上个月最后几天
const prevMonthLastDay = new Date(year, month, 0).getDate();
// 清空日历
calendarDays.innerHTML = '';
// 添加上个月的几天
for (let i = firstDayOfWeek - 1; i >= 0; i--) {
const dayElement = document.createElement('div');
dayElement.className = 'calendar-day other-month';
dayElement.textContent = prevMonthLastDay - i;
calendarDays.appendChild(dayElement);
}
// 添加当月天数
const today = new Date();
for (let i = 1; i <= daysInMonth; i++) {
const dayElement = document.createElement('div');
dayElement.className = 'calendar-day';
dayElement.textContent = i;
// 标记今天
if (year === today.getFullYear() && month === today.getMonth() && i === today.getDate()) {
dayElement.classList.add('today');
}
calendarDays.appendChild(dayElement);
}
// 添加下个月的前几天
const remainingDays = 42 - (firstDayOfWeek + daysInMonth); // 6行x7天=42格
for (let i = 1; i <= remainingDays; i++) {
const dayElement = document.createElement('div');
dayElement.className = 'calendar-day other-month';
dayElement.textContent = i;
calendarDays.appendChild(dayElement);
}
}
// 初始化日历
let currentDate = new Date();
let currentYear = currentDate.getFullYear();
let currentMonth = currentDate.getMonth();
renderCalendar(currentYear, currentMonth);
// 日历导航按钮
document.getElementById('calendarPrev').addEventListener('click', () => {
currentMonth--;
if (currentMonth < 0) {
currentMonth = 11;
currentYear--;
}
renderCalendar(currentYear, currentMonth);
});
document.getElementById('calendarNext').addEventListener('click', () => {
currentMonth++;
if (currentMonth > 11) {
currentMonth = 0;
currentYear++;
}
renderCalendar(currentYear, currentMonth);
});
// 待办事项功能
const todoList = document.getElementById('todoList');
const todoInput = document.querySelector('.todo-input');
const todoSubmit = document.querySelector('.todo-submit');
// 添加新任务
function addTodoItem(text, completed = false) {
const li = document.createElement('li');
li.className = 'todo-item';
li.innerHTML = `
<input type="checkbox" class="todo-checkbox" ${completed ? 'checked' : ''}>
<span class="todo-text ${completed ? 'completed' : ''}">${text}</span>
<i class="fas fa-trash todo-delete"></i>
`;
// 添加事件监听器
const checkbox = li.querySelector('.todo-checkbox');
const deleteBtn = li.querySelector('.todo-delete');
checkbox.addEventListener('change', function() {
const textElement = this.nextElementSibling;
textElement.classList.toggle('completed', this.checked);
saveTodos();
});
deleteBtn.addEventListener('click', function() {
li.remove();
saveTodos();
});
todoList.appendChild(li);
}
// 保存待办事项到本地存储
function saveTodos() {
const todos = [];
document.querySelectorAll('.todo-item').forEach(item => {
todos.push({
text: item.querySelector('.todo-text').textContent,
completed: item.querySelector('.todo-checkbox').checked
});
});
localStorage.setItem('todos', JSON.stringify(todos));
}
// 从本地存储加载待办事项
function loadTodos() {
const todos = JSON.parse(localStorage.getItem('todos')) || [];
todos.forEach(todo => {
addTodoItem(todo.text, todo.completed);
});
}
// 添加新任务
todoSubmit.addEventListener('click', function() {
const text = todoInput.value.trim();
if (text) {
addTodoItem(text);
todoInput.value = '';
saveTodos();
}
});
// 按Enter键添加任务
todoInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
const text = todoInput.value.trim();
if (text) {
addTodoItem(text);
todoInput.value = '';
saveTodos();
}
}
});
// 加载待办事项
loadTodos();
// 访客统计图表
function renderVisitorChart() {
const ctx = document.getElementById('visitorChart').getContext('2d');
// 模拟访客数据 - 最近7天
const dates = [];
const visitors = [];
// 生成最近7天的日期和模拟访客数据
for (let i = 6; i >= 0; i--) {
const date = new Date();
date.setDate(date.getDate() - i);
dates.push(date.toLocaleDateString('zh-CN', { month: 'short', day: 'numeric' }));
// 模拟数据,30-100之间
visitors.push(Math.floor(Math.random() * 70) + 30);
}
// 创建图表
new Chart(ctx, {
type: 'line',
data: {
labels: dates,
datasets: [{
label: '访客数量',
data: visitors,
backgroundColor: 'rgba(30, 144, 255, 0.2)',
borderColor: 'rgba(30, 144, 255, 1)',
borderWidth: 2,
tension: 0.4,
fill: true,
pointBackgroundColor: 'rgba(30, 144, 255, 1)',
pointBorderColor: '#fff',
pointBorderWidth: 2,
pointRadius: 4,
pointHoverRadius: 6
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
tooltip: {
backgroundColor: 'rgba(22, 33, 62, 0.8)',
titleColor: '#fff',
bodyColor: '#fff',
borderColor: 'rgba(255, 255, 255, 0.1)',
borderWidth: 1,
displayColors: false,
callbacks: {
title: function(tooltipItems) {
return tooltipItems[0].label;
},
label: function(context) {
return `访客数: ${context.raw}`;
}
}
}
},
scales: {
x: {
grid: {
display: false,
drawBorder: false
},
ticks: {
color: function() {
return document.body.classList.contains('light-mode') ? '#4a5568' : '#94a3b8';
}
}
},
y: {
beginAtZero: true,
grid: {
color: function() {
return document.body.classList.contains('light-mode') ? 'rgba(0, 0, 0, 0.05)' : 'rgba(255, 255, 255, 0.05)';
}
},
ticks: {
color: function() {
return document.body.classList.contains('light-mode') ? '#4a5568' : '#94a3b8';
},
stepSize: 20
}
}
}
}
});
}
// 当DOM加载完成后渲染图表
document.addEventListener('DOMContentLoaded', renderVisitorChart);
// 主题切换时重新渲染图表
themeToggleBtn.addEventListener('click', () => {
// 延迟一点时间确保主题已经切换
setTimeout(() => {
// 清除旧图表
const oldChart = document.getElementById('visitorChart');
const parent = oldChart.parentNode;
parent.removeChild(oldChart);
// 创建新的canvas元素
const newChart = document.createElement('canvas');
newChart.id = 'visitorChart';
newChart.width = '100%';
newChart.height = '200';
parent.appendChild(newChart);
// 重新渲染图表
renderVisitorChart();
}, 100);
});
// FPS监控功能
const fpsDisplay = document.getElementById('fpsDisplay');
const fpsValue = document.querySelector('.fps-value');
const fpsStatus = document.querySelector('.fps-status');
const fpsCharacter = document.querySelector('.fps-character');
// FPS计算
let frameCount = 0;
let fps = 60;
let lastTime = performance.now();
let frameTime = 0;
function updateFPS() {
frameCount++;
const currentTime = performance.now();
frameTime += currentTime - lastTime;
lastTime = currentTime;
if (frameTime >= 1000) {
fps = Math.round((frameCount * 1000) / frameTime);
frameCount = 0;
frameTime = 0;
// 更新FPS显示
fpsValue.textContent = fps;
// 根据FPS值更新状态和表情
if (fps >= 55) {
fpsDisplay.className = 'comic-fps excellent';
fpsStatus.textContent = '超流畅!';
fpsCharacter.textContent = '(๑•̀ㅂ•́)و✧';
} else if (fps >= 45) {
fpsDisplay.className = 'comic-fps good';
fpsStatus.textContent = '流畅';
fpsCharacter.textContent = '(•̀ᴗ•́)و ̑̑';
} else if (fps >= 30) {
fpsDisplay.className = 'comic-fps normal';
fpsStatus.textContent = '一般';
fpsCharacter.textContent = '(・∀・)';
} else if (fps >= 15) {
fpsDisplay.className = 'comic-fps low';
fpsStatus.textContent = '卡顿';
fpsCharacter.textContent = '( ̄▽ ̄")';
} else {
fpsDisplay.className = 'comic-fps critical';
fpsStatus.textContent = '严重卡顿!';
fpsCharacter.textContent = '(╥﹏╥)';
}
}
requestAnimationFrame(updateFPS);
}
// 启动FPS监控
requestAnimationFrame(updateFPS);
// 赞赏码放大功能
const donateImage = document.getElementById('donateImage');
const donateModal = document.getElementById('donateModal');
const donateModalImg = document.getElementById('donateModalImg');
const donateModalClose = document.getElementById('donateModalClose');
// 点击赞赏码打开模态框
donateImage.addEventListener('click', () => {
// 获取原始图片的src
const imgSrc = donateImage.querySelector('img').src;
// 设置模态框图片的src
donateModalImg.src = imgSrc;
// 显示模态框
donateModal.classList.add('active');
// 阻止页面滚动
document.body.style.overflow = 'hidden';
});
// 点击关闭按钮关闭模态框
donateModalClose.addEventListener('click', () => {
donateModal.classList.remove('active');
// 恢复页面滚动
document.body.style.overflow = '';
});
// 点击模态框背景关闭模态框
donateModal.addEventListener('click', (e) => {
if (e.target === donateModal) {
donateModal.classList.remove('active');
// 恢复页面滚动
document.body.style.overflow = '';
}
});
// ESC键关闭模态框
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && donateModal.classList.contains('active')) {
donateModal.classList.remove('active');
// 恢复页面滚动
document.body.style.overflow = '';
}
});
// 天气API配置
const weatherConfig = {
apiUrl: "https://cn.apihz.cn/api/tianqi/tqybmoji15ip.php",
id: "10003788", // 替换为你的用户ID
key: "ffa8afb46dce4916c5a74fd73c8de9f6", // 替换为你的API Key
ip: "", // 留空则使用访问者IP
uip: "" // 留空则使用访问者IP
};
// 获取天气数据
async function fetchWeatherData() {
try {
// 构建请求URL
const params = new URLSearchParams();
params.append('id', weatherConfig.id);
params.append('key', weatherConfig.key);
if (weatherConfig.ip) params.append('ip', weatherConfig.ip);
if (weatherConfig.uip) params.append('uip', weatherConfig.uip);
const url = `${weatherConfig.apiUrl}?${params.toString()}`;
const response = await fetch(url);
const data = await response.json();
if (data.code === 200) {
updateWeatherUI(data);
} else {
console.error("天气API错误:", data.msg);
updateWeatherUI(null); // 使用默认数据
}
} catch (error) {
console.error("获取天气数据失败:", error);
updateWeatherUI(null); // 使用默认数据
}
}
// 更新天气UI
function updateWeatherUI(apiData) {
const locationEl = document.getElementById('weather-location');
const weatherIcon = document.querySelector('.weather-current .weather-icon i');
const weatherTemp = document.querySelector('.weather-current .weather-temp');
const weatherDesc = document.querySelector('.weather-current .weather-desc');
const weatherDays = document.querySelectorAll('.weather-forecast .weather-day');
// 默认数据(当API请求失败时使用)
const defaultData = {
place: "北京",
data: [
{
week1: "今天",
wea1: "晴",
wea2: "晴",
wendu1: "25°",
wendu2: "17°"
},
{
week1: "明天",
wea1: "多云",
wea2: "多云",
wendu1: "23°",
wendu2: "18°"
},
{
week1: "后天",
wea1: "阴",
wea2: "小雨",
wendu1: "20°",
wendu2: "16°"
},
{
week1: "大后天",
wea1: "小雨",
wea2: "晴",
wendu1: "22°",
wendu2: "15°"
}
]
};
const weatherData = apiData || defaultData;
// 更新位置信息
locationEl.textContent = `📍 ${weatherData.place || "未知位置"}`;
// 更新当前天气(使用今天的数据)
const today = weatherData.data[0];
weatherIcon.className = `fas ${getWeatherIcon(today.wea1)}`;
weatherTemp.textContent = today.wendu1;
weatherDesc.textContent = `${today.wea1}${today.wea1 !== today.wea2 ? '转' + today.wea2 : ''}`;
// 更新预报天气(跳过今天,从明天开始)
for (let i = 0; i < 2; i++) {
const dayData = weatherData.data[i + 1]; // 从明天开始
if (weatherDays[i] && dayData) {
const dayEl = weatherDays[i];
// 更新日期显示
dayEl.querySelector('div:first-child').textContent =
i === 0 ? "明天" : "后天";
// 更新天气图标
const iconEl = dayEl.querySelector('.weather-day-icon i');
iconEl.className = `fas ${getWeatherIcon(dayData.wea1)}`;
// 更新温度
dayEl.querySelector('.weather-day-temp').textContent = dayData.wendu1;
}
}
}
// 天气图标映射
function getWeatherIcon(weatherText) {
const iconMap = {
"晴": "fa-sun",
"少云": "fa-cloud-sun",
"多云": "fa-cloud",
"阴": "fa-cloud",
"雾": "fa-smog",
"雷阵雨": "fa-bolt",
"小雨": "fa-cloud-rain",
"中雨": "fa-cloud-rain",
"大雨": "fa-cloud-showers-heavy",
"暴雨": "fa-cloud-showers-heavy",
"阵雨": "fa-cloud-rain",
"雨夹雪": "fa-cloud-meatball",
"小雪": "fa-snowflake",
"中雪": "fa-snowflake",
"大雪": "fa-snowflake",
"暴雪": "fa-snowflake",
"浮尘": "fa-smog",
"扬沙": "fa-smog",
"沙尘暴": "fa-smog"
};
// 尝试匹配完整文本
if (iconMap[weatherText]) {
return iconMap[weatherText];
}
// 尝试匹配部分文本
for (const key in iconMap) {
if (weatherText.includes(key)) {
return iconMap[key];
}
}
// 默认返回晴天图标
return "fa-sun";
}
// 页面加载时获取天气数据
document.addEventListener('DOMContentLoaded', () => {
fetchWeatherData();
// 每1小时更新一次天气数据
setInterval(fetchWeatherData, 60 * 60 * 1000);
});
</script>
index.html
style.css
index.js
assets