generated from dellevin/template
添加历史足迹
This commit is contained in:
26
index.html
26
index.html
@@ -1,5 +1,6 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
@@ -12,9 +13,9 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<!-- 今日诗词 -->
|
<!-- 今日诗词 -->
|
||||||
<!-- <script src="https://sdk.jinrishici.com/v2/browser/jinrishici.js" charset="utf-8"></script> -->
|
<script src="https://sdk.jinrishici.com/v2/browser/jinrishici.js" charset="utf-8"></script>
|
||||||
<!-- 百度统计 -->
|
<!-- 百度统计 -->
|
||||||
<!-- <script>
|
<script>
|
||||||
var _hmt = _hmt || [];
|
var _hmt = _hmt || [];
|
||||||
(function () {
|
(function () {
|
||||||
var hm = document.createElement("script");
|
var hm = document.createElement("script");
|
||||||
@@ -22,9 +23,11 @@
|
|||||||
var s = document.getElementsByTagName("script")[0];
|
var s = document.getElementsByTagName("script")[0];
|
||||||
s.parentNode.insertBefore(hm, s);
|
s.parentNode.insertBefore(hm, s);
|
||||||
})();
|
})();
|
||||||
</script> -->
|
</script>
|
||||||
<!-- umami统计 -->
|
<!-- umami统计 -->
|
||||||
<!-- <script defer src="https://umami.iletter.top/anyjs" data-website-id="ae6cd64c-5900-49c9-9c22-95cedc24a508"></script> -->
|
<script defer src="https://umami.iletter.top/anyjs" data-website-id="ae6cd64c-5900-49c9-9c22-95cedc24a508"></script>
|
||||||
|
<!-- ECharts 库 -->
|
||||||
|
<script src="./static/js/echarts/echarts.min.js"></script>
|
||||||
<!-- 多语言 -->
|
<!-- 多语言 -->
|
||||||
<script src="./static/js/language/zh.js"></script>
|
<script src="./static/js/language/zh.js"></script>
|
||||||
<script src="./static/js/language/en.js"></script>
|
<script src="./static/js/language/en.js"></script>
|
||||||
@@ -36,6 +39,7 @@
|
|||||||
</style>
|
</style>
|
||||||
<title data-i18n="page_title">白荼 - BAITU</title>
|
<title data-i18n="page_title">白荼 - BAITU</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="letter-container">
|
<div class="letter-container">
|
||||||
<!-- 语言切换按钮 -->
|
<!-- 语言切换按钮 -->
|
||||||
@@ -49,6 +53,9 @@
|
|||||||
<div class="nav-tab" data-tab="website"><span data-i18n="nav_website"></span></div>
|
<div class="nav-tab" data-tab="website"><span data-i18n="nav_website"></span></div>
|
||||||
<div class="nav-tab" data-tab="tools"><span data-i18n="nav_tools"></span></div>
|
<div class="nav-tab" data-tab="tools"><span data-i18n="nav_tools"></span></div>
|
||||||
<div class="nav-tab" data-tab="games"><span data-i18n="nav_games"></span></div>
|
<div class="nav-tab" data-tab="games"><span data-i18n="nav_games"></span></div>
|
||||||
|
|
||||||
|
<div class="nav-tab" data-tab="footprint"><span data-i18n="nav_footprint"></span></div>
|
||||||
|
|
||||||
<div class="nav-tab" data-tab="memos"><span data-i18n="nav_memos"></span></div>
|
<div class="nav-tab" data-tab="memos"><span data-i18n="nav_memos"></span></div>
|
||||||
<div class="nav-tab" data-tab="contact"><span data-i18n="nav_contact"></span></div>
|
<div class="nav-tab" data-tab="contact"><span data-i18n="nav_contact"></span></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -140,6 +147,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 历史足迹 (地图) -->
|
||||||
|
<div id="footprint-content" class="tab-content">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 闲言碎语内容 -->
|
<!-- 闲言碎语内容 -->
|
||||||
<div class="tab-content" id="memos-content">
|
<div class="tab-content" id="memos-content">
|
||||||
<div class="content-section">
|
<div class="content-section">
|
||||||
@@ -168,7 +180,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="copyright" style="margin-top: 15px;"><a href="http://beian.miit.gov.cn"
|
<div class="copyright" style="margin-top: 15px;"><a href="http://beian.miit.gov.cn"
|
||||||
target="_blank">冀ICP备2025122609号</a> ©<span>2024 - 2026</span> <span>Power BY</span> <span>Del Levin </span>
|
target="_blank">冀ICP备2025122609号</a> ©<span>2024 - 2026</span> <span>Power BY</span> <span>Del
|
||||||
|
Levin </span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@@ -199,7 +212,7 @@
|
|||||||
const key = element.getAttribute('data-i18n');
|
const key = element.getAttribute('data-i18n');
|
||||||
const translation = translations[lang][key];
|
const translation = translations[lang][key];
|
||||||
if (translation !== undefined) {
|
if (translation !== undefined) {
|
||||||
element.innerHTML = translation;
|
element.innerHTML = translation;
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Translation key '${key}' not found for language '${lang}'`);
|
console.warn(`Translation key '${key}' not found for language '${lang}'`);
|
||||||
}
|
}
|
||||||
@@ -229,6 +242,7 @@
|
|||||||
<script src="./static/js/tools_my.js"></script>
|
<script src="./static/js/tools_my.js"></script>
|
||||||
<script src="./static/js/memos.js"></script>
|
<script src="./static/js/memos.js"></script>
|
||||||
<script src="./static/js/my-websites.js"></script>
|
<script src="./static/js/my-websites.js"></script>
|
||||||
|
<script src="./static/js/map-footprint.js"></script>
|
||||||
<script src="./static/js/tabchange.js"></script>
|
<script src="./static/js/tabchange.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
235
index.html.bak
Normal file
235
index.html.bak
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="description" content="95后,全干开发者">
|
||||||
|
<meta name="keywords" content="Java,Spring,个人博客,微信小程序,博客,技术文章,编程,开发者,白荼,Del Levin">
|
||||||
|
<link rel="shortcut icon" href="./favicon.ico">
|
||||||
|
<script type="text/javascript">
|
||||||
|
if (!!window.ActiveXObject || "ActiveXObject" in window) { //is IE?
|
||||||
|
alert('朋友,上古浏览器不支持呢~');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<!-- 今日诗词 -->
|
||||||
|
<script src="https://sdk.jinrishici.com/v2/browser/jinrishici.js" charset="utf-8"></script>
|
||||||
|
<!-- 百度统计 -->
|
||||||
|
<script>
|
||||||
|
var _hmt = _hmt || [];
|
||||||
|
(function () {
|
||||||
|
var hm = document.createElement("script");
|
||||||
|
hm.src = "https://hm.baidu.com/hm.js?d82271fd27b69793bf97f088c0a87fd4";
|
||||||
|
var s = document.getElementsByTagName("script")[0];
|
||||||
|
s.parentNode.insertBefore(hm, s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<!-- umami统计 -->
|
||||||
|
<script defer src="https://umami.iletter.top/anyjs" data-website-id="ae6cd64c-5900-49c9-9c22-95cedc24a508"></script>
|
||||||
|
<!-- 多语言 -->
|
||||||
|
<script src="./static/js/language/zh.js"></script>
|
||||||
|
<script src="./static/js/language/en.js"></script>
|
||||||
|
<script src="./static/js/axios.min.js"></script>
|
||||||
|
<style>
|
||||||
|
@import url("./static/css/main.css");
|
||||||
|
@import url("./static/css/memos.css");
|
||||||
|
@import url("./static/css/game_dialog.css");
|
||||||
|
</style>
|
||||||
|
<title data-i18n="page_title">白荼 - BAITU</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="letter-container">
|
||||||
|
<!-- 语言切换按钮 -->
|
||||||
|
<div class="lang-switch-container">
|
||||||
|
<img id="lang-switch-btn" src="./static/img/中文.png" alt="Switch Language" title="切换语言" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 头部导航 -->
|
||||||
|
<div class="nav-tabs">
|
||||||
|
<div class="nav-tab active" data-tab="about"><span data-i18n="nav_about"></span></div>
|
||||||
|
<div class="nav-tab" data-tab="website"><span data-i18n="nav_website"></span></div>
|
||||||
|
<div class="nav-tab" data-tab="tools"><span data-i18n="nav_tools"></span></div>
|
||||||
|
<div class="nav-tab" data-tab="games"><span data-i18n="nav_games"></span></div>
|
||||||
|
<div class="nav-tab" data-tab="memos"><span data-i18n="nav_memos"></span></div>
|
||||||
|
<div class="nav-tab" data-tab="contact"><span data-i18n="nav_contact"></span></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 今日诗词 -->
|
||||||
|
<div id="jinrishici-sentence">正在加载今日诗词...</div>
|
||||||
|
|
||||||
|
<!-- 联系我内容 -->
|
||||||
|
<div class="tab-content" id="contact-content">
|
||||||
|
<div class="content-section">
|
||||||
|
<h2 data-i18n="contact_me_h2"></h2>
|
||||||
|
<p data-i18n="contact_intro"></p>
|
||||||
|
<div class="contact-info">
|
||||||
|
<div class="contact-item">
|
||||||
|
<span class="contact-label" data-i18n="email_label">邮箱:</span>
|
||||||
|
<span>dellevin99@gmail.com</span>
|
||||||
|
</div>
|
||||||
|
<div class="contact-item">
|
||||||
|
<span class="contact-label" data-i18n="wechat_label">微信:</span>
|
||||||
|
<span>E-Levin_</span>
|
||||||
|
</div>
|
||||||
|
<div class="contact-item">
|
||||||
|
<span class="contact-label" data-i18n="qq_label">扣扣:</span>
|
||||||
|
<span>1754084631</span>
|
||||||
|
</div>
|
||||||
|
<div class="contact-item">
|
||||||
|
<span class="contact-label" data-i18n="address_label">地址:</span>
|
||||||
|
<span data-i18n="address_value">山东省·济南市·市中区</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 data-i18n="social_media_h3">社交媒体</h3>
|
||||||
|
<div class="website-links">
|
||||||
|
<a href="https://github.com/dellevin" target="_blank" data-i18n="social_link1"
|
||||||
|
data-i18n-attr="href">GitHub</a>
|
||||||
|
<a href="https://weibo.com/u/6094785109999999999" target="_blank" data-i18n="social_link2"
|
||||||
|
data-i18n-attr="href">微博</a>
|
||||||
|
<a href="https://www.zhihu.com/people/bing-xue-chen-xi-59" target="_blank" data-i18n="social_link3"
|
||||||
|
data-i18n-attr="href">知乎</a>
|
||||||
|
<a href="https://space.bilibili.com/403551212" target="_blank" data-i18n="social_link4"
|
||||||
|
data-i18n-attr="href">B站</a>
|
||||||
|
<a href="https://www.52pojie.cn/home.php?mod=space&uid=2059006" target="_blank"
|
||||||
|
data-i18n="social_link5" data-i18n-attr="href">52pojie</a>
|
||||||
|
</div>
|
||||||
|
<h3 data-i18n="leave_message_h3">留言</h3>
|
||||||
|
<p data-i18n="leave_message_p"><a href="https://blog.iletter.top/401.html" target="_blank"
|
||||||
|
data-i18n="leave_message_link" data-i18n-attr="href">点击此链接</a>去我的博客下面给我留言!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 关于我内容 -->
|
||||||
|
<div class="tab-content active" id="about-content">
|
||||||
|
<div class="content-section about-me-content">
|
||||||
|
<h2 data-i18n="hello"></h2>
|
||||||
|
<p data-i18n="greeting"></p>
|
||||||
|
<p data-i18n="about_me_p1"></p>
|
||||||
|
<p data-i18n="about_me_p2"></p>
|
||||||
|
<p data-i18n="about_me_p3"></p>
|
||||||
|
<p data-i18n="about_me_p4"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 我的网站内容 -->
|
||||||
|
<div class="tab-content" id="website-content">
|
||||||
|
<div class="content-section">
|
||||||
|
<h2 data-i18n="my_website_h2"></h2>
|
||||||
|
<div class="website-links" id="dynamic-website-links"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 工具内容 -->
|
||||||
|
<div class="tab-content" id="tools-content">
|
||||||
|
<div class="content-section">
|
||||||
|
<h2 data-i18n="my_tools_h2">我的工具</h2>
|
||||||
|
|
||||||
|
<div id="tools-container" class="tools-grid">
|
||||||
|
<div class="memo-loading" data-i18n="loading_tools">正在加载工具列表...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 游戏内容 -->
|
||||||
|
<div class="tab-content" id="games-content">
|
||||||
|
<div class="content-section">
|
||||||
|
<h2 data-i18n="my_games_h2">我常玩的游戏</h2>
|
||||||
|
<div id="games-container" class="games-grid">
|
||||||
|
<div class="memo-loading" data-i18n="loading_games">正在加载游戏列表...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 闲言碎语内容 -->
|
||||||
|
<div class="tab-content" id="memos-content">
|
||||||
|
<div class="content-section">
|
||||||
|
<h2 data-i18n="memos_h2">闲言碎语</h2>
|
||||||
|
<div id="memos-container" class="memos-container">
|
||||||
|
<div class="memo-loading" data-i18n="loading_memos">正在加载...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="letter-footer">
|
||||||
|
<span data-i18n="footer_text"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部版权信息和网站统计 - 在信纸外部 -->
|
||||||
|
<div id="footer-wrap">
|
||||||
|
<div class="webinfo">
|
||||||
|
<div class="webinfo-item">
|
||||||
|
<div class="webinfo-site-uv-name" data-i18n="visitor_count_label">本站访客数 :</div>
|
||||||
|
<div class="webinfo-site-uv-count" id="site_uv">-</div>
|
||||||
|
</div>
|
||||||
|
<div class="webinfo-item">
|
||||||
|
<div class="webinfo-site-name" data-i18n="visit_count_label">本站总访问量 :</div>
|
||||||
|
<div class="webinfo-site-pv-count" id="site_pv">-</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="copyright" style="margin-top: 15px;"><a href="http://beian.miit.gov.cn"
|
||||||
|
target="_blank">冀ICP备2025122609号</a> ©<span>2024 - 2026</span> <span>Power BY</span> <span>Del Levin </span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
// ========== 语言切换逻辑 ==========
|
||||||
|
const translations = {
|
||||||
|
'zh': translationsZH,
|
||||||
|
'en': translationsEN
|
||||||
|
};
|
||||||
|
if (typeof translations === 'undefined') {
|
||||||
|
console.error('Translations file (translations.js) is not loaded!');
|
||||||
|
}
|
||||||
|
const switchButton = document.getElementById('lang-switch-btn');
|
||||||
|
const LANG_KEY = 'preferred_language';
|
||||||
|
function switchLanguage() {
|
||||||
|
let currentLang = localStorage.getItem(LANG_KEY) || 'zh';
|
||||||
|
let newLang = currentLang === 'zh' ? 'en' : 'zh';
|
||||||
|
|
||||||
|
localStorage.setItem(LANG_KEY, newLang);
|
||||||
|
updatePageContent(newLang);
|
||||||
|
updateLanguageIcon(newLang);
|
||||||
|
document.documentElement.lang = newLang;
|
||||||
|
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
function updatePageContent(lang) {
|
||||||
|
const elements = document.querySelectorAll('[data-i18n]');
|
||||||
|
elements.forEach(element => {
|
||||||
|
const key = element.getAttribute('data-i18n');
|
||||||
|
const translation = translations[lang][key];
|
||||||
|
if (translation !== undefined) {
|
||||||
|
element.innerHTML = translation;
|
||||||
|
} else {
|
||||||
|
console.warn(`Translation key '${key}' not found for language '${lang}'`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function updateLanguageIcon(lang) {
|
||||||
|
if (lang === 'zh') {
|
||||||
|
switchButton.src = './static/img/中文.png';
|
||||||
|
switchButton.alt = 'Switch to English';
|
||||||
|
switchButton.title = '切换到英文';
|
||||||
|
} else {
|
||||||
|
switchButton.src = './static/img/英文.png';
|
||||||
|
switchButton.alt = 'Switch to Chinese';
|
||||||
|
switchButton.title = '切换到中文';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const savedLang = localStorage.getItem(LANG_KEY) || 'zh';
|
||||||
|
updatePageContent(savedLang);
|
||||||
|
updateLanguageIcon(savedLang);
|
||||||
|
document.documentElement.lang = savedLang;
|
||||||
|
switchButton.addEventListener('click', switchLanguage);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script src="./static/js/anypage.js"></script>
|
||||||
|
<script src="./static/js/game_my.js"></script>
|
||||||
|
<script src="./static/js/tools_my.js"></script>
|
||||||
|
<script src="./static/js/memos.js"></script>
|
||||||
|
<script src="./static/js/my-websites.js"></script>
|
||||||
|
<script src="./static/js/tabchange.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -1,324 +1,324 @@
|
|||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: 'Georgia', 'Times New Roman', 'STSong', serif;
|
font-family: 'Georgia', 'Times New Roman', 'STSong', serif;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
color: #333;
|
color: #333;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background-position: 0 0, 10px 10px;
|
background-position: 0 0, 10px 10px;
|
||||||
/* 信件背景(图片) */
|
/* 信件背景(图片) */
|
||||||
background: #eeeeee url(../img/bj.png);
|
background: #eeeeee url(../img/bj.png);
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
/* 信件背景(马赛克方格) */
|
/* 信件背景(马赛克方格) */
|
||||||
/*background-color: #f0f0f0;*/
|
/*background-color: #f0f0f0;*/
|
||||||
/*background-image:*/
|
/*background-image:*/
|
||||||
/* linear-gradient(45deg, #e0e0e0 25%, transparent 25%, transparent 75%, #e0e0e0 75%),*/
|
/* linear-gradient(45deg, #e0e0e0 25%, transparent 25%, transparent 75%, #e0e0e0 75%),*/
|
||||||
/* linear-gradient(45deg, #e0e0e0 25%, transparent 25%, transparent 75%, #e0e0e0 75%);*/
|
/* linear-gradient(45deg, #e0e0e0 25%, transparent 25%, transparent 75%, #e0e0e0 75%);*/
|
||||||
/*background-size: 20px 20px;*/
|
/*background-size: 20px 20px;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.letter-container {
|
.letter-container {
|
||||||
max-width: 800px;
|
max-width: 850px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
background: white;
|
background: white;
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 语言切换按钮样式 */
|
/* 语言切换按钮样式 */
|
||||||
.lang-switch-container {
|
.lang-switch-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lang-switch-container img {
|
.lang-switch-container img {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
transition: opacity 0.3s ease;
|
transition: opacity 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lang-switch-container img:hover {
|
.lang-switch-container img:hover {
|
||||||
opacity: 1.0;
|
opacity: 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 头部导航 */
|
/* 头部导航 */
|
||||||
.nav-tabs {
|
.nav-tabs {
|
||||||
display: flex;
|
display: flex;
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tab {
|
.nav-tab {
|
||||||
padding: 15px 20px;
|
padding: 15px 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-bottom: 3px solid transparent;
|
border-bottom: 3px solid transparent;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tab:hover {
|
.nav-tab:hover {
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tab.active {
|
.nav-tab.active {
|
||||||
border-bottom-color: #333;
|
border-bottom-color: #333;
|
||||||
color: #333;
|
color: #333;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 内容区域 */
|
/* 内容区域 */
|
||||||
.tab-content {
|
.tab-content {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-content.active {
|
.tab-content.active {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 信纸纹理效果 */
|
/* 信纸纹理效果 */
|
||||||
.letter-container {
|
.letter-container {
|
||||||
background-image:
|
background-image:
|
||||||
linear-gradient(transparent 29px, #f0f0f0 30px);
|
linear-gradient(transparent 29px, #f0f0f0 30px);
|
||||||
background-size: 100% 30px;
|
background-size: 100% 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 通用内容样式 */
|
/* 通用内容样式 */
|
||||||
.content-section {
|
.content-section {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-section h2 {
|
.content-section h2 {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
color: #222;
|
color: #222;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-section h3 {
|
.content-section h3 {
|
||||||
margin: 25px 0 15px 0;
|
margin: 25px 0 15px 0;
|
||||||
color: #444;
|
color: #444;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-section p {
|
.content-section p {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
text-align: justify;
|
text-align: justify;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 列表样式 */
|
/* 列表样式 */
|
||||||
.content-section ul {
|
.content-section ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
margin: 15px 0;
|
margin: 15px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-section li {
|
.content-section li {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-section li::before {
|
.content-section li::before {
|
||||||
content: "▹";
|
content: "▹";
|
||||||
color: #999;
|
color: #999;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 联系方式 */
|
/* 联系方式 */
|
||||||
.contact-info {
|
.contact-info {
|
||||||
margin: 15px 0;
|
margin: 15px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-item {
|
.contact-item {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-label {
|
.contact-label {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #555;
|
color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 网站链接 */
|
/* 网站链接 */
|
||||||
.website-links a {
|
.website-links a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
color: #666;
|
color: #666;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.website-links a:hover {
|
.website-links a:hover {
|
||||||
color: #333;
|
color: #333;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 工具和游戏网格 */
|
/* 工具和游戏网格 */
|
||||||
.tools-grid,
|
.tools-grid,
|
||||||
.games-grid {
|
.games-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
margin: 15px 0;
|
margin: 15px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-item,
|
.tool-item,
|
||||||
.game-item {
|
.game-item {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-name,
|
.tool-name,
|
||||||
.game-name {
|
.game-name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333;
|
color: #333;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-desc,
|
.tool-desc,
|
||||||
.game-desc {
|
.game-desc {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 关于我页面特殊样式 */
|
/* 关于我页面特殊样式 */
|
||||||
.about-me-content {
|
.about-me-content {
|
||||||
text-align: justify;
|
text-align: justify;
|
||||||
}
|
}
|
||||||
|
|
||||||
.about-me-content p:first-child {
|
.about-me-content p:first-child {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: #666;
|
color: #666;
|
||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.letter-container {
|
.letter-container {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs {
|
.nav-tabs {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tab {
|
.nav-tab {
|
||||||
padding: 10px 15px;
|
padding: 10px 15px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tools-grid,
|
.tools-grid,
|
||||||
.games-grid {
|
.games-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 移动端调整语言按钮位置 */
|
/* 移动端调整语言按钮位置 */
|
||||||
.lang-switch-container {
|
.lang-switch-container {
|
||||||
top: 5px;
|
top: 5px;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 信纸底部页脚描述 */
|
/* 信纸底部页脚描述 */
|
||||||
.letter-footer {
|
.letter-footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 60px;
|
margin-top: 60px;
|
||||||
padding-top: 20px;
|
padding-top: 20px;
|
||||||
border-top: 1px solid #eee;
|
border-top: 1px solid #eee;
|
||||||
color: #999;
|
color: #999;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 底部版权信息 - 在信纸外部 */
|
/* 底部版权信息 - 在信纸外部 */
|
||||||
#footer-wrap {
|
#footer-wrap {
|
||||||
max-width: 800px;
|
max-width: 850px;
|
||||||
margin: 0 auto 20px auto;
|
margin: 0 auto 20px auto;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
color: #999;
|
color: #999;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
background: white;
|
background: white;
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
background-image:
|
background-image:
|
||||||
linear-gradient(transparent 29px, #f0f0f0 30px);
|
linear-gradient(transparent 29px, #f0f0f0 30px);
|
||||||
background-size: 100% 30px;
|
background-size: 100% 30px;
|
||||||
border-top: 1px solid #eee;
|
border-top: 1px solid #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
#footer-wrap a {
|
#footer-wrap a {
|
||||||
color: #666;
|
color: #666;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#footer-wrap a:hover {
|
#footer-wrap a:hover {
|
||||||
color: #333;
|
color: #333;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
#footer-wrap img {
|
#footer-wrap img {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 今日诗词样式 */
|
/* 今日诗词样式 */
|
||||||
#jinrishici-sentence {
|
#jinrishici-sentence {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 111px;
|
top: 111px;
|
||||||
right: 40px;
|
right: 40px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: #666;
|
color: #666;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 网站统计样式 */
|
/* 网站统计样式 */
|
||||||
.webinfo {
|
.webinfo {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 30px;
|
gap: 30px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #999;
|
color: #999;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.webinfo-item {
|
.webinfo-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
#jinrishici-sentence {
|
#jinrishici-sentence {
|
||||||
position: static;
|
position: static;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.webinfo {
|
.webinfo {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BIN
static/img/game/guigubahuang/1.jpg
Normal file
BIN
static/img/game/guigubahuang/1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 840 KiB |
BIN
static/img/game/guigubahuang/2.jpg
Normal file
BIN
static/img/game/guigubahuang/2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
BIN
static/img/game/guigubahuang/3.jpg
Normal file
BIN
static/img/game/guigubahuang/3.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 720 KiB |
BIN
static/img/game/wodeshijie/1.jpg
Normal file
BIN
static/img/game/wodeshijie/1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 323 KiB |
BIN
static/img/game/wodeshijie/2.jpg
Normal file
BIN
static/img/game/wodeshijie/2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 377 KiB |
BIN
static/img/game/wodeshijie/3.jpg
Normal file
BIN
static/img/game/wodeshijie/3.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 161 KiB |
1
static/js/echarts/china.geojson
Normal file
1
static/js/echarts/china.geojson
Normal file
File diff suppressed because one or more lines are too long
45
static/js/echarts/echarts.min.js
vendored
Normal file
45
static/js/echarts/echarts.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,74 +1,143 @@
|
|||||||
// static/js/game_my.js
|
|
||||||
|
|
||||||
// ========== 游戏配置数据 ==========
|
// ========== 游戏配置数据 ==========
|
||||||
const gamesData = [
|
const gamesData = [
|
||||||
{ id:0, name: "《永劫无间》", desc: "我身无拘,武道无穷" },
|
{ id: 0, name: "《永劫无间》111", desc: "我身无拘,武道无穷" },
|
||||||
{ id:1, name: "《我的世界》", desc: "这个小盒才是我的永远的家" },
|
{ id: 1, name: "《我的世界》", desc: "这个小盒才是我的永远的家" },
|
||||||
{ id:2, name: "《鬼谷八荒》", desc: "当互动版的修仙小说看了,很好玩." },
|
{ id: 2, name: "《鬼谷八荒》", desc: "当互动版的修仙小说看了,很好玩." },
|
||||||
{ id:3, name: "《江城创业记》", desc: "缝合怪,但是全缝了。很喜欢的一款游戏" },
|
{
|
||||||
{ id:4, name: "《中国式家长》", desc: "我承认我做不好一个孩子,也做不好一个家长" },
|
id: 3,
|
||||||
{ id:5, name: "《王者荣耀》", desc: "买了好多皮肤,和朋友玩才是真快乐(已退坑)" },
|
name: "《江城创业记》",
|
||||||
{ id:6, name: "《QQ飞车手游》", desc: "氪了好多,有些后悔了,太耗注意力了(已退坑)" },
|
desc: "缝合怪,但是全缝了。很喜欢的一款游戏",
|
||||||
{ id:7, name: "《龙族幻想》", desc: "因为龙族入坑的,江南老贼!(已退坑)" },
|
},
|
||||||
{ id:8, name: "《洛克王国》", desc: "还记得小时候拿压岁钱偷偷买点卡(已退坑)" },
|
{
|
||||||
{ id:9, name: "《造梦西游》", desc: "造梦3从小学玩到大学,现在还时不时的回味一下(已退坑)" },
|
id: 4,
|
||||||
|
name: "《中国式家长》",
|
||||||
|
desc: "我承认我做不好一个孩子,也做不好一个家长",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
name: "《王者荣耀》",
|
||||||
|
desc: "买了好多皮肤,和朋友玩才是真快乐(已退坑)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
name: "《QQ飞车手游》",
|
||||||
|
desc: "氪了好多,有些后悔了,太耗注意力了(已退坑)",
|
||||||
|
},
|
||||||
|
{ id: 7, name: "《龙族幻想》", desc: "因为龙族入坑的,江南老贼!(已退坑)" },
|
||||||
|
{
|
||||||
|
id: 8,
|
||||||
|
name: "《洛克王国》",
|
||||||
|
desc: "还记得小时候拿压岁钱偷偷买点卡(已退坑)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 9,
|
||||||
|
name: "《造梦西游》",
|
||||||
|
desc: "造梦3从小学玩到大学,现在还时不时的回味一下(已退坑)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:10,
|
||||||
|
name:'《Street Fighter 6》',
|
||||||
|
desc: "街霸6,超级炎炎舞!outfit3是真好看。",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:11,
|
||||||
|
name:'《WorldBox》',
|
||||||
|
desc: "世界盒子,无意间发现的一款游戏,可惜价格太贵了。",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:12,
|
||||||
|
name:'《无人深空》',
|
||||||
|
desc: "难以想象的开放遨游!这次,我的目标是星辰大海!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:13,
|
||||||
|
name:'《戴森球计划》',
|
||||||
|
desc: "没有蓝图玩的,把自己恶心坏了。主打一个自动化",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// ========== 游戏详情数据 ==========
|
// ========== 游戏详情数据 ==========
|
||||||
const gameDetailData = {
|
const gameDetailData = {
|
||||||
0: {
|
0: {
|
||||||
id: '游戏ID: 42956400140163',
|
id: "游戏ID: 42956400140163",
|
||||||
rank: '<strong>历史最高段位:</strong>无相龙王',
|
rank: "<strong>历史最高段位:</strong>无相龙王",
|
||||||
detailDesc: '我希望能玩一辈子永劫无间!',
|
detailDesc: "我希望能玩一辈子永劫无间!",
|
||||||
images: [
|
images: [
|
||||||
'./static/img/game/yjwj/yjwj_chuanyun.png',
|
"./static/img/game/yjwj/yjwj_chuanyun.png",
|
||||||
'./static/img/game/yjwj/yjwj_xiafeng.png',
|
"./static/img/game/yjwj/yjwj_xiafeng.png",
|
||||||
'./static/img/game/yjwj/yjwj_liebian.png',
|
"./static/img/game/yjwj/yjwj_liebian.png",
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
6: {
|
1: {
|
||||||
id: '',
|
id: "levin9992@qq.com",
|
||||||
rank: '<strong>历史最高段位:</strong>传奇车神',
|
rank: "",
|
||||||
detailDesc: '巅峰竞速!可惜我的天行者被割韭菜了。。。',
|
detailDesc: "我自己精神的自留地!我幻想中的乌托邦",
|
||||||
images: [
|
images: [
|
||||||
'./static/img/game/qqspead/qqspead1.jpg',
|
"./static/img/game/wodeshijie/1.jpg",
|
||||||
'./static/img/game/qqspead/qqspead2.jpg',
|
"./static/img/game/wodeshijie/2.jpg",
|
||||||
]
|
"./static/img/game/wodeshijie/3.jpg",
|
||||||
},
|
],
|
||||||
|
},
|
||||||
|
2: {
|
||||||
|
id: "",
|
||||||
|
rank: "<strong>历史最高段位:</strong>登仙",
|
||||||
|
detailDesc: "好玩!爱玩!立绘非常好看!",
|
||||||
|
images: [
|
||||||
|
"./static/img/game/guigubahuang/1.jpg",
|
||||||
|
"./static/img/game/guigubahuang/2.jpg",
|
||||||
|
"./static/img/game/guigubahuang/3.jpg",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
6: {
|
||||||
|
id: "",
|
||||||
|
rank: "<strong>历史最高段位:</strong>传奇车神",
|
||||||
|
detailDesc: "巅峰竞速!可惜我的天行者被割韭菜了。。。",
|
||||||
|
images: [
|
||||||
|
"./static/img/game/qqspead/qqspead1.jpg",
|
||||||
|
"./static/img/game/qqspead/qqspead2.jpg",
|
||||||
|
],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let currentlyOpenTooltip = null; // 用于跟踪当前打开的tooltip
|
let currentlyOpenTooltip = null; // 用于跟踪当前打开的tooltip
|
||||||
|
|
||||||
// ========== 显示/隐藏游戏详情的函数 (Tooltip 版本) ==========
|
// ========== 显示/隐藏游戏详情的函数 (Tooltip 版本) ==========
|
||||||
function toggleGameDetailTooltip(gameElement, gameIndex) {
|
function toggleGameDetailTooltip(gameElement, gameIndex) {
|
||||||
// 如果点击的是同一个游戏,且tooltip是打开的,则关闭它
|
// 如果点击的是同一个游戏,且tooltip是打开的,则关闭它
|
||||||
if (currentlyOpenTooltip && currentlyOpenTooltip.index === gameIndex && currentlyOpenTooltip.element && currentlyOpenTooltip.element.style.display === 'block') {
|
if (
|
||||||
hideTooltip(currentlyOpenTooltip.element);
|
currentlyOpenTooltip &&
|
||||||
currentlyOpenTooltip = null;
|
currentlyOpenTooltip.index === gameIndex &&
|
||||||
return;
|
currentlyOpenTooltip.element &&
|
||||||
}
|
currentlyOpenTooltip.element.style.display === "block"
|
||||||
|
) {
|
||||||
|
hideTooltip(currentlyOpenTooltip.element);
|
||||||
|
currentlyOpenTooltip = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 如果点击的是另一个游戏,先关闭之前打开的tooltip
|
// 如果点击的是另一个游戏,先关闭之前打开的tooltip
|
||||||
if (currentlyOpenTooltip) {
|
if (currentlyOpenTooltip) {
|
||||||
hideTooltip(currentlyOpenTooltip.element);
|
hideTooltip(currentlyOpenTooltip.element);
|
||||||
}
|
}
|
||||||
|
|
||||||
const detailId = `game-tooltip-${gameIndex}`;
|
const detailId = `game-tooltip-${gameIndex}`;
|
||||||
let tooltipDiv = document.getElementById(detailId);
|
let tooltipDiv = document.getElementById(detailId);
|
||||||
|
|
||||||
// 如果tooltip不存在,则创建它
|
// 如果tooltip不存在,则创建它
|
||||||
if (!tooltipDiv) {
|
if (!tooltipDiv) {
|
||||||
const detail = gameDetailData[gameIndex];
|
const detail = gameDetailData[gameIndex];
|
||||||
const currentLang = localStorage.getItem('preferred_language') || 'zh';
|
const currentLang = localStorage.getItem("preferred_language") || "zh";
|
||||||
|
|
||||||
const nameKey = `game_name_${gameIndex}`;
|
const nameKey = `game_name_${gameIndex}`;
|
||||||
const descKey = `game_desc_${gameIndex}`;
|
const descKey = `game_desc_${gameIndex}`;
|
||||||
const gameName = typeof translations !== 'undefined' && translations[currentLang] ? translations[currentLang][nameKey] || gamesData[gameIndex].name : gamesData[gameIndex].name;
|
const gameName =
|
||||||
// const gameDesc = typeof translations !== 'undefined' && translations[currentLang] ? translations[currentLang][descKey] || gamesData[gameIndex].desc : gamesData[gameIndex].desc;
|
typeof translations !== "undefined" && translations[currentLang]
|
||||||
// console.log("游戏名称:", gameDesc);
|
? translations[currentLang][nameKey] || gamesData[gameIndex].name
|
||||||
let tooltipContentHtml = '';
|
: gamesData[gameIndex].name;
|
||||||
if (detail) {
|
|
||||||
tooltipContentHtml = `
|
let tooltipContentHtml = "";
|
||||||
|
if (detail) {
|
||||||
|
tooltipContentHtml = `
|
||||||
<div class="tooltip-content">
|
<div class="tooltip-content">
|
||||||
<div class="tooltip-header">
|
<div class="tooltip-header">
|
||||||
<h4>${gameName}</h4>
|
<h4>${gameName}</h4>
|
||||||
@@ -78,16 +147,18 @@ function toggleGameDetailTooltip(gameElement, gameIndex) {
|
|||||||
<p><strong>${detail.id}</strong></p>
|
<p><strong>${detail.id}</strong></p>
|
||||||
<p> ${detail.rank}</p>
|
<p> ${detail.rank}</p>
|
||||||
<p><em>${detail.detailDesc}</em></p>
|
<p><em>${detail.detailDesc}</em></p>
|
||||||
${detail.images && detail.images.length > 0 ?
|
${
|
||||||
`<div class="tooltip-images">
|
detail.images && detail.images.length > 0
|
||||||
${detail.images.map(imgSrc => `<img src="${imgSrc}" alt="游戏详情图片" class="tooltip-image-item">`).join('')}
|
? `<div class="tooltip-images">
|
||||||
|
${detail.images.map((imgSrc) => `<img src="${imgSrc}" alt="游戏详情图片" class="tooltip-image-item">`).join("")}
|
||||||
</div>`
|
</div>`
|
||||||
: ''}
|
: ""
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
} else {
|
} else {
|
||||||
tooltipContentHtml = `
|
tooltipContentHtml = `
|
||||||
<div class="tooltip-content">
|
<div class="tooltip-content">
|
||||||
<div class="tooltip-header">
|
<div class="tooltip-header">
|
||||||
<h4>${gameName}</h4>
|
<h4>${gameName}</h4>
|
||||||
@@ -98,72 +169,75 @@ function toggleGameDetailTooltip(gameElement, gameIndex) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
|
||||||
|
|
||||||
tooltipDiv = document.createElement('div');
|
|
||||||
tooltipDiv.id = detailId;
|
|
||||||
tooltipDiv.className = 'game-detail-tooltip';
|
|
||||||
tooltipDiv.innerHTML = tooltipContentHtml;
|
|
||||||
|
|
||||||
// 添加关闭按钮事件
|
|
||||||
const closeBtn = tooltipDiv.querySelector('.tooltip-close');
|
|
||||||
closeBtn.addEventListener('click', (e) => {
|
|
||||||
e.stopPropagation(); // 防止触发外层的点击关闭
|
|
||||||
hideTooltip(tooltipDiv);
|
|
||||||
currentlyOpenTooltip = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 添加点击tooltip外部区域关闭的功能
|
|
||||||
tooltipDiv.addEventListener('click', (e) => {
|
|
||||||
// 只有点击tooltip自身(而非内部内容)才关闭
|
|
||||||
if (e.target === tooltipDiv) {
|
|
||||||
hideTooltip(tooltipDiv);
|
|
||||||
currentlyOpenTooltip = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.appendChild(tooltipDiv); // 将tooltip添加到body,实现悬浮效果
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 定位tooltip,让它出现在游戏项附近
|
tooltipDiv = document.createElement("div");
|
||||||
const rect = gameElement.getBoundingClientRect();
|
tooltipDiv.id = detailId;
|
||||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
tooltipDiv.className = "game-detail-tooltip";
|
||||||
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
|
tooltipDiv.innerHTML = tooltipContentHtml;
|
||||||
|
|
||||||
// 计算tooltip的位置 (例如,出现在游戏项下方)
|
// 添加关闭按钮事件
|
||||||
const top = rect.bottom + scrollTop + 10; // 10px 间隙
|
const closeBtn = tooltipDiv.querySelector(".tooltip-close");
|
||||||
const left = rect.left + scrollLeft; // 与游戏项左侧对齐
|
closeBtn.addEventListener("click", (e) => {
|
||||||
|
e.stopPropagation(); // 防止触发外层的点击关闭
|
||||||
|
hideTooltip(tooltipDiv);
|
||||||
|
currentlyOpenTooltip = null;
|
||||||
|
});
|
||||||
|
|
||||||
tooltipDiv.style.top = `${top}px`;
|
// 添加点击tooltip外部区域关闭的功能
|
||||||
tooltipDiv.style.left = `${left}px`;
|
tooltipDiv.addEventListener("click", (e) => {
|
||||||
tooltipDiv.style.display = 'block';
|
// 只有点击tooltip自身(而非内部内容)才关闭
|
||||||
|
if (e.target === tooltipDiv) {
|
||||||
|
hideTooltip(tooltipDiv);
|
||||||
|
currentlyOpenTooltip = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 记录当前打开的tooltip
|
document.body.appendChild(tooltipDiv); // 将tooltip添加到body,实现悬浮效果
|
||||||
currentlyOpenTooltip = { element: tooltipDiv, index: gameIndex };
|
}
|
||||||
|
|
||||||
// 阻止事件冒泡到document,避免立即被关闭
|
// 定位tooltip,让它出现在游戏项附近
|
||||||
tooltipDiv.onclick = function(e) {
|
const rect = gameElement.getBoundingClientRect();
|
||||||
e.stopPropagation();
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||||
};
|
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
|
||||||
|
|
||||||
|
// 计算tooltip的位置 (例如,出现在游戏项下方)
|
||||||
|
const top = rect.bottom + scrollTop + 10; // 10px 间隙
|
||||||
|
const left = rect.left + scrollLeft; // 与游戏项左侧对齐
|
||||||
|
|
||||||
|
tooltipDiv.style.top = `${top}px`;
|
||||||
|
tooltipDiv.style.left = `${left}px`;
|
||||||
|
tooltipDiv.style.display = "block";
|
||||||
|
|
||||||
|
// 记录当前打开的tooltip
|
||||||
|
currentlyOpenTooltip = { element: tooltipDiv, index: gameIndex };
|
||||||
|
|
||||||
|
// 阻止事件冒泡到document,避免立即被关闭
|
||||||
|
tooltipDiv.onclick = function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 隐藏Tooltip的辅助函数 ==========
|
// ========== 隐藏Tooltip的辅助函数 ==========
|
||||||
function hideTooltip(tooltipElement) {
|
function hideTooltip(tooltipElement) {
|
||||||
if (tooltipElement) {
|
if (tooltipElement) {
|
||||||
tooltipElement.style.display = 'none';
|
tooltipElement.style.display = "none";
|
||||||
// 如果想完全移除DOM,可以取消下面两行注释,但通常隐藏即可
|
// 如果想完全移除DOM,可以取消下面两行注释,但通常隐藏即可
|
||||||
// if (tooltipElement.parentNode) {
|
// if (tooltipElement.parentNode) {
|
||||||
// tooltipElement.parentNode.removeChild(tooltipElement);
|
// tooltipElement.parentNode.removeChild(tooltipElement);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 点击文档其他地方关闭Tooltip ==========
|
// ========== 点击文档其他地方关闭Tooltip ==========
|
||||||
document.addEventListener('click', function(event) {
|
document.addEventListener("click", function (event) {
|
||||||
if (currentlyOpenTooltip && !currentlyOpenTooltip.element.contains(event.target)) {
|
if (
|
||||||
hideTooltip(currentlyOpenTooltip.element);
|
currentlyOpenTooltip &&
|
||||||
currentlyOpenTooltip = null;
|
!currentlyOpenTooltip.element.contains(event.target)
|
||||||
}
|
) {
|
||||||
|
hideTooltip(currentlyOpenTooltip.element);
|
||||||
|
currentlyOpenTooltip = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// ========== 渲染游戏列表的函数 ==========
|
// ========== 渲染游戏列表的函数 ==========
|
||||||
@@ -180,14 +254,20 @@ function renderGames(gamesArray) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentLang = localStorage.getItem('preferred_language') || 'zh';
|
const currentLang = localStorage.getItem("preferred_language") || "zh";
|
||||||
|
|
||||||
let html = "";
|
let html = "";
|
||||||
gamesArray.forEach((game, index) => {
|
gamesArray.forEach((game, index) => {
|
||||||
const nameKey = `game_name_${index}`;
|
const nameKey = `game_name_${index}`;
|
||||||
const descKey = `game_desc_${index}`;
|
const descKey = `game_desc_${index}`;
|
||||||
const nameTranslation = typeof translations !== 'undefined' && translations[currentLang] ? translations[currentLang][nameKey] || game.name : game.name;
|
const nameTranslation =
|
||||||
const descTranslation = typeof translations !== 'undefined' && translations[currentLang] ? translations[currentLang][descKey] || game.desc : game.desc;
|
typeof translations !== "undefined" && translations[currentLang]
|
||||||
|
? translations[currentLang][nameKey] || game.name
|
||||||
|
: game.name;
|
||||||
|
const descTranslation =
|
||||||
|
typeof translations !== "undefined" && translations[currentLang]
|
||||||
|
? translations[currentLang][descKey] || game.desc
|
||||||
|
: game.desc;
|
||||||
|
|
||||||
// 为每个游戏项添加点击事件,并传递其索引
|
// 为每个游戏项添加点击事件,并传递其索引
|
||||||
html += `
|
html += `
|
||||||
@@ -201,17 +281,17 @@ function renderGames(gamesArray) {
|
|||||||
container.innerHTML = html;
|
container.innerHTML = html;
|
||||||
|
|
||||||
// 为每个生成的游戏项添加点击事件监听器
|
// 为每个生成的游戏项添加点击事件监听器
|
||||||
const gameItems = container.querySelectorAll('.game-item');
|
const gameItems = container.querySelectorAll(".game-item");
|
||||||
gameItems.forEach(item => {
|
gameItems.forEach((item) => {
|
||||||
item.addEventListener('click', function(event) {
|
item.addEventListener("click", function (event) {
|
||||||
event.stopPropagation(); // 阻止点击事件冒泡到document,避免立即关闭
|
event.stopPropagation(); // 阻止点击事件冒泡到document,避免立即关闭
|
||||||
const gameIndex = parseInt(this.getAttribute('data-game-index'));
|
const gameIndex = parseInt(this.getAttribute("data-game-index"));
|
||||||
toggleGameDetailTooltip(this, gameIndex);
|
toggleGameDetailTooltip(this, gameIndex);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 初始化 ==========
|
// ========== 初始化 ==========
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
renderGames(gamesData);
|
renderGames(gamesData);
|
||||||
});
|
});
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
const translationsEN = {
|
const translationsEN = {
|
||||||
|
'footprint_map_h2': '足迹',// 添加这个
|
||||||
'page_title': 'BaiTu - BAITU',
|
'page_title': 'BaiTu - BAITU',
|
||||||
'nav_about': 'About Me',
|
'nav_about': 'About Me',
|
||||||
'nav_website': 'My Websites',
|
'nav_website': 'My Websites',
|
||||||
'nav_tools': 'Tools',
|
'nav_tools': 'Tools',
|
||||||
'nav_games': 'Games',
|
'nav_games': 'Games',
|
||||||
|
'nav_footprint':'Footprints',
|
||||||
'nav_memos': 'Memos',
|
'nav_memos': 'Memos',
|
||||||
'nav_contact': 'Contact Me',
|
'nav_contact': 'Contact Me',
|
||||||
'hello': 'Hello',
|
'hello': 'Hello',
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const translationsZH = {
|
|||||||
'nav_website': '我的网站',
|
'nav_website': '我的网站',
|
||||||
'nav_tools': '常用工具',
|
'nav_tools': '常用工具',
|
||||||
'nav_games': '常玩游戏',
|
'nav_games': '常玩游戏',
|
||||||
|
'nav_footprint':'历史足迹',
|
||||||
'nav_memos': '闲言碎语',
|
'nav_memos': '闲言碎语',
|
||||||
'nav_contact': '联系我',
|
'nav_contact': '联系我',
|
||||||
'hello': '你好',
|
'hello': '你好',
|
||||||
@@ -54,21 +55,21 @@ const translationsZH = {
|
|||||||
'game_name_0': '《永劫无间》',
|
'game_name_0': '《永劫无间》',
|
||||||
'game_desc_0': '我身无拘,武道无穷',
|
'game_desc_0': '我身无拘,武道无穷',
|
||||||
'game_name_1': '《我的世界》',
|
'game_name_1': '《我的世界》',
|
||||||
'game_desc_1': '这个小盒才是我的永远的家',
|
'game_desc_1': '这个小盒才是我的永远的家。',
|
||||||
'game_name_2': '《鬼谷八荒》',
|
'game_name_2': '《鬼谷八荒》',
|
||||||
'game_desc_2': '当互动版的修仙小说看了,很好玩.',
|
'game_desc_2': '立绘无敌,剧情无敌,非常不错的修仙游戏!',
|
||||||
'game_name_3': '《江城创业记》',
|
'game_name_3': '《江城创业记》',
|
||||||
'game_desc_3': '缝合怪,但是全缝了。很喜欢的一款游戏',
|
'game_desc_3': '自动化、闯关、结婚总有一款方式适合你。',
|
||||||
'game_name_4': '《中国式家长》',
|
'game_name_4': '《中国式家长》',
|
||||||
'game_desc_4': '我承认我做不好一个孩子,也做不好一个家长',
|
'game_desc_4': '我承认我做不好一个孩子,也做不好一个家长。',
|
||||||
'game_name_5': '《王者荣耀》',
|
'game_name_5': '《王者荣耀》',
|
||||||
'game_desc_5': '买了好多皮肤,和朋友玩才是真快乐(已退坑)',
|
'game_desc_5': '和朋友玩才是真快乐,一个人的王者,一群人的荣耀(已退坑)',
|
||||||
'game_name_6': '《QQ飞车手游》',
|
'game_name_6': '《QQ飞车手游》',
|
||||||
'game_desc_6': '氪了好多,有些后悔了(已退坑)',
|
'game_desc_6': '一辆天行者陪我从大学跑到工作(已退坑)',
|
||||||
'game_name_7': '《龙族幻想》',
|
'game_name_7': '《龙族幻想》',
|
||||||
'game_desc_7': '因为龙族入坑的,江南老贼!(已退坑)',
|
'game_desc_7': '因为龙族入坑的,只能说剧情还不错!(已退坑)',
|
||||||
'game_name_8': '《洛克王国》',
|
'game_name_8': '《洛克王国》',
|
||||||
'game_desc_8': '还记得小时候拿压岁钱偷偷买点卡(已退坑)',
|
'game_desc_8': '还记得小时候拿压岁钱偷偷买点卡,可惜号被盗了(已退坑)',
|
||||||
'game_name_9': '《造梦西游》',
|
'game_name_9': '《造梦西游》',
|
||||||
'game_desc_9': '造梦3从小学玩到大学,现在还时不时的回味一下(已退坑)',
|
'game_desc_9': '造梦3从小学玩到大学,现在还时不时的回味一下(已退坑)',
|
||||||
|
|
||||||
|
|||||||
229
static/js/map-footprint.js
Normal file
229
static/js/map-footprint.js
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
// ./static/js/map-footprint.js
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ECharts 地图足迹模块 (使用本地 GeoJSON)
|
||||||
|
*/
|
||||||
|
const MapFootprintModule = (() => {
|
||||||
|
let myChart = null; // ECharts 实例
|
||||||
|
const MAP_NAME = 'china_custom'; // 为自定义地图起一个名字
|
||||||
|
|
||||||
|
const visitedPlaces = [
|
||||||
|
{ name: "济南市", value: [117.024961, 36.682788] },
|
||||||
|
{ name: "青岛市", value: [120.384423, 36.065918] },
|
||||||
|
{ name: "淄博市", value: [118.055915, 36.813547] },
|
||||||
|
{ name: "潍坊市", value: [119.162775, 36.705759] },
|
||||||
|
{ name: "北京市", value: [116.407395, 39.904211] },
|
||||||
|
{ name: "杭州市", value: [120.153576, 30.287459] },
|
||||||
|
{ name: "苏州市", value: [120.585316, 31.298886] },
|
||||||
|
{ name: "扬州市", value: [119.421003, 32.393159] },
|
||||||
|
{ name: "保定市", value: [115.482331, 38.867657] },
|
||||||
|
{ name: "石家庄市", value: [114.514891, 38.042309] },
|
||||||
|
{ name: "衡水市", value: [115.665996, 37.739574] },
|
||||||
|
{ name: "洛阳市", value: [112.454174, 34.618139] },
|
||||||
|
{ name: "南京市", value: [118.796877, 32.060255] },
|
||||||
|
{ name: "无锡市", value: [120.311987, 31.490920] },
|
||||||
|
{ name: "沧州市", value: [116.838581, 38.308094] },
|
||||||
|
{ name: "镇江市", value: [119.452753, 32.204402] },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载 GeoJSON 地图数据并注册
|
||||||
|
*/
|
||||||
|
const loadAndRegisterMap = async () => {
|
||||||
|
try {
|
||||||
|
// console.log('开始加载 GeoJSON 地图数据...');
|
||||||
|
const response = await fetch('./static/js/echarts/china.geojson'); // 确保路径正确
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`加载 GeoJSON 失败: ${response.status} ${response.statusText}`);
|
||||||
|
}
|
||||||
|
const geoJsonData = await response.json();
|
||||||
|
|
||||||
|
// 注册自定义地图
|
||||||
|
echarts.registerMap(MAP_NAME, geoJsonData);
|
||||||
|
// console.log('GeoJSON 地图数据加载并注册成功。');
|
||||||
|
|
||||||
|
// 地图注册成功后,初始化图表
|
||||||
|
const container = document.getElementById(getMapContainerId());
|
||||||
|
if (container) {
|
||||||
|
initEChartsMap(container);
|
||||||
|
} else {
|
||||||
|
console.error('地图容器 DOM 元素未找到,无法初始化图表。');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载或注册 GeoJSON 地图时出错:', error);
|
||||||
|
// 可以选择在内容区域显示错误信息
|
||||||
|
const contentDiv = document.getElementById('footprint-content'); // 假设足迹内容区域ID是这个
|
||||||
|
if (contentDiv) {
|
||||||
|
contentDiv.innerHTML = '<p>加载地图数据失败,请检查网络连接或稍后重试。</p>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化 ECharts 地图
|
||||||
|
* @param {HTMLElement} container - 图表容器DOM元素
|
||||||
|
*/
|
||||||
|
const initEChartsMap = (container) => {
|
||||||
|
if (!container) {
|
||||||
|
console.error('地图容器未找到');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化 ECharts 实例
|
||||||
|
myChart = echarts.init(container);
|
||||||
|
|
||||||
|
// ECharts 配置项 (使用注册的地图名称)
|
||||||
|
const option = {
|
||||||
|
title: {
|
||||||
|
text: '',
|
||||||
|
subtext: '读万卷书,不如行万里路。见多才会识广~',
|
||||||
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 18
|
||||||
|
},
|
||||||
|
subtextStyle: {
|
||||||
|
fontSize: 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
formatter: function(params) {
|
||||||
|
if (params.value && params.value.length >= 2) {
|
||||||
|
return params.name + '<br/>经度: ' + params.value[0].toFixed(4) + '<br/>纬度: ' + params.value[1].toFixed(4);
|
||||||
|
}
|
||||||
|
return params.name; // 如果没有坐标信息,只显示地名
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toolbox: {
|
||||||
|
show: false,
|
||||||
|
orient: 'vertical',
|
||||||
|
left: 'right',
|
||||||
|
top: 'center',
|
||||||
|
feature: {
|
||||||
|
dataView: { readOnly: false },
|
||||||
|
restore: {},
|
||||||
|
saveAsImage: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
visualMap: {
|
||||||
|
show: false, // 是否显示 visualMap 组件,这里设为 false,因为我们用 symbolSize 控制点大小
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
left: 'left',
|
||||||
|
top: 'bottom',
|
||||||
|
text: ['High', 'Low'], // 文本,默认为数值文本
|
||||||
|
calculable: true
|
||||||
|
},
|
||||||
|
geo: {
|
||||||
|
map: MAP_NAME, // 使用注册的自定义地图名称
|
||||||
|
roam: false, // 是否开启鼠标缩放和平移漫游
|
||||||
|
zoom: 1.1, // 当前视角的缩放比例
|
||||||
|
center: [104.06, 30],
|
||||||
|
emphasis: { // 高亮状态下的样式
|
||||||
|
itemStyle: {
|
||||||
|
areaColor: '#f0f0f0', // 高亮时省份的颜色
|
||||||
|
borderColor: '#409EFF', // 高亮时省份的边框颜色
|
||||||
|
borderWidth: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: { // 普通状态下的样式
|
||||||
|
areaColor: '#eef2ff', // 未选中时省份的颜色
|
||||||
|
borderColor: '#333' // 未选中时省份的边框颜色
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '足迹',
|
||||||
|
type: 'scatter', // 使用散点图表示标记点
|
||||||
|
coordinateSystem: 'geo', // 指定坐标系为地理坐标系
|
||||||
|
data: visitedPlaces, // 使用我们的数据
|
||||||
|
symbol: 'pin', // 使用内置符号 'pin'
|
||||||
|
symbolSize: 18, // 标记点的大小
|
||||||
|
itemStyle: { // 普通状态下的样式
|
||||||
|
color: '#FF6B6B', // 设置图标颜色
|
||||||
|
borderColor: '#fff', // 设置图标边框颜色
|
||||||
|
borderWidth: 1, // 设置图标边框宽度
|
||||||
|
},
|
||||||
|
emphasis: { // 高亮状态
|
||||||
|
itemStyle: {
|
||||||
|
color: '#dd4444' // 高亮时点的颜色
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
formatter: function(params) {
|
||||||
|
// 这里可以更精细地控制 tooltip 内容
|
||||||
|
return ` ${params.data.name}<br/>坐标: [ ${params.data.value[0].toFixed(4)}, ${params.data.value[1].toFixed(4)}]`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置配置项并渲染图表
|
||||||
|
myChart.setOption(option);
|
||||||
|
|
||||||
|
// 监听窗口大小变化,自动适配
|
||||||
|
window.addEventListener('resize', function () {
|
||||||
|
if (myChart) {
|
||||||
|
myChart.resize();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取地图容器ID
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
const getMapContainerId = () => {
|
||||||
|
return 'echarts-map-container'; // 定义一个唯一的ID
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染 ECharts 地图内容到指定容器
|
||||||
|
* @param {HTMLElement} contentDiv - 标签页的内容容器
|
||||||
|
*/
|
||||||
|
const renderMap = (contentDiv) => {
|
||||||
|
// 清空内容区域
|
||||||
|
contentDiv.innerHTML = '';
|
||||||
|
|
||||||
|
// 创建标题
|
||||||
|
const titleElement = document.createElement('h2');
|
||||||
|
titleElement.setAttribute('data-i18n', 'footprint_map_h2'); // 假设你在语言文件中有这个键
|
||||||
|
titleElement.textContent = '历史足迹'; // 默认文本
|
||||||
|
contentDiv.appendChild(titleElement);
|
||||||
|
|
||||||
|
// 创建地图容器
|
||||||
|
const mapDiv = document.createElement('div');
|
||||||
|
mapDiv.id = getMapContainerId();
|
||||||
|
mapDiv.style.width = '100%';
|
||||||
|
mapDiv.style.height = '600px'; // 设置地图高度,可以根据需要调整
|
||||||
|
mapDiv.style.marginTop = '20px'; // 可选:添加上边距
|
||||||
|
|
||||||
|
contentDiv.appendChild(mapDiv);
|
||||||
|
|
||||||
|
// 加载 GeoJSON 并初始化地图
|
||||||
|
// 使用 setTimeout 确保 DOM 元素已渲染后再加载地图数据
|
||||||
|
setTimeout(() => {
|
||||||
|
loadAndRegisterMap();
|
||||||
|
}, 100); // 延迟一点确保渲染完成
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销毁 ECharts 实例 (可选,用于性能优化或切换时清理)
|
||||||
|
*/
|
||||||
|
const destroyMap = () => {
|
||||||
|
if (myChart) {
|
||||||
|
myChart.dispose(); // 销毁实例,释放资源
|
||||||
|
myChart = null;
|
||||||
|
console.log('ECharts 地图已销毁');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 返回公共方法
|
||||||
|
return {
|
||||||
|
renderMap,
|
||||||
|
destroyMap // 导出销毁方法,如果需要的话
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -12,7 +12,6 @@
|
|||||||
// 获取 DOM 元素
|
// 获取 DOM 元素
|
||||||
const memosTab = document.querySelector('.nav-tab[data-tab="memos"]');
|
const memosTab = document.querySelector('.nav-tab[data-tab="memos"]');
|
||||||
const memosContainer = document.getElementById("memos-container");
|
const memosContainer = document.getElementById("memos-container");
|
||||||
const memosContent = document.getElementById("memos-content");
|
|
||||||
|
|
||||||
// 日期格式化函数 (简单实现)
|
// 日期格式化函数 (简单实现)
|
||||||
function formatDate(dateStr) {
|
function formatDate(dateStr) {
|
||||||
|
|||||||
@@ -1,60 +1,105 @@
|
|||||||
// ==================== 标签切换功能 ====================
|
// ==================== 标签切换功能 ====================
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
const tabs = document.querySelectorAll('.nav-tab');
|
const tabs = document.querySelectorAll(".nav-tab");
|
||||||
const contents = document.querySelectorAll('.tab-content');
|
const contents = document.querySelectorAll(".tab-content");
|
||||||
tabs.forEach(tab => {
|
tabs.forEach((tab) => {
|
||||||
tab.addEventListener('click', function () {
|
tab.addEventListener("click", function () {
|
||||||
const tabId = this.getAttribute('data-tab');
|
const tabId = this.getAttribute("data-tab");
|
||||||
// 移除所有激活状态
|
// 在切换之前,如果当前是足迹页且地图已存在,销毁旧地图实例 (ECharts 版本)
|
||||||
tabs.forEach(t => t.classList.remove('active'));
|
const currentActiveTab = document.querySelector(".nav-tab.active");
|
||||||
contents.forEach(c => c.classList.remove('active'));
|
if (
|
||||||
// 添加当前激活状态
|
currentActiveTab &&
|
||||||
this.classList.add('active');
|
currentActiveTab.getAttribute("data-tab") === "footprint" &&
|
||||||
document.getElementById(`${tabId}-content`).classList.add('active');
|
typeof MapFootprintModule !== "undefined"
|
||||||
});
|
) {
|
||||||
});
|
MapFootprintModule.destroyMap(); // 销毁之前的 ECharts 实例
|
||||||
|
console.log("切换标签前已销毁旧地图实例");
|
||||||
|
}
|
||||||
|
|
||||||
const websiteTab = document.querySelector('.nav-tab[data-tab="website"]');
|
// 移除所有激活状态
|
||||||
const websiteContent = document.getElementById('website-content');
|
tabs.forEach((t) => t.classList.remove("active"));
|
||||||
if (websiteTab && websiteContent) {
|
contents.forEach((c) => c.classList.remove("active"));
|
||||||
websiteTab.addEventListener('click', function () {
|
// 添加当前激活状态
|
||||||
const hasRendered = websiteContent.querySelector('.category-links') !== null;
|
this.classList.add("active");
|
||||||
if (!hasRendered) {
|
document.getElementById(`${tabId}-content`).classList.add("active");
|
||||||
const savedLang = localStorage.getItem(LANG_KEY) || 'zh';
|
});
|
||||||
renderWebsites(websitesData, translations, savedLang);
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.warn("未找到“我的网站”标签或内容区域。");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 点击我的工具函数
|
const websiteTab = document.querySelector('.nav-tab[data-tab="website"]');
|
||||||
const toolsTab = document.querySelector('.nav-tab[data-tab="tools"]');
|
const websiteContent = document.getElementById("website-content");
|
||||||
const toolsContent = document.getElementById('tools-content');
|
if (websiteTab && websiteContent) {
|
||||||
if (toolsTab && toolsContent) {
|
websiteTab.addEventListener("click", function () {
|
||||||
toolsTab.addEventListener('click', function () {
|
const hasRendered =
|
||||||
const hasRendered = toolsContent.querySelector('.tool-item') !== null;
|
websiteContent.querySelector(".category-links") !== null;
|
||||||
if (!hasRendered) {
|
if (!hasRendered) {
|
||||||
renderTools(toolsData);
|
const savedLang = localStorage.getItem(LANG_KEY) || "zh";
|
||||||
}
|
renderWebsites(websitesData, translations, savedLang);
|
||||||
});
|
}
|
||||||
} else {
|
});
|
||||||
console.warn("未找到“我的工具”标签或内容区域,将在页面加载时尝试渲染。");
|
} else {
|
||||||
renderTools(toolsData);
|
console.warn("未找到“我的网站”标签或内容区域。");
|
||||||
}
|
}
|
||||||
// 点击常玩游戏函数
|
|
||||||
const gamesTab = document.querySelector('.nav-tab[data-tab="games"]');
|
|
||||||
const gamesContent = document.getElementById('games-content');
|
|
||||||
if (gamesTab && gamesContent) {
|
|
||||||
gamesTab.addEventListener('click', function () {
|
|
||||||
const hasRendered = gamesContent.querySelector('.game-item') !== null;
|
|
||||||
if (!hasRendered) {
|
|
||||||
renderGames(gamesData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.warn("未找到“常玩游戏”标签或内容区域。");
|
|
||||||
renderGames(gamesData);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
// 点击我的工具函数
|
||||||
|
const toolsTab = document.querySelector('.nav-tab[data-tab="tools"]');
|
||||||
|
const toolsContent = document.getElementById("tools-content");
|
||||||
|
if (toolsTab && toolsContent) {
|
||||||
|
toolsTab.addEventListener("click", function () {
|
||||||
|
const hasRendered = toolsContent.querySelector(".tool-item") !== null;
|
||||||
|
if (!hasRendered) {
|
||||||
|
renderTools(toolsData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn("未找到“我的工具”标签或内容区域,将在页面加载时尝试渲染。");
|
||||||
|
renderTools(toolsData);
|
||||||
|
}
|
||||||
|
// 点击常玩游戏函数
|
||||||
|
const gamesTab = document.querySelector('.nav-tab[data-tab="games"]');
|
||||||
|
const gamesContent = document.getElementById("games-content");
|
||||||
|
if (gamesTab && gamesContent) {
|
||||||
|
gamesTab.addEventListener("click", function () {
|
||||||
|
const hasRendered = gamesContent.querySelector(".game-item") !== null;
|
||||||
|
if (!hasRendered) {
|
||||||
|
renderGames(gamesData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn("未找到“常玩游戏”标签或内容区域。");
|
||||||
|
renderGames(gamesData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击足迹函数 (新增)
|
||||||
|
const footprintTab = document.querySelector('.nav-tab[data-tab="footprint"]');
|
||||||
|
const footprintContent = document.getElementById("footprint-content");
|
||||||
|
if (footprintTab && footprintContent) {
|
||||||
|
footprintTab.addEventListener("click", function () {
|
||||||
|
// 如果 MapFootprintModule 已加载(即 map-footprint.js 已成功执行)
|
||||||
|
if (typeof MapFootprintModule !== "undefined") {
|
||||||
|
// 调用模块中的 renderMap 函数来渲染地图
|
||||||
|
MapFootprintModule.renderMap(footprintContent);
|
||||||
|
} else {
|
||||||
|
// 如果模块未定义,说明 map-footprint.js 可能未加载或加载失败
|
||||||
|
console.error(
|
||||||
|
"MapFootprintModule 未定义,请确保 map-footprint.js 已正确加载且在 tabchange.js 之前。",
|
||||||
|
);
|
||||||
|
// 可以选择显示错误信息给用户
|
||||||
|
footprintContent.innerHTML =
|
||||||
|
'<p data-i18n="error_loading_map">加载地图失败,请刷新页面重试。</p>';
|
||||||
|
// 如果需要更新国际化文本,可以在这里处理
|
||||||
|
if (typeof translations !== "undefined") {
|
||||||
|
const errorElement = footprintContent.querySelector(
|
||||||
|
'[data-i18n="error_loading_map"]',
|
||||||
|
);
|
||||||
|
if (errorElement) {
|
||||||
|
const savedLang = localStorage.getItem(LANG_KEY) || "zh";
|
||||||
|
const translation = translations[savedLang]["error_loading_map"];
|
||||||
|
if (translation) errorElement.textContent = translation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn("未找到“足迹”标签或内容区域。");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
60
static/js/tabchange.js.bak
Normal file
60
static/js/tabchange.js.bak
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
// ==================== 标签切换功能 ====================
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const tabs = document.querySelectorAll(".nav-tab");
|
||||||
|
const contents = document.querySelectorAll(".tab-content");
|
||||||
|
tabs.forEach((tab) => {
|
||||||
|
tab.addEventListener("click", function () {
|
||||||
|
const tabId = this.getAttribute("data-tab");
|
||||||
|
// 移除所有激活状态
|
||||||
|
tabs.forEach((t) => t.classList.remove("active"));
|
||||||
|
contents.forEach((c) => c.classList.remove("active"));
|
||||||
|
// 添加当前激活状态
|
||||||
|
this.classList.add("active");
|
||||||
|
document.getElementById(`${tabId}-content`).classList.add("active");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const websiteTab = document.querySelector('.nav-tab[data-tab="website"]');
|
||||||
|
const websiteContent = document.getElementById("website-content");
|
||||||
|
if (websiteTab && websiteContent) {
|
||||||
|
websiteTab.addEventListener("click", function () {
|
||||||
|
const hasRendered =
|
||||||
|
websiteContent.querySelector(".category-links") !== null;
|
||||||
|
if (!hasRendered) {
|
||||||
|
const savedLang = localStorage.getItem(LANG_KEY) || "zh";
|
||||||
|
renderWebsites(websitesData, translations, savedLang);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn("未找到“我的网站”标签或内容区域。");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击我的工具函数
|
||||||
|
const toolsTab = document.querySelector('.nav-tab[data-tab="tools"]');
|
||||||
|
const toolsContent = document.getElementById("tools-content");
|
||||||
|
if (toolsTab && toolsContent) {
|
||||||
|
toolsTab.addEventListener("click", function () {
|
||||||
|
const hasRendered = toolsContent.querySelector(".tool-item") !== null;
|
||||||
|
if (!hasRendered) {
|
||||||
|
renderTools(toolsData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn("未找到“我的工具”标签或内容区域,将在页面加载时尝试渲染。");
|
||||||
|
renderTools(toolsData);
|
||||||
|
}
|
||||||
|
// 点击常玩游戏函数
|
||||||
|
const gamesTab = document.querySelector('.nav-tab[data-tab="games"]');
|
||||||
|
const gamesContent = document.getElementById("games-content");
|
||||||
|
if (gamesTab && gamesContent) {
|
||||||
|
gamesTab.addEventListener("click", function () {
|
||||||
|
const hasRendered = gamesContent.querySelector(".game-item") !== null;
|
||||||
|
if (!hasRendered) {
|
||||||
|
renderGames(gamesData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn("未找到“常玩游戏”标签或内容区域。");
|
||||||
|
renderGames(gamesData);
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user