本篇續第23篇介紹pdf.js讓前端可以看pdf檔及第24車廂介紹翻頁效果套件turn.js,整合兩篇將pdf檔翻頁起來!
看本篇之前,需看一下本系列文
- 這篇是介紹使用pdf.js透過canvas或者viewer.js將pdf檔案秀在前端畫面裡,有範例檔
- 翻頁無動畫
- 這篇是介紹使用turn.js可以模擬出翻頁效果的畫面,有turn.js參數介紹
- 翻頁有動畫,可放圖片或文字,無法放pdf檔
而這篇要介紹的是
使用pdf.js + turn.js 匯入pdf檔
,並實現翻頁效果
此篇不會介紹詳細的參數說明,可往系列文看
▼完成圖
引用
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js'></script>
<script src='https://mozilla.github.io/pdf.js/build/pdf.js'></script>
<script src='http://www.turnjs.com/lib/turn.min.js'></script>
※這邊有一個問題,假如turn.js用的是https://cdnjs.cloudflare.com/ajax/libs/turn.js/3/turn.js
會有問題,所以只好先用http://www.turnjs.com/lib/turn.min.js
HTML
<div class="hard">Turn.js</div>
為封面,可加可不加<div id="flipbook">
<div class="hard">Turn.js</div>
<!-- 這邊會append canvas-->
</div>
CSS範例沒有調整的完美,都可自行再調整
<canvas>
設定為{max-width: 100%;height: 100%;} 是讓它高度=外殼"flipbook"高度,寬度自動縮放,否則比例會不對;設auto沒用,因為放<canvas>
的殼是被下了position: absolute; html,body{
overflow:hidden;
height: 100%;
}
#flipbook{
width:960px; //自行設定
height:500px; //自行設定
background-color:#000;
}
#flipbook .page{
width:100%;
height:auto;
background-color:white;
font-size:20px;
text-align:center;
}
#flipbook .hard{
background:#ccc !important;
color:#333;
font-weight:bold;
}
#flipbook .odd{
background:-webkit-gradient(linear, right top, left top, color-stop(0.95, #FFF), color-stop(1, #DADADA));
box-shadow:inset 0 0 5px #666;
}
#flipbook .even{
background:-webkit-gradient(linear, left top, right top, color-stop(0.95, #fff), color-stop(1, #dadada));
box-shadow:inset 0 0 5px #666;
}
canvas{
max-width: 100%;
height: 100%;
}
JS/JQ
var url = 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf'; //你要放的pdf檔
var flipbook = document.getElementById('flipbook');
var scale = 1.5; //可靠這個修改canvas解析度
window.onload = function(){
getpdf(url);
}
function getpdf(url){
var pdfjsLib = window['pdfjs-dist/build/pdf'];
pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js'; //
若是下載在自己的本端,這邊src為自己專案中worker.js的路徑
var loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise.then(function(pdf) { //根據總頁數新增固定的div和canvas
console.log("總頁數",pdf.numPages);
for (let i = 1; i <= pdf.numPages;i++) {
let id = 'canvaspage' + i;
let div = document.createElement('div');
div.innerHTML = '<canvas id="' + id + '"></canvas>';
flipbook.append(div);
setcanvas(i,pdf,id);
}
//呼叫turn方法
loadApp()
})
}
//將pdf新增到canvas裡面
function setcanvas(i,pdf,id){
pdf.getPage(i).then(function(page) {
var viewport = page.getViewport({scale: scale});
let canvas = document.getElementById(id);
let context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
let renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
})
}
function loadApp() {
$(flipbook).turn({
autoCenter: true,//是否置中
//display: 'single',//單頁顯示
});
}
//當畫面縮放時,要改變外殼大小,如果你想固定,不一定要加
window.addEventListener('resize',function(e){
flipbook.style.width="";
flipbook.style.height="";
$(flipbook).turn("size", window.innerWidth,window.innerHeight*0.8);
})
這樣就完成啦!
附上程式碼
本篇參考文章:
https://www.itread01.com/content/1545973866.html
不好意思可以請問一下
為什麼pdf只能載入前面5頁的內容?
以後的內容全部都為空白
要如何修改呢?
感謝
感謝您發現問題!已更改程式碼囉~
以下是我詢問ChatGPT的解法:
本來的問題與PDF.js中getPage()方法的非同步特性有關。getpdf(url)函式中的for迴圈遍歷頁面並呼叫setcanvas()函式來渲染每個頁面。然而,渲染過程是非同步的,迴圈在前一個頁面的渲染完成之前繼續執行。
為了解決這個問題,使用Promise確保所有頁面的渲染完成後再調用loadApp()函式。