feat 電子書

This commit is contained in:
2026-05-15 14:50:20 +08:00
parent 95dabb9389
commit 904f3ebffd
27 changed files with 231 additions and 121 deletions
+100 -7
View File
@@ -25,7 +25,7 @@
<canvas id="particles"></canvas>
<nav class="ebook-back-link content-container totoga2-split-crossnav" aria-label="六六歌2 複本分頁">
<a href="totoga2-copy-video.html" class="btn">節目影片</a>
<a href="totoga2-video.html" class="btn">節目影片</a>
<a href="totoga2-copy-ebook.html" class="btn" aria-current="page">紀實電子書</a>
<a href="totoga2-copy-timeline.html" class="btn">時間軸+長文</a>
<a href="totoga2%20copy.html" class="btn">複本總覽</a>
@@ -35,21 +35,28 @@
<section class="ebook-intro section" aria-label="電子書說明">
<h2 class="section-title">紀實電子書</h2>
<p class="ebook-intro-lead">
以下為《無限挑戰》六六歌2 相關跨頁電子書(FlipHTML5)。若載入較慢請稍候或重新整理;全螢幕閱讀請使用閱讀器內建控制項
以下為《無限挑戰》六六歌2 紀實跨頁 PDF(以 PDF.js 載入、PageFlip 翻頁)。若載入較慢請稍候;請以本機伺服器開啟頁面(勿用 file://),否則 PDF 可能被瀏覽器擋下
</p>
</section>
<div class="flip-ebook-shell">
<!-- <div class="flip-ebook-shell">
<div class="flip-ebook-aspect">
<iframe src="https://online.fliphtml5.com/tjyxm/vqff/"
title="2023_電子書_無限挑戰六六歌2_final跨頁" allowfullscreen></iframe>
<iframe src="https://online.fliphtml5.com/tjyxm/vqff/" title="2023_電子書_無限挑戰六六歌2_final跨頁"
allowfullscreen></iframe>
</div>
</div> -->
<div class="flip-ebook-shell">
<div id="book-container" class="flip-ebook-aspect flip-ebook-aspect--pageflip">
<!-- PDF.js + PageFlip 會在此產生頁面 -->
<div id="my-flipbook"></div>
</div>
</div>
</div>
<p class="ebook-back-link content-container">
<a href="../index.html#story" class="btn">回到首頁 · 傳奇的轉折</a>
<a href="totoga2-copy-video.html" class="btn">節目影片(另頁)</a>
<a href="totoga2-video.html" class="btn">節目影片(另頁)</a>
<a href="totoga2-copy-timeline.html" class="btn">時間軸+八章(另頁)</a>
</p>
@@ -62,6 +69,92 @@
<script src="../assets/js/particles.js"></script>
<script src="../assets/js/portal-nav.js"></script>
<!-- 1. 引入 PDF.js 核心庫 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
<!-- 2. 引入 PageFlip -->
<script src="https://cdn.jsdelivr.net/npm/page-flip/dist/js/page-flip.browser.js"></script>
<script>
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';
/** 專案內實際存在的 PDF(原 totoga2/ebook/totoga2_ebook.pdf 尚未建檔) */
var EBOOK_PDF_URL = '../assets/images/totoga2/totoga2.pdf';
function showEbookError(message) {
var box = document.getElementById('my-flipbook');
if (!box) return;
box.innerHTML = '<p class="ebook-pdf-error" role="alert">' + message + '</p>';
}
async function initEbook(pdfUrl) {
var container = document.getElementById('my-flipbook');
if (!container) throw new Error('找不到 #my-flipbook');
if (typeof pdfjsLib === 'undefined') throw new Error('PDF.js 未載入');
if (typeof St === 'undefined' || !St.PageFlip) throw new Error('PageFlipSt.PageFlip)未載入');
var loadingTask = pdfjsLib.getDocument(pdfUrl);
var pdf = await loadingTask.promise;
/* 第 1 頁為封面;內文比例以第 2 頁為準(與 PageFlip showCover 一致) */
var sizePageIndex = pdf.numPages >= 2 ? 2 : 1;
var sizePage = await pdf.getPage(sizePageIndex);
var natural = sizePage.getViewport({ scale: 1 });
var shell = document.querySelector('.flip-ebook-shell');
var maxW = Math.min((shell && shell.clientWidth) || 1000, 1000) - 8;
var pageW = Math.max(320, Math.floor(maxW));
var pageH = Math.floor(pageW * (natural.height / natural.width));
var maxH = Math.floor(window.innerHeight * 0.72);
if (pageH > maxH) {
pageH = maxH;
pageW = Math.floor(pageH * (natural.width / natural.height));
}
var renderScale = (pageW / natural.width) * Math.min(window.devicePixelRatio || 1, 2);
for (var i = 1; i <= pdf.numPages; i++) {
var page = await pdf.getPage(i);
var viewport = page.getViewport({ scale: renderScale });
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
await page.render({ canvasContext: context, viewport: viewport }).promise;
var pageElement = document.createElement('div');
pageElement.className = 'page';
if (i === 1) {
pageElement.setAttribute('data-density', 'hard');
} else if (i === pdf.numPages) {
pageElement.setAttribute('data-density', 'hard');
}
pageElement.appendChild(canvas);
container.appendChild(pageElement);
}
var pageFlip = new St.PageFlip(container, {
width: pageW,
height: pageH,
size: 'stretch',
// PDF 每個 page 本身已是「A4*2 的攤開幅面」;避免 StPageFlip 在橫向模式下把頁寬視為總寬一半
// 導致看起來像把兩頁攤在一起、寬度被切半。
usePortrait: true,
showCover: true,
startPage: 0,
drawShadow: true,
maxShadowOpacity: 0.4
});
pageFlip.loadFromHTML(document.querySelectorAll('#my-flipbook .page'));
}
initEbook(EBOOK_PDF_URL).catch(function (err) {
console.error(err);
showEbookError(
'電子書 PDF 無法載入或翻頁初始化失敗。若用本機直接開檔案(file://),請改由本機伺服器開啟;並確認路徑存在:<code>'
+ EBOOK_PDF_URL + '</code>'
);
});
</script>
</body>
</html>
</html>