405 lines
21 KiB
HTML
405 lines
21 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Hermite 多项式 · 高斯世界里的频率分解工具</title>
|
||
|
||
<!--
|
||
设计系统(深空学术 Deep Space)
|
||
背景:radial #11202a → #0a0e14 → #07090d(暗青底,章节用不同 glow 方位制造节奏)
|
||
色:primary 青绿 #2ec4b6 / accent 琥珀 #ffb703 / 文本 #e8eef2 / 次级 #9fb0ba / mono #56727d
|
||
字:标题 Noto Sans SC 900;正文 Noto Sans SC 300/500;公式与标签 JetBrains Mono / KaTeX
|
||
字号:H1 110-118 / H2 70-78 / 卡标题 34-40 / 正文 26-30 / mono 18-22(震撼态,整体偏大)
|
||
节奏:封面=大字+留白;类比/正交=卡片;OU/谱权重=图形化条;小结=网格。
|
||
-->
|
||
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" crossorigin="anonymous">
|
||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js" crossorigin="anonymous"></script>
|
||
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" crossorigin="anonymous"></script>
|
||
|
||
<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+Sans+SC:wght@300;500;700;900&family=JetBrains+Mono:wght@400;700&family=Space+Grotesk:wght@500;700&display=swap" rel="stylesheet">
|
||
|
||
<style>
|
||
*{margin:0;padding:0;box-sizing:border-box;}
|
||
:root{
|
||
--bg0:#07090d; --teal:#2ec4b6; --amber:#ffb703;
|
||
--ink:#e8eef2; --ink2:#9fb0ba; --mono:#56727d; --line:rgba(255,255,255,.08);
|
||
}
|
||
html,body{width:100%;height:100%;background:var(--bg0);overflow:hidden;
|
||
font-family:"Noto Sans SC",sans-serif;color:var(--ink);}
|
||
|
||
/* 舞台缩放 */
|
||
#wrap{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;}
|
||
.stage{width:1920px;height:1080px;transform-origin:center center;position:relative;}
|
||
|
||
.slide{position:absolute;inset:0;padding:96px 110px 120px;display:flex;flex-direction:column;
|
||
background:radial-gradient(120% 120% at 75% 12%, #11202a 0%, #0a0e14 56%, #07090d 100%);}
|
||
.slide:not(.active){display:none !important;}
|
||
.slide.posBL{background:radial-gradient(120% 120% at 18% 92%, #11202a 0%, #0a0e14 60%, #07090d 100%);}
|
||
.slide.posCR{background:radial-gradient(130% 130% at 95% 50%, #12232c 0%, #0a0e14 58%, #07090d 100%);}
|
||
|
||
.glow{position:absolute;width:620px;height:620px;border-radius:50%;pointer-events:none;
|
||
background:radial-gradient(circle,rgba(46,196,182,.16),transparent 70%);top:-160px;right:-110px;filter:blur(6px);}
|
||
.glow.amber{background:radial-gradient(circle,rgba(255,183,3,.13),transparent 70%);}
|
||
|
||
/* 页眉小标 + 页脚 */
|
||
.kicker{font-family:"JetBrains Mono",monospace;color:var(--teal);font-size:22px;letter-spacing:.18em;
|
||
text-transform:uppercase;display:flex;align-items:center;gap:16px;}
|
||
.kicker .ln{width:54px;height:2px;background:var(--teal);opacity:.7;}
|
||
.page-footer{position:absolute;left:110px;right:110px;bottom:60px;display:flex;justify-content:space-between;
|
||
align-items:center;font-family:"JetBrains Mono",monospace;font-size:18px;color:var(--mono);}
|
||
.page-footer .prog{flex:1;margin:0 30px;height:2px;background:rgba(255,255,255,.08);position:relative;border-radius:2px;}
|
||
.page-footer .prog i{position:absolute;left:0;top:0;height:100%;background:linear-gradient(90deg,var(--teal),var(--amber));border-radius:2px;transition:width .4s;}
|
||
|
||
h1{font-weight:900;font-size:116px;line-height:1.03;letter-spacing:-.01em;}
|
||
h1 em{font-style:normal;color:var(--teal);}
|
||
h2{font-weight:900;font-size:74px;line-height:1.08;margin-top:22px;}
|
||
h2 em{font-style:normal;color:var(--amber);}
|
||
.lead{font-size:29px;color:var(--ink2);font-weight:300;margin-top:18px;line-height:1.5;max-width:1300px;}
|
||
|
||
.content{flex:1;display:flex;align-items:center;min-height:0;}
|
||
|
||
.katex{font-size:1em;}
|
||
.fbox{background:rgba(46,196,182,.06);border:1px solid rgba(46,196,182,.24);border-radius:18px;
|
||
padding:46px 44px;text-align:center;color:#eafcf9;}
|
||
.fbox .small{font-size:23px;color:#7fd8cf;margin-top:22px;font-family:"JetBrains Mono",monospace;}
|
||
|
||
/* 通用卡片 */
|
||
.cards{display:flex;gap:36px;width:100%;}
|
||
.card{flex:1;background:rgba(255,255,255,.03);border:1px solid var(--line);border-radius:18px;padding:42px 38px;}
|
||
.card .ct{font-size:36px;font-weight:700;margin-bottom:18px;}
|
||
.card .cb{font-size:26px;color:var(--ink2);font-weight:300;line-height:1.55;}
|
||
.card .cf{margin-top:22px;font-size:30px;color:var(--teal);}
|
||
|
||
/* 封面 */
|
||
.cover{justify-content:center;}
|
||
.cover .meta{position:absolute;bottom:72px;left:110px;font-family:"JetBrains Mono",monospace;font-size:21px;color:var(--mono);}
|
||
|
||
/* 衰减条 */
|
||
.barrow{display:flex;align-items:center;gap:20px;margin:22px 0;font-size:30px;}
|
||
.barrow .chip{font-family:"JetBrains Mono",monospace;font-size:24px;padding:7px 16px;border-radius:8px;
|
||
background:#13343a;color:var(--teal);min-width:96px;text-align:center;}
|
||
.barrow .track{flex:1;height:16px;border-radius:8px;background:rgba(255,255,255,.06);position:relative;overflow:hidden;}
|
||
.barrow .track i{position:absolute;left:0;top:0;height:100%;border-radius:8px;
|
||
background:linear-gradient(90deg,var(--teal),var(--amber));}
|
||
.barrow .val{font-family:"JetBrains Mono",monospace;font-size:24px;color:var(--ink2);min-width:70px;}
|
||
|
||
/* 表格类比 */
|
||
table.cmp{width:100%;border-collapse:collapse;font-size:28px;}
|
||
table.cmp th,table.cmp td{padding:24px 26px;text-align:left;border-bottom:1px solid var(--line);}
|
||
table.cmp th{font-family:"JetBrains Mono",monospace;font-size:22px;color:var(--mono);letter-spacing:.08em;font-weight:400;}
|
||
table.cmp td.k{color:var(--ink2);font-weight:300;width:24%;}
|
||
table.cmp td .fr{color:var(--teal);}
|
||
table.cmp td .he{color:var(--amber);}
|
||
|
||
/* 谱权重饼图 */
|
||
.pie{width:340px;height:340px;border-radius:50%;flex-shrink:0;}
|
||
.legend{margin-left:60px;}
|
||
.legend .li{display:flex;align-items:center;gap:18px;font-size:30px;margin:18px 0;}
|
||
.legend .dot{width:26px;height:26px;border-radius:6px;}
|
||
|
||
/* 列表 */
|
||
ul.pts{list-style:none;}
|
||
ul.pts li{font-size:31px;font-weight:300;color:var(--ink);line-height:1.5;margin:24px 0;padding-left:46px;position:relative;}
|
||
ul.pts li::before{content:"";position:absolute;left:0;top:16px;width:22px;height:22px;border-radius:6px;
|
||
background:linear-gradient(135deg,var(--teal),var(--amber));}
|
||
ul.pts li b{color:var(--teal);font-weight:700;}
|
||
|
||
/* 小结网格 */
|
||
.grid4{display:grid;grid-template-columns:1fr 1fr;gap:30px;width:100%;}
|
||
.grid4 .g{background:rgba(255,255,255,.03);border:1px solid var(--line);border-radius:16px;padding:34px 34px;}
|
||
.grid4 .g .n{font-family:"Space Grotesk";font-weight:700;font-size:40px;color:var(--teal);}
|
||
.grid4 .g .t{font-size:28px;margin-top:8px;line-height:1.45;color:var(--ink);font-weight:300;}
|
||
.grid4 .g .t b{color:var(--amber);font-weight:700;}
|
||
|
||
/* 导航键(在 stage 外,避免被 scale 压缩)*/
|
||
.nav{position:fixed;bottom:18px;left:50%;transform:translateX(-50%);z-index:900;display:flex;gap:10px;align-items:center;}
|
||
.nav button{background:#16242b;border:1px solid #2a3c44;color:#cfe;font-size:15px;padding:9px 18px;border-radius:8px;cursor:pointer;font-family:"JetBrains Mono",monospace;}
|
||
.nav button:hover{background:#1d3038;}
|
||
.nav .pg{color:#6f8a93;font-family:"JetBrains Mono",monospace;font-size:14px;padding:0 8px;}
|
||
.hintkey{position:fixed;top:14px;right:18px;z-index:900;color:#42535b;font-family:"JetBrains Mono",monospace;font-size:13px;}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="hintkey">← → 翻页 · F 全屏 · 刷新记忆当前页</div>
|
||
|
||
<div id="wrap">
|
||
<div class="stage" id="stage">
|
||
|
||
<!-- 1 封面 -->
|
||
<section class="slide active cover">
|
||
<div class="glow"></div>
|
||
<div class="kicker"><span class="ln"></span>SELF-SUPERVISED · 谱分解 · EP.01</div>
|
||
<h1 style="margin-top:34px;">Hermite<br><em>多项式</em></h1>
|
||
<p class="lead" style="margin-top:38px;">高斯世界里的「频率分解」工具<br>—— 配套播客讲解,从直觉到 LeJEPA 的理论基石</p>
|
||
<div class="meta">配套音频 7:43 · 双主播对话 · 数学不可怕,可怕的是没人陪你拆积木</div>
|
||
</section>
|
||
|
||
<!-- 2 动机 -->
|
||
<section class="slide posBL">
|
||
<div class="glow amber"></div>
|
||
<div class="kicker"><span class="ln"></span>01 · 动机</div>
|
||
<h2>我们需要一把<em>拆函数的刀</em></h2>
|
||
<div class="content">
|
||
<ul class="pts">
|
||
<li>LeJEPA 的证明要回答:编码器的表示里,<b>哪一部分</b>对「正样本对」的相关性贡献最大?</li>
|
||
<li>正样本对 = 同一内容的两个视角,模型希望它们的表示尽量像。</li>
|
||
<li>要回答这个问题,得先能把<b>任意函数拆成一块块</b>——就像傅里叶把声音拆成不同频率的波。</li>
|
||
<li>在高斯(钟形)分布下,这套「积木」就是 <b>Hermite 多项式</b>。</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 3 傅里叶类比 -->
|
||
<section class="slide">
|
||
<div class="glow"></div>
|
||
<div class="kicker"><span class="ln"></span>02 · 类比</div>
|
||
<h2>傅里叶之于周期,<em>Hermite</em> 之于高斯</h2>
|
||
<div class="content">
|
||
<table class="cmp">
|
||
<tr><th>维度</th><th>傅里叶级数</th><th>Hermite 展开</th></tr>
|
||
<tr><td class="k">适用场景</td><td><span class="fr">周期函数</span></td><td><span class="he">高斯分布下的函数</span></td></tr>
|
||
<tr><td class="k">基函数</td><td><span class="fr">$\sin nx,\ \cos nx$</span></td><td><span class="he">$He_0,He_1,He_2,\dots$</span></td></tr>
|
||
<tr><td class="k">正交性</td><td><span class="fr">在区间上积分为 0</span></td><td><span class="he">在高斯期望下为 0</span></td></tr>
|
||
<tr><td class="k">完备性</td><td><span class="fr">任意周期函数可展开</span></td><td><span class="he">任意 $L^2(\gamma)$ 函数可展开</span></td></tr>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 4 定义与递推 -->
|
||
<section class="slide posCR">
|
||
<div class="glow"></div>
|
||
<div class="kicker"><span class="ln"></span>03 · 定义</div>
|
||
<h2>积木长什么样 & <em>递推</em>搭出来</h2>
|
||
<div class="content" style="gap:60px;">
|
||
<div class="fbox" style="flex:1;font-size:34px;line-height:2;">
|
||
$He_0=1,\quad He_1=z$<br>
|
||
$He_2=z^2-1$<br>
|
||
$He_3=z^3-3z$<br>
|
||
$He_4=z^4-6z^2+3$
|
||
</div>
|
||
<div style="flex:1;">
|
||
<div class="fbox" style="font-size:40px;">
|
||
$He_{n+1}(z)=z\,He_n(z)-n\,He_{n-1}(z)$
|
||
<div class="small">下一块 = z × 当前块 − 阶数 × 前一块</div>
|
||
</div>
|
||
<p class="lead" style="margin-top:30px;font-size:26px;">验证:$z\cdot z-1\cdot 1=z^2-1=He_2$ ✓</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 5 正交性 -->
|
||
<section class="slide">
|
||
<div class="glow amber"></div>
|
||
<div class="kicker"><span class="ln"></span>04 · 核心性质</div>
|
||
<h2>正交性:不同阶数<em>互不干扰</em></h2>
|
||
<div class="content" style="gap:60px;">
|
||
<div class="fbox" style="flex:1.1;font-size:34px;">
|
||
$\mathbb{E}\big[He_m(z)\,He_n(z)\big]=\begin{cases}n! & m=n\\[4pt]0 & m\neq n\end{cases}$
|
||
<div class="small">$z\sim\mathcal N(0,1)$,期望对钟形曲线取</div>
|
||
</div>
|
||
<div style="flex:1;">
|
||
<div class="card">
|
||
<div class="ct">最小例子验证</div>
|
||
<div class="cb" style="font-size:28px;line-height:1.8;">
|
||
$\mathbb{E}[He_1\cdot He_2]=\mathbb{E}[z^3-z]$<br>
|
||
高斯的奇数阶矩为 0 → $=0-0=0$ ✓
|
||
</div>
|
||
<div class="cf" style="font-size:26px;">就像不同频率的正弦波互相正交</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 6 完备性 -->
|
||
<section class="slide posBL">
|
||
<div class="glow"></div>
|
||
<div class="kicker"><span class="ln"></span>05 · 完备性</div>
|
||
<h2>任意函数都能<em>拆开重组</em></h2>
|
||
<div class="content" style="gap:60px;">
|
||
<div class="fbox" style="flex:1;font-size:36px;">
|
||
$h(z)=\sum_{d=0}^{\infty}c_d\,He_d(z)$
|
||
<div class="small">$c_d=\dfrac{\mathbb{E}[h(z)\,He_d(z)]}{d!}$</div>
|
||
</div>
|
||
<div style="flex:1;">
|
||
<p class="lead" style="font-size:30px;">只要 $\mathbb{E}[h(z)^2]<\infty$(有限能量),就能写成这些积木的<b style="color:var(--teal)">加权叠加</b>。</p>
|
||
<p class="lead" style="font-size:30px;margin-top:24px;">就像把一个向量沿正交坐标轴分解——每个轴上投影多少,系数 $c_d$ 就有多大。</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 7 OU 衰减 -->
|
||
<section class="slide posCR">
|
||
<div class="glow amber"></div>
|
||
<div class="kicker"><span class="ln"></span>06 · 关键转折</div>
|
||
<h2>OU 过程让相关性<em>按阶数指数衰减</em></h2>
|
||
<div class="content" style="gap:60px;">
|
||
<div class="fbox" style="flex:.95;font-size:34px;">
|
||
$\mathbb{E}[He_n(z')He_n(z)]=\rho^{\,n}\cdot n!$
|
||
<div class="small">$z'=\rho z+\sqrt{1-\rho^2}\,\eta,\quad 0<\rho<1$</div>
|
||
</div>
|
||
<div style="flex:1.05;">
|
||
<div class="barrow"><span class="chip">1 阶</span><div class="track"><i style="width:90%"></i></div><span class="val">ρ¹</span></div>
|
||
<div class="barrow"><span class="chip">2 阶</span><div class="track"><i style="width:50%"></i></div><span class="val">ρ²</span></div>
|
||
<div class="barrow"><span class="chip">3 阶</span><div class="track"><i style="width:26%"></i></div><span class="val">ρ³</span></div>
|
||
<p class="lead" style="font-size:26px;margin-top:18px;">阶数越高 → 相关性掉得越快 → 高阶非线性几乎被冲淡。</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 8 线性可识别性 -->
|
||
<section class="slide">
|
||
<div class="glow"></div>
|
||
<div class="kicker"><span class="ln"></span>07 · 结论</div>
|
||
<h2>最优解:<em>只保留线性成分</em></h2>
|
||
<div class="content">
|
||
<ul class="pts">
|
||
<li>对齐损失要<b>最大化</b>正样本对的相关性。</li>
|
||
<li>线性成分贡献 $\rho$;非线性成分贡献 $\rho^d<\rho\ (d\ge 2)$,被打了折扣。</li>
|
||
<li>于是最优策略就是:<b>留下线性,丢掉所有非线性</b>。</li>
|
||
<li>模型被这个机制温柔地逼成一个本质线性的表示 —— 这就是<b>线性可识别性</b>,整套定理的直觉来源。</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 9 谱权重 -->
|
||
<section class="slide posBL">
|
||
<div class="glow amber"></div>
|
||
<div class="kicker"><span class="ln"></span>08 · 度量工具</div>
|
||
<h2>谱权重:一张<em>能量饼图</em></h2>
|
||
<div class="content">
|
||
<div class="pie" style="background:conic-gradient(var(--teal) 0 62%, var(--amber) 62% 84%, #4a6b74 84% 100%);"></div>
|
||
<div class="legend">
|
||
<div class="li"><span class="dot" style="background:var(--teal)"></span>线性 $w_1$ —— 我们想要的成分</div>
|
||
<div class="li"><span class="dot" style="background:var(--amber)"></span>二阶 $w_2$ —— 被 OU 衰减更多</div>
|
||
<div class="li"><span class="dot" style="background:#4a6b74"></span>更高阶 —— 衰减最狠</div>
|
||
<div class="li" style="font-size:24px;color:var(--ink2);margin-top:14px;font-family:'JetBrains Mono',monospace;">
|
||
$w_d\ge 0,\quad w_0=0,\quad \textstyle\sum w_d=1$</div>
|
||
<div class="li" style="font-size:25px;color:var(--ink2);">理想状态:整张饼都给线性那一块。</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 10 小结 -->
|
||
<section class="slide posCR">
|
||
<div class="glow"></div>
|
||
<div class="kicker"><span class="ln"></span>09 · 小结</div>
|
||
<h2>四句话<em>带走全场</em></h2>
|
||
<div class="content">
|
||
<div class="grid4">
|
||
<div class="g"><div class="n">01</div><div class="t">Hermite 是高斯世界的<b>频率分解工具</b>,类比傅里叶。</div></div>
|
||
<div class="g"><div class="n">02</div><div class="t"><b>正交性</b>让任意合理函数都能干净地拆成这些积木叠加。</div></div>
|
||
<div class="g"><div class="n">03</div><div class="t">OU 过程使相关性按 <b>ρᵈ</b> 指数衰减,高阶削减更狠。</div></div>
|
||
<div class="g"><div class="n">04</div><div class="t">最大化相关性 → 只留线性 → <b>线性可识别性</b>。</div></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 11 尾页 -->
|
||
<section class="slide cover posBL">
|
||
<div class="glow amber"></div>
|
||
<div class="kicker"><span class="ln"></span>下一站</div>
|
||
<h1 style="font-size:92px;margin-top:30px;">Mehler 公式<br><em>把直觉坐实</em></h1>
|
||
<p class="lead" style="margin-top:34px;font-size:30px;">下一讲深入 $\rho^d$ 衰减的来源 —— 它来自 OU 过程的转移核在 Hermite 基下的展开。</p>
|
||
<div class="meta">谢谢收听 · 配套音频 hermite_polynomials-podcast.mp3 · 我们下次见</div>
|
||
</section>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="nav">
|
||
<button id="prev">← 上一页</button>
|
||
<span class="pg" id="pg">1 / 11</span>
|
||
<button id="next">下一页 →</button>
|
||
</div>
|
||
|
||
<script>
|
||
const STAGE = document.getElementById('stage');
|
||
const slides = Array.from(document.querySelectorAll('.slide'));
|
||
const total = slides.length;
|
||
const KEY = 'hermite_deck_page';
|
||
|
||
// 读回上次页码
|
||
let cur = parseInt(localStorage.getItem(KEY) || '0', 10);
|
||
if (isNaN(cur) || cur < 0 || cur >= total) cur = 0;
|
||
|
||
function fit(){
|
||
const s = Math.min(window.innerWidth / 1920, window.innerHeight / 1080);
|
||
STAGE.style.transform = `scale(${s})`;
|
||
}
|
||
window.addEventListener('resize', fit); fit();
|
||
|
||
function show(i){
|
||
cur = (i + total) % total;
|
||
slides.forEach((s, idx) => s.classList.toggle('active', idx === cur));
|
||
document.getElementById('pg').textContent = `${cur + 1} / ${total}`;
|
||
// 进度条
|
||
const w = ((cur) / (total - 1) * 100).toFixed(1) + '%';
|
||
document.querySelectorAll('.page-footer .prog i').forEach(b => b.style.width = w);
|
||
localStorage.setItem(KEY, cur);
|
||
}
|
||
|
||
// 给每页注入页脚(带进度条)—— 封面/尾页也加,保持节奏统一
|
||
slides.forEach((s, idx) => {
|
||
const f = document.createElement('div');
|
||
f.className = 'page-footer';
|
||
f.innerHTML = `<span>Hermite 多项式 · 谱分解</span><span class="prog"><i></i></span><span>${String(idx+1).padStart(2,'0')} / ${String(total).padStart(2,'0')}</span>`;
|
||
s.appendChild(f);
|
||
});
|
||
|
||
document.getElementById('prev').addEventListener('click', () => show(cur - 1));
|
||
document.getElementById('next').addEventListener('click', () => show(cur + 1));
|
||
|
||
// 键盘
|
||
document.addEventListener('keydown', (e) => {
|
||
if (e.key === 'ArrowRight' || e.key === 'PageDown' || e.key === ' ') { e.preventDefault(); show(cur + 1); }
|
||
else if (e.key === 'ArrowLeft' || e.key === 'PageUp') { e.preventDefault(); show(cur - 1); }
|
||
else if (e.key === 'Home') show(0);
|
||
else if (e.key === 'End') show(total - 1);
|
||
else if (e.key === 'f' || e.key === 'F') {
|
||
if (!document.fullscreenElement) document.documentElement.requestFullscreen();
|
||
else document.exitFullscreen();
|
||
}
|
||
});
|
||
|
||
// 点击舞台右/左半屏翻页
|
||
document.getElementById('wrap').addEventListener('click', (e) => {
|
||
if (e.target.closest('.nav')) return;
|
||
if (e.clientX > window.innerWidth * 0.5) show(cur + 1); else show(cur - 1);
|
||
});
|
||
|
||
// KaTeX 渲染
|
||
function renderMath(){
|
||
if (window.renderMathInElement){
|
||
renderMathInElement(document.body, {
|
||
delimiters: [
|
||
{left:'$$', right:'$$', display:true},
|
||
{left:'$', right:'$', display:false}
|
||
],
|
||
throwOnError:false
|
||
});
|
||
} else { setTimeout(renderMath, 120); }
|
||
}
|
||
// URL 参数:?page=N(1-based 定位单页,用于截图/导出)、?clean=1(隐藏 UI)
|
||
const params = new URLSearchParams(location.search);
|
||
const pageParam = params.get('page');
|
||
if (pageParam !== null) {
|
||
const p = parseInt(pageParam, 10);
|
||
if (!isNaN(p) && p >= 1 && p <= total) cur = p - 1;
|
||
}
|
||
if (params.get('clean') === '1') {
|
||
document.body.classList.add('clean');
|
||
const navEl = document.querySelector('.nav'); if (navEl) navEl.style.display = 'none';
|
||
const hk = document.querySelector('.hintkey'); if (hk) hk.style.display = 'none';
|
||
}
|
||
|
||
window.addEventListener('DOMContentLoaded', () => { renderMath(); show(cur); });
|
||
// 兜底:若 DOMContentLoaded 已过
|
||
if (document.readyState !== 'loading') { renderMath(); show(cur); }
|
||
</script>
|
||
</body>
|
||
</html> |