jianzhihuixiang/alacarte-novel-website/chapters/chapter-108.html

975 lines
41 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>瘟疫之源 - 阿拉德:剑之回响</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-primary: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%);
--text-primary: #e0e0e0;
--text-secondary: #888;
--accent-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
--border-color: rgba(255,255,255,0.1);
--btn-bg: rgba(255,255,255,0.1);
--btn-hover: rgba(255,255,255,0.2);
}
[data-theme="light"] {
--bg-primary: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
--text-primary: #333;
--text-secondary: #666;
--border-color: rgba(0,0,0,0.1);
--btn-bg: rgba(0,0,0,0.05);
--btn-hover: rgba(0,0,0,0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Noto Serif SC', serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.8;
min-height: 100vh;
transition: all 0.3s ease;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
padding-bottom: 120px;
}
/* 顶部导航 */
.top-nav {
position: fixed;
top: 0;
left: 0;
right: 0;
background: rgba(0,0,0,0.3);
backdrop-filter: blur(10px);
border-bottom: 1px solid var(--border-color);
z-index: 1000;
padding: 10px 20px;
}
.top-nav-content {
max-width: 800px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-link {
color: var(--text-primary);
text-decoration: none;
font-family: 'Noto Sans SC', sans-serif;
font-size: 14px;
padding: 8px 16px;
background: var(--btn-bg);
border: 1px solid var(--border-color);
border-radius: 8px;
transition: all 0.3s ease;
}
.nav-link:hover {
background: var(--btn-hover);
}
.chapter-header {
text-align: center;
padding: 80px 0 40px;
border-bottom: 1px solid var(--border-color);
margin-bottom: 40px;
}
.chapter-number {
font-size: 14px;
color: var(--text-secondary);
letter-spacing: 4px;
text-transform: uppercase;
margin-bottom: 10px;
}
.chapter-title {
font-size: 32px;
font-weight: 700;
background: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 20px;
}
.chapter-meta {
font-size: 14px;
color: var(--text-secondary);
}
.chapter-content {
font-size: 18px;
line-height: 2;
text-align: justify;
}
.chapter-content p {
margin-bottom: 1.5em;
text-indent: 2em;
}
.chapter-content p:first-of-type::first-letter {
font-size: 3em;
float: left;
line-height: 1;
margin-right: 8px;
margin-top: -5px;
background: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-weight: 700;
}
/* 固定底部导航 */
.fixed-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: rgba(0,0,0,0.3);
backdrop-filter: blur(10px);
border-top: 1px solid var(--border-color);
z-index: 1000;
padding: 15px 20px;
}
.fixed-nav-content {
max-width: 800px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-btn {
padding: 12px 24px;
background: var(--btn-bg);
border: 1px solid var(--border-color);
border-radius: 8px;
color: var(--text-primary);
text-decoration: none;
transition: all 0.3s ease;
font-family: 'Noto Sans SC', sans-serif;
font-size: 14px;
cursor: pointer;
}
.nav-btn:hover {
background: var(--btn-hover);
transform: translateY(-2px);
}
.nav-btn.disabled {
opacity: 0.3;
cursor: not-allowed;
pointer-events: none;
}
.nav-btn.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-color: #667eea;
}
/* 右侧滚动按钮 */
.scroll-buttons {
position: fixed;
right: 20px;
bottom: 90px;
display: flex;
flex-direction: column;
gap: 10px;
z-index: 1001;
}
.scroll-btn {
width: 40px;
height: 40px;
border-radius: 8px;
background: var(--btn-bg);
border: 1px solid var(--border-color);
color: var(--text-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
transition: all 0.3s ease;
font-family: 'Noto Sans SC', sans-serif;
}
.scroll-btn:hover {
background: var(--btn-hover);
}
/* TTS弹出面板 */
.tts-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
z-index: 2000;
display: none;
align-items: center;
justify-content: center;
}
.tts-overlay.show {
display: flex;
}
.tts-panel {
background: rgba(30,30,50,0.95);
backdrop-filter: blur(10px);
border-radius: 16px;
border: 1px solid var(--border-color);
padding: 24px;
width: 90%;
max-width: 400px;
box-shadow: 0 10px 40px rgba(0,0,0,0.3);
}
[data-theme="light"] .tts-panel {
background: rgba(255,255,255,0.95);
}
.tts-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid var(--border-color);
}
.tts-title {
font-size: 18px;
font-weight: 600;
color: var(--text-primary);
font-family: 'Noto Sans SC', sans-serif;
}
.tts-close {
width: 32px;
height: 32px;
border-radius: 50%;
background: var(--btn-bg);
border: 1px solid var(--border-color);
color: var(--text-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
transition: all 0.3s ease;
}
.tts-close:hover {
background: var(--btn-hover);
}
.tts-controls {
display: flex;
justify-content: center;
gap: 16px;
margin-bottom: 20px;
}
.tts-btn {
width: 56px;
height: 56px;
border-radius: 50%;
background: var(--btn-bg);
border: 2px solid var(--border-color);
color: var(--text-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
transition: all 0.3s ease;
font-family: 'Noto Sans SC', sans-serif;
}
.tts-btn:hover {
background: var(--btn-hover);
transform: scale(1.1);
}
.tts-btn.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-color: #667eea;
transform: scale(1.1);
}
.tts-progress {
margin-bottom: 20px;
}
.tts-progress-bar {
height: 6px;
background: var(--btn-bg);
border-radius: 3px;
overflow: hidden;
margin-bottom: 8px;
}
.tts-progress-fill {
height: 100%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
width: 0%;
transition: width 0.1s ease;
}
.tts-time {
font-size: 13px;
color: var(--text-secondary);
font-family: 'Noto Sans SC', sans-serif;
text-align: center;
}
.tts-speed {
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
}
.tts-speed-label {
font-size: 14px;
color: var(--text-secondary);
font-family: 'Noto Sans SC', sans-serif;
}
.tts-speed-select {
padding: 8px 16px;
background: var(--btn-bg);
border: 1px solid var(--border-color);
border-radius: 8px;
color: var(--text-primary);
font-size: 14px;
cursor: pointer;
font-family: 'Noto Sans SC', sans-serif;
}
/* 侧边栏 - 标题固定,内容滚动 */
.sidebar {
position: fixed;
right: 20px;
top: 50%;
transform: translateY(-50%);
background: rgba(0,0,0,0.5);
backdrop-filter: blur(10px);
border-radius: 12px;
border: 1px solid var(--border-color);
width: 200px;
max-height: 70vh;
z-index: 999;
display: flex;
flex-direction: column;
}
.sidebar-title {
font-size: 14px;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 2px;
padding: 15px 20px;
border-bottom: 1px solid var(--border-color);
flex-shrink: 0;
}
.sidebar-content {
overflow-y: auto;
padding: 10px 20px 20px;
flex: 1;
scrollbar-width: thin;
scrollbar-color: transparent transparent;
transition: scrollbar-color 0.3s ease;
}
.sidebar-content:hover {
scrollbar-color: rgba(255,255,255,0.3) transparent;
}
.sidebar-content::-webkit-scrollbar {
width: 6px;
}
.sidebar-content::-webkit-scrollbar-track {
background: transparent;
}
.sidebar-content::-webkit-scrollbar-thumb {
background: transparent;
border-radius: 3px;
transition: background 0.3s ease;
}
.sidebar-content:hover::-webkit-scrollbar-thumb {
background: rgba(255,255,255,0.3);
}
.sidebar-content:hover::-webkit-scrollbar-thumb:hover {
background: rgba(255,255,255,0.5);
}
[data-theme="light"] .sidebar-content:hover {
scrollbar-color: rgba(0,0,0,0.3) transparent;
}
[data-theme="light"] .sidebar-content:hover::-webkit-scrollbar-thumb {
background: rgba(0,0,0,0.3);
}
[data-theme="light"] .sidebar-content:hover::-webkit-scrollbar-thumb:hover {
background: rgba(0,0,0,0.5);
}
.sidebar-chapter {
display: block;
padding: 8px 0;
color: #aaa;
text-decoration: none;
font-size: 13px;
border-bottom: 1px solid rgba(255,255,255,0.05);
transition: all 0.3s ease;
line-height: 1.5;
}
.sidebar-chapter:hover {
color: #667eea;
}
.sidebar-chapter.current {
color: #667eea;
font-weight: 600;
}
@media (max-width: 1200px) {
.sidebar {
display: none;
}
}
@media (max-width: 600px) {
.chapter-title {
font-size: 24px;
}
.chapter-content {
font-size: 16px;
}
.fixed-nav-content {
gap: 8px;
}
.nav-btn {
padding: 10px 12px;
font-size: 12px;
}
.scroll-buttons {
display: none;
}
.tts-panel {
padding: 20px;
width: 95%;
}
.tts-btn {
width: 48px;
height: 48px;
font-size: 18px;
}
.tts-title {
font-size: 16px;
}
}
/* 滚动条样式 */
.sidebar::-webkit-scrollbar {
width: 4px;
}
.sidebar::-webkit-scrollbar-track {
background: transparent;
}
.sidebar::-webkit-scrollbar-thumb {
background: rgba(255,255,255,0.2);
border-radius: 2px;
}
</style>
</head>
<body>
<!-- 顶部导航 -->
<nav class="top-nav">
<div class="top-nav-content">
<a href="../index.html" class="nav-link">返回首页</a>
<button class="nav-link" id="themeToggle">切换主题</button>
</div>
</nav>
<div class="container">
<header class="chapter-header">
<div class="chapter-number">Chapter 108</div>
<h1 class="chapter-title">{{CHAPTER_TITLE}}</h1>
</header>
<article class="chapter-content">
<p>三天后,林克再次来到时空之门前。</p>
<p>这三天里他和赛丽亚度过了难得的宁静时光。他们一起看日出日落一起在艾尔文防线的街道上散步一起回忆500年前的那场相遇。</p>
<p>但林克知道,他不能一直停留在这里。赫尔德的阴谋还在继续,时空之门中还有更多的真相等待揭开。</p>
<p>"一定要去吗?"赛丽亚站在时空之门前,眼中满是不舍。</p>
<p>"是的。"林克握住她的手,"瘟疫之源、暗黑圣战、昔日悲鸣...还有很多地方等着我去。只有揭开全部真相,才能真正阻止赫尔德。"</p>
<p>赛丽亚轻轻点头:"我明白。我会在这里等你回来。"</p>
<p>"等我。"林克在她额头上轻轻一吻,"这次不会再让你等500年了。"</p>
<p>赛丽亚笑了,眼泪却在眼眶中打转:"快去吧,别让命运等太久。"</p>
<p>林克转身,踏入时空之门。</p>
<p style="text-align: center; color: var(--text-secondary); text-indent: 0;">···</p>
<p>金色的光芒闪烁,林克感到身体被时空之力牵引,穿越到了另一个时间点。</p>
<p>当他睁开眼睛时,眼前的景象让他心中一沉。</p>
<p>这里曾经是一个宁静的村庄——低矮的石屋错落有致,街道两旁种着暗精灵特有的紫罗兰。但此刻,整个村庄笼罩在一层黑色的雾气中,空气中弥漫着腐臭和死亡的气息。</p>
<p>街道上,曾经繁华的市集如今一片狼藉。摊位翻倒,货物散落,还有一些...尸体。</p>
<p>不,不是尸体。</p>
<p>那些东西在动。</p>
<p>"这就是...诺伊佩拉?"林克握紧了细雪之舞,冰属性的光剑在这种环境下显得格外清冷。</p>
<p>他记得这个地方。在未来的时间线里,诺伊佩拉因为瘟疫而变成了死城,暗精灵王国不得不封锁这片区域。而现在,他正站在瘟疫爆发的原点。</p>
<p style="text-align: center; color: var(--text-secondary); text-indent: 0;">···</p>
<p>"救...救命..."</p>
<p>微弱的声音从废墟中传来。林克循声走去,在一座倒塌的石屋下,发现了一个还活着的暗精灵。</p>
<p>那是一个身穿民兵制服的暗精灵男子,他的脸色苍白,身上有多处被感染的痕迹,黑色的纹路在皮肤下蔓延。但他的眼神依然清醒,手中紧紧握着一把短剑。</p>
<p>"你是谁?"暗精灵警惕地看着林克。</p>
<p>"路过的剑士。"林克蹲下身,"这里发生了什么?"</p>
<p>暗精灵苦笑一声:"瘟疫...一夜之间,整个村庄都毁了。我叫贺加斯,是这里的民兵队长。"</p>
<p>他艰难地坐起身,指向村庄中央:"昨天夜里,一个身穿黑色斗篷的神秘人出现在村子里。他...他在水源里投放了什么东西。然后,天就亮了,瘟疫爆发了。"</p>
<p>"黑色斗篷?"林克心中一凛。在格兰之火,他也遇到了那个黑袍人。</p>
<p>"那个人...不是普通人。"贺加斯的声音颤抖,"他使用的是某种邪恶的魔法,我从未见过。村民们...有的当场死亡,有的变成了那种怪物..."</p>
<p>他指向街道尽头,那里有几个身影在游荡——那是被瘟疫感染的盗尸者,它们的身体扭曲变形,眼中闪烁着疯狂的光芒。</p>
<p>"求求你..."贺加斯抓住林克的手,"我知道我活不了多久了,但请你...阻止那个黑斗篷。他还在村子里,他在进行某种仪式...救救我的族人..."</p>
<p>林克看着这个濒临死亡的民兵队长,郑重地点头:"我答应你。"</p>
<p style="text-align: center; color: var(--text-secondary); text-indent: 0;">···</p>
<p>林克站起身,朝着村庄中央走去。</p>
<p>沿途,他遭遇了各种瘟疫怪物。有的是被感染的村民变成的盗尸者,它们行动迟缓但数量众多;有的是被瘟疫溶解的怪物,黑色的浆糊状生物,散发着剧毒的气息。</p>
<p>"流心·刺!"</p>
<p>林克的光剑精准地刺穿一只盗尸者的头颅,冰属性的剑气瞬间冻结了它的身体。但更多的怪物从四面八方涌来。</p>
<p>他深吸一口气,光剑在手中旋转。</p>
<p>"里鬼剑术!"</p>
<p>无数剑气如同暴风般席卷而出,将周围的怪物全部斩成碎片。冰蓝色的剑光在黑色的瘟疫雾气中显得格外耀眼。</p>
<p>但林克注意到,这些怪物被击败后,身上会掉落一些闪烁着微光的碎片——那是时间之痕,西岚需要的东西。</p>
<p>他一边战斗,一边收集时间之痕。</p>
<p style="text-align: center; color: var(--text-secondary); text-indent: 0;">···</p>
<p>村庄中央,林克终于找到了那个黑色斗篷人。</p>
<p>那是一个身穿黑色长袍、戴着面具的神秘人,和格兰之火遇到的那个一模一样。她站在一座祭坛上,手中高举着一瓶黑色的液体,正在进行某种邪恶的仪式。祭坛周围,黑色的能量在涌动,瘟疫的气息更加浓郁。</p>
<p>"又是你..."林克冷声说道,"格兰之火的账还没算完,你竟然又在这里散播瘟疫!"</p>
<p>黑袍人转过身,面具下的眼睛看向林克,发出阴冷的笑声:"哦?又是你?看来上次的教训还不够啊。"</p>
<p>林克心中一震——她记得格兰之火的事情!</p>
<p>"你到底是什么人?为什么要做这些?"</p>
<p>"我?"黑袍人放下手中的瓶子,"我是赫尔德大人的使者,负责为'创新世纪'计划铺路。这场瘟疫,是为了削弱暗精灵王国,让他们在未来无法抵抗使徒的入侵。"</p>
<p>她张开双臂,黑色的能量在她周身涌动:"狄瑞吉终将降临,而暗精灵王国将因为这场瘟疫而元气大伤。到时候,整个阿拉德大陆都将陷入混乱..."</p>
<p>"我不会让你得逞的!"林克握紧光剑。</p>
<p>"就凭你?"黑袍人嗤笑,"一个被时空之门限制在70级的剑士"</p>
<p>她双手结印,黑色的瘟疫能量化作无数触手,朝着林克席卷而来!</p>
<p style="text-align: center; color: var(--text-secondary); text-indent: 0;">···</p>
<p>战斗瞬间爆发!</p>
<p>黑袍人的瘟疫魔法诡异而强大,黑色的触手蕴含着剧毒,所过之处连石头都被腐蚀。林克挥舞着细雪之舞,冰属性的剑气与瘟疫能量碰撞,发出刺耳的嘶鸣声。</p>
<p>"破军升龙击!"</p>
<p>林克的身形如同游龙般冲向黑袍人,光剑带起一道金色的龙形剑气。但黑袍人轻轻一闪,就避开了这一击。</p>
<p>"太慢了。"黑袍人冷笑,"在70级的限制下你的速度根本跟不上我。"</p>
<p>她挥手间,更多的瘟疫触手从四面八方涌来,将林克团团围住。</p>
<p>林克咬牙他知道对方说得没错。在70级的限制下他无法使用极·神剑术等高级技能实力大打折扣。</p>
<p>但他没有放弃。</p>
<p>"幻影剑舞!"</p>
<p>无数剑气从林克身上爆发形成了一道巨大的剑气风暴将周围的瘟疫触手全部斩断。这是他在70级以内能够使用的最强技能</p>
<p>"有点意思..."黑袍人终于露出了认真的表情,"但还不够!"</p>
<p>她双手高举,祭坛上的黑色液体开始沸腾,一股更加强大的瘟疫能量爆发出来!</p>
<p>"瘟疫爆发!"</p>
<p>黑色的能量如同潮水般涌向林克所过之处一切都被腐蚀。林克感到前所未有的压力这种级别的攻击已经超出了普通70级技能的防御范围</p>
<p>就在这千钧一发之际,林克突然想起了什么。</p>
<p>"细雪之舞...冰属性..."</p>
<p>他低头看着手中的光剑,眼中闪过一丝明悟。</p>
<p>瘟疫的本质是病毒和细菌,而极寒可以冻结一切生命活动!</p>
<p>"流心·跃!"</p>
<p>林克的身形高高跃起,躲过了瘟疫能量的正面冲击。同时,他将全身的剑魂之力注入细雪之舞,光剑爆发出前所未有的冰蓝色光芒!</p>
<p>"极寒...拔刀斩!"</p>
<p>这一剑,不是普通的拔刀斩。林克将冰属性的力量发挥到了极致,剑气所过之处,连空气都被冻结!</p>
<p>冰蓝色的剑气与黑色的瘟疫能量碰撞,发出震耳欲聋的轰鸣声。最终,极寒的剑气冻结了瘟疫能量,将它们全部粉碎!</p>
<p>"什么?!"黑袍人大惊。</p>
<p>林克没有给她反应的机会,身形如同闪电般冲到黑袍人面前。</p>
<p>"猛龙断空斩!"</p>
<p>金色的龙形剑气穿透了黑袍人的防御,将她重重地击飞出去!</p>
<p>黑袍人撞在祭坛上,面具碎裂,露出了一张苍白的脸。她的眼中满是不甘和震惊。</p>
<p>"不可能...我怎么可能败给一个人类..."</p>
<p>林克走到她面前,光剑指向她的咽喉:"你的阴谋结束了。"</p>
<p>黑袍人突然狂笑起来:"结束?你以为阻止了我就能改变什么?狄瑞吉终将降临,瘟疫必将蔓延...这是命中注定的..."</p>
<p>她的身体开始崩溃,黑色的能量从她体内爆发,然后彻底消散。</p>
<p>"赫尔德...大人...计划不会停止..."</p>
<p>这是她的最后一句话。</p>
<p style="text-align: center; color: var(--text-secondary); text-indent: 0;">···</p>
<p>战斗结束,祭坛上的黑色液体也随之消散。</p>
<p>林克收集了大量时间之痕,这些都是西岚需要的东西。但他心中却没有胜利的喜悦。</p>
<p>黑袍人的话在他耳边回响——</p>
<p>"狄瑞吉终将降临...这是命中注定的..."</p>
<p>赫尔德的阴谋比他想象的更加深远。格兰之火、瘟疫之源,这些都只是开始。</p>
<p>林克转身离开,朝着时空之门的方向走去。</p>
<p>在他身后,贺加斯靠在废墟上,看着林克的背影,眼中闪过一丝感激。</p>
<p>"谢谢你...陌生人..."</p>
<p>贺加斯闭上了眼睛,他的使命完成了。</p>
<p style="text-align: center; color: var(--text-secondary); text-indent: 0;">···</p>
<p>时空之门前,林克回头望了一眼这片被瘟疫毁灭的土地。</p>
<p>"诺伊佩拉...我会记住这个地方。"</p>
<p>他踏入金色的光芒,前往下一个时间点。</p>
<p style="text-align: center; color: var(--text-secondary); text-indent: 0; margin-top: 2em;">(第一百零八章完)</p>
</article>
</div>
<!-- 固定底部导航 -->
<nav class="fixed-nav">
<div class="fixed-nav-content">
<a href="chapter-107.html" class="nav-btn ">上一章</a>
<a href="../chapters.html" class="nav-btn">目录</a>
<button class="nav-btn" id="ttsToggleBtn">朗读</button>
<a href="chapter-109.html" class="nav-btn ">下一章</a>
</div>
</nav>
<!-- 右侧滚动按钮 -->
<div class="scroll-buttons">
<button class="scroll-btn" id="scrollTop" title="回到顶部"></button>
<button class="scroll-btn" id="scrollBottom" title="回到底部"></button>
</div>
<!-- TTS弹出面板 -->
<div class="tts-overlay" id="ttsOverlay">
<div class="tts-panel">
<div class="tts-header">
<div class="tts-title">🔊 语音朗读</div>
<button class="tts-close" id="ttsClose">×</button>
</div>
<div class="tts-controls">
<button class="tts-btn" id="ttsPlay" title="播放"></button>
<button class="tts-btn" id="ttsPause" title="暂停"></button>
<button class="tts-btn" id="ttsStop" title="停止"></button>
</div>
<div class="tts-progress">
<div class="tts-progress-bar">
<div class="tts-progress-fill" id="ttsProgressFill"></div>
</div>
<div class="tts-time" id="ttsTime">0 / 0 句</div>
</div>
<div class="tts-speed">
<span class="tts-speed-label">朗读速度:</span>
<select class="tts-speed-select" id="ttsSpeed">
<option value="0.5">慢速 (0.5x)</option>
<option value="0.75">较慢 (0.75x)</option>
<option value="1" selected>正常 (1x)</option>
<option value="1.25">较快 (1.25x)</option>
<option value="1.5">快速 (1.5x)</option>
<option value="2">极速 (2x)</option>
</select>
</div>
</div>
</div>
<!-- 侧边栏章节导航 -->
<aside class="sidebar">
<div class="sidebar-title">章节导航</div>
<div class="sidebar-content" id="sidebarContent">
<a href="chapter-78.html" class="sidebar-chapter ">第78章列车上的海贼·铁鳞团的覆灭</a>
<a href="chapter-79.html" class="sidebar-chapter ">第79章夺回西部线·卡勒特的余孽</a>
<a href="chapter-80.html" class="sidebar-chapter ">第80章雾都赫伊斯·无法地带的阴影</a>
<a href="chapter-81.html" class="sidebar-chapter ">第81章阿登高地·GT-9600</a>
<a href="chapter-82.html" class="sidebar-chapter ">第82章卡勒特指挥部·兰蒂卢斯</a>
<a href="chapter-83.html" class="sidebar-chapter ">第83章皇女的告白·天界的新篇章</a>
<a href="chapter-84.html" class="sidebar-chapter ">第84章幽灵列车·亡者的低语</a>
<a href="chapter-85.html" class="sidebar-chapter ">第85章伊顿工业区·克雷发电站</a>
<a href="chapter-86.html" class="sidebar-chapter ">第86章普鲁兹发电站·闪电之帕特里斯</a>
<a href="chapter-87.html" class="sidebar-chapter ">第87章特伦斯发电站·熔岩之萨姆</a>
<a href="chapter-88.html" class="sidebar-chapter ">第88章格兰迪发电站·虚空之弗曼</a>
<a href="chapter-89.html" class="sidebar-chapter ">第89章安图恩攻坚战·黑雾之源</a>
<a href="chapter-90.html" class="sidebar-chapter ">第90章安图恩攻坚战·震颤的大地</a>
<a href="chapter-91.html" class="sidebar-chapter ">第91章安图恩攻坚战·擎天之柱</a>
<a href="chapter-92.html" class="sidebar-chapter ">第92章安图恩攻坚战·黑色火山</a>
<a href="chapter-93.html" class="sidebar-chapter ">第93章安图恩攻坚战·使徒陨落</a>
<a href="chapter-94.html" class="sidebar-chapter ">第94章克洛诺斯岛·寂静城的召唤</a>
<a href="chapter-95.html" class="sidebar-chapter ">第95章寂静城的秘密</a>
<a href="chapter-96.html" class="sidebar-chapter ">第96章番外·贝奇的献身</a>
<a href="chapter-97.html" class="sidebar-chapter ">第97章光之舞会</a>
<a href="chapter-98.html" class="sidebar-chapter ">第98章钢铁之臂</a>
<a href="chapter-99.html" class="sidebar-chapter ">第99章能源熔炉</a>
<a href="chapter-100.html" class="sidebar-chapter ">第100章王之书库</a>
<a href="chapter-101.html" class="sidebar-chapter ">第101章不灭回廊</a>
<a href="chapter-102.html" class="sidebar-chapter ">第102章机械王座</a>
<a href="chapter-103.html" class="sidebar-chapter ">第103章番外·寂静城的早晨</a>
<a href="chapter-104.html" class="sidebar-chapter ">第104章番外·贝奇与艾泽拉</a>
<a href="chapter-105.html" class="sidebar-chapter ">第105章番外·卢克的嘱托</a>
<a href="chapter-106.html" class="sidebar-chapter ">第106章时空之门的召唤</a>
<a href="chapter-107.html" class="sidebar-chapter ">第107章格兰之火</a>
<a href="chapter-108.html" class="sidebar-chapter current">第108章瘟疫之源</a>
<a href="chapter-109.html" class="sidebar-chapter ">第109章卡勒特之初</a>
<a href="chapter-110.html" class="sidebar-chapter ">第110章无法地带</a>
<a href="chapter-111.html" class="sidebar-chapter ">第111章暗黑圣战</a>
<a href="chapter-112.html" class="sidebar-chapter ">第112章昔日悲鸣</a>
<a href="chapter-113.html" class="sidebar-chapter ">第113章凛冬</a>
<a href="chapter-114.html" class="sidebar-chapter ">第114章迷之觉悟</a>
<a href="chapter-115.html" class="sidebar-chapter ">第115章番外·艾丽丝的抉择</a>
<a href="chapter-116.html" class="sidebar-chapter ">第116章番外·后宫的日常</a>
<a href="chapter-117.html" class="sidebar-chapter ">第117章番外·与赛丽亚的约会</a>
<a href="chapter-118.html" class="sidebar-chapter ">第118章番外·与奥菲利亚的重逢</a>
<a href="chapter-119.html" class="sidebar-chapter ">第119章番外·与敏泰的雪山之行</a>
<a href="chapter-120.html" class="sidebar-chapter ">第120章番外·与莎兰的魔法时光</a>
<a href="chapter-121.html" class="sidebar-chapter ">第121章番外·与帕丽丝的格斗训练</a>
<a href="chapter-122.html" class="sidebar-chapter ">第122章番外·与莫纳亨的念动力</a>
<a href="chapter-123.html" class="sidebar-chapter ">第123章番外·与泽丁的天界巡逻</a>
<a href="chapter-124.html" class="sidebar-chapter ">第124章番外·与马琳的骑士之道</a>
<a href="chapter-125.html" class="sidebar-chapter ">第125章番外·与皇女的皇家约会</a>
<a href="chapter-126.html" class="sidebar-chapter ">第126章番外·与米娅的工坊时光</a>
<a href="chapter-127.html" class="sidebar-chapter ">第127章番外·与贝奇的人造之心</a>
<a href="chapter-128.html" class="sidebar-chapter ">第128章番外·与艾泽拉的守护誓言</a>
<a href="chapter-129.html" class="sidebar-chapter ">第129章魔界的召唤</a>
<a href="chapter-130.html" class="sidebar-chapter ">第130章魔界营地</a>
<a href="chapter-131.html" class="sidebar-chapter ">第131章凯蒂的指引</a>
<a href="chapter-132.html" class="sidebar-chapter ">第132章营地危机</a>
<a href="chapter-133.html" class="sidebar-chapter ">第133章尼梅尔的心意</a>
<a href="chapter-134.html" class="sidebar-chapter ">第134章中央公园</a>
<a href="chapter-135.html" class="sidebar-chapter ">第135章剑圣的试炼</a>
<a href="chapter-136.html" class="sidebar-chapter ">第136章地轨中心</a>
<a href="chapter-137.html" class="sidebar-chapter ">第137章魔剑士阿斯兰</a>
<a href="chapter-138.html" class="sidebar-chapter ">第138章泪目之眼</a>
</div>
</aside>
<script>
// 记录阅读进度
let readChapters = JSON.parse(localStorage.getItem('readChapters') || '[]');
if (!readChapters.includes(108)) {
readChapters.push({{CHAPTER_ID}});
localStorage.setItem('readChapters', JSON.stringify(readChapters));
}
// 主题切换
const themeToggle = document.getElementById('themeToggle');
const savedTheme = localStorage.getItem('theme') || 'dark';
document.documentElement.setAttribute('data-theme', savedTheme);
themeToggle.textContent = savedTheme === 'dark' ? '浅色' : '深色';
themeToggle.addEventListener('click', () => {
const currentTheme = document.documentElement.getAttribute('data-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem('theme', newTheme);
themeToggle.textContent = newTheme === 'dark' ? '浅色' : '深色';
});
// 滚动到顶部
document.getElementById('scrollTop').addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
// 滚动到底部
document.getElementById('scrollBottom').addEventListener('click', () => {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
});
// 页面加载时,侧边栏自动滚动到当前章节
window.addEventListener('load', () => {
const sidebarContent = document.getElementById('sidebarContent');
const currentChapter = sidebarContent.querySelector('.current');
if (currentChapter) {
currentChapter.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
});
// ========== TTS弹出面板 ==========
const ttsOverlay = document.getElementById('ttsOverlay');
const ttsToggleBtn = document.getElementById('ttsToggleBtn');
const ttsClose = document.getElementById('ttsClose');
// 打开TTS面板
ttsToggleBtn.addEventListener('click', () => {
ttsOverlay.classList.add('show');
initTTS();
});
// 关闭TTS面板
ttsClose.addEventListener('click', () => {
ttsOverlay.classList.remove('show');
});
// 点击遮罩关闭
ttsOverlay.addEventListener('click', (e) => {
if (e.target === ttsOverlay) {
ttsOverlay.classList.remove('show');
}
});
// ========== TTS语音朗读功能 ==========
let ttsSynth = window.speechSynthesis;
let ttsUtterance = null;
let ttsText = '';
let ttsSentences = [];
let ttsCurrentIndex = 0;
let ttsIsPlaying = false;
let ttsIsPaused = false;
let ttsSpeed = 1;
// 初始化:提取章节内容
function initTTS() {
const contentEl = document.querySelector('.chapter-content');
if (!contentEl) return;
// 获取所有段落文本清理HTML标签
ttsText = contentEl.innerText || contentEl.textContent;
// 分割成句子(中文按句号、问号、感叹号分割)
ttsSentences = ttsText.match(/[^。!?\n]+[。!?\n]+|[^。!?\n]+$/g) || [ttsText];
ttsSentences = ttsSentences.filter(s => s.trim().length > 0);
updateTTSProgress();
}
// 更新进度显示
function updateTTSProgress() {
const total = ttsSentences.length;
const current = ttsCurrentIndex;
document.getElementById('ttsTime').textContent = `${current} / ${total}`;
const percent = total > 0 ? (current / total * 100) : 0;
document.getElementById('ttsProgressFill').style.width = `${percent}%`;
}
// 播放当前句子
function playCurrentSentence() {
if (ttsCurrentIndex >= ttsSentences.length) {
stopTTS();
return;
}
const text = ttsSentences[ttsCurrentIndex].trim();
ttsUtterance = new SpeechSynthesisUtterance(text);
ttsUtterance.lang = 'zh-CN';
ttsUtterance.rate = ttsSpeed;
// 尝试选择中文语音
const voices = ttsSynth.getVoices();
const zhVoice = voices.find(v => v.lang.includes('zh') || v.lang.includes('CN'));
if (zhVoice) {
ttsUtterance.voice = zhVoice;
}
ttsUtterance.onend = () => {
if (ttsIsPlaying && !ttsIsPaused) {
ttsCurrentIndex++;
updateTTSProgress();
playCurrentSentence();
}
};
ttsUtterance.onerror = (e) => {
console.error('TTS error:', e);
if (ttsIsPlaying) {
ttsCurrentIndex++;
updateTTSProgress();
playCurrentSentence();
}
};
ttsSynth.speak(ttsUtterance);
}
// 播放
function playTTS() {
if (ttsSentences.length === 0) {
initTTS();
}
if (ttsIsPaused) {
ttsSynth.resume();
ttsIsPaused = false;
} else {
ttsIsPlaying = true;
playCurrentSentence();
}
document.getElementById('ttsPlay').classList.add('active');
document.getElementById('ttsPause').classList.remove('active');
ttsToggleBtn.classList.add('active');
}
// 暂停
function pauseTTS() {
if (ttsIsPlaying) {
ttsSynth.pause();
ttsIsPaused = true;
document.getElementById('ttsPlay').classList.remove('active');
document.getElementById('ttsPause').classList.add('active');
ttsToggleBtn.classList.remove('active');
}
}
// 停止
function stopTTS() {
ttsSynth.cancel();
ttsIsPlaying = false;
ttsIsPaused = false;
ttsCurrentIndex = 0;
updateTTSProgress();
document.getElementById('ttsPlay').classList.remove('active');
document.getElementById('ttsPause').classList.remove('active');
ttsToggleBtn.classList.remove('active');
}
// 设置速度
function setTTSSpeed(speed) {
ttsSpeed = parseFloat(speed);
// 如果正在播放,需要重新开始当前句子
if (ttsIsPlaying && !ttsIsPaused) {
ttsSynth.cancel();
playCurrentSentence();
}
}
// 绑定事件
document.getElementById('ttsPlay').addEventListener('click', playTTS);
document.getElementById('ttsPause').addEventListener('click', pauseTTS);
document.getElementById('ttsStop').addEventListener('click', stopTTS);
document.getElementById('ttsSpeed').addEventListener('change', (e) => setTTSSpeed(e.target.value));
// 加载语音列表(某些浏览器需要异步加载)
if (speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = initTTS;
}
// 页面离开时停止播放
window.addEventListener('beforeunload', stopTTS);
</script>
</body>
</html>