2026-05-14 22:41:52 +08:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
<html lang="zh-TW">
|
|
|
|
|
|
|
|
|
|
|
|
<head>
|
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
|
<title>水晶男孩|六六歌2 — 紀實電子書</title>
|
|
|
|
|
|
<link rel="stylesheet" href="../assets/css/style.css">
|
|
|
|
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../assets/css/tablet.css">
|
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
|
|
<body class="ebook-ssg2-page totoga2-page">
|
|
|
|
|
|
<header class="map-archive-header">
|
|
|
|
|
|
<div class="header-inner">
|
|
|
|
|
|
<h1 class="main-title">無限挑戰 · 六六歌2</h1>
|
|
|
|
|
|
<div class="subtitle-wrap">
|
2026-05-15 02:47:26 +08:00
|
|
|
|
<span class="sub-title">水晶男孩回來啦!</span>
|
2026-05-14 22:41:52 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
|
|
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
|
|
|
|
|
|
|
|
|
|
|
|
<canvas id="particles"></canvas>
|
|
|
|
|
|
|
|
|
|
|
|
<nav class="ebook-back-link content-container totoga2-split-crossnav" aria-label="六六歌2 複本分頁">
|
2026-05-15 14:50:20 +08:00
|
|
|
|
<a href="totoga2-video.html" class="btn">節目影片</a>
|
2026-05-14 22:41:52 +08:00
|
|
|
|
<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>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="content-container ebook-main">
|
|
|
|
|
|
<section class="ebook-intro section" aria-label="電子書說明">
|
|
|
|
|
|
<h2 class="section-title">紀實電子書</h2>
|
|
|
|
|
|
<p class="ebook-intro-lead">
|
2026-05-15 14:50:20 +08:00
|
|
|
|
以下為《無限挑戰》六六歌2 紀實跨頁 PDF(以 PDF.js 載入、PageFlip 翻頁)。若載入較慢請稍候;請以本機伺服器開啟頁面(勿用 file://),否則 PDF 可能被瀏覽器擋下。
|
2026-05-14 22:41:52 +08:00
|
|
|
|
</p>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
2026-05-15 14:50:20 +08:00
|
|
|
|
<!-- <div class="flip-ebook-shell">
|
2026-05-14 22:41:52 +08:00
|
|
|
|
<div class="flip-ebook-aspect">
|
2026-05-15 14:50:20 +08:00
|
|
|
|
<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>
|
2026-05-14 22:41:52 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<p class="ebook-back-link content-container">
|
|
|
|
|
|
<a href="../index.html#story" class="btn">回到首頁 · 傳奇的轉折</a>
|
2026-05-15 14:50:20 +08:00
|
|
|
|
<a href="totoga2-video.html" class="btn">節目影片(另頁)</a>
|
2026-05-14 22:41:52 +08:00
|
|
|
|
<a href="totoga2-copy-timeline.html" class="btn">時間軸+八章(另頁)</a>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
<footer>
|
|
|
|
|
|
<p>SECHSKIES Fanpage © 2026 - 黃色氣球永遠飄揚</p>
|
|
|
|
|
|
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank">
|
|
|
|
|
|
Design by <span class="mark_b">Jekkinoopy Studio</span>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</footer>
|
|
|
|
|
|
|
|
|
|
|
|
<script src="../assets/js/particles.js"></script>
|
|
|
|
|
|
<script src="../assets/js/portal-nav.js"></script>
|
2026-05-15 14:50:20 +08:00
|
|
|
|
<!-- 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('PageFlip(St.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>
|
|
|
|
|
|
|
2026-05-14 22:41:52 +08:00
|
|
|
|
</body>
|
|
|
|
|
|
|
2026-05-15 14:50:20 +08:00
|
|
|
|
</html>
|