iT邦幫忙

2021 iThome 鐵人賽

DAY 25
0
Modern Web

快搭上姐姐的`微`前端便車系列 第 25

第25車廂-讓pdf檔有翻頁效果!pdf.js+turn.js應用篇

  • 分享至 

  • xImage
  •  

本篇續第23篇介紹pdf.js讓前端可以看pdf檔及第24車廂介紹翻頁效果套件turn.js,整合兩篇將pdf檔翻頁起來!

看本篇之前,需看一下本系列文

第23車廂-在網頁中預覽pdf—pdf.js簡易版應用篇

  • 這篇是介紹使用pdf.js透過canvas或者viewer.js將pdf檔案秀在前端畫面裡,有範例檔
  • 翻頁無動畫

第24車廂-翻起來惹!頁面翻頁效果turn.js應用篇

  • 這篇是介紹使用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

  • 一樣先放外殼id="flipbook"
  • <div class="hard">Turn.js</div> 為封面,可加可不加
<div id="flipbook">
  <div class="hard">Turn.js</div> 
  <!-- 這邊會append canvas-->
</div>

CSS
範例沒有調整的完美,都可自行再調整

  • 外殼id="flipbook" 一定要放寬高,於CSS設定可指定為px 或 %,
  • <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

  • 程式碼參考pdf.js及turn.js整合起來
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


上一篇
第24車廂-翻起來惹!頁面翻頁效果turn.js應用篇
下一篇
第26車廂-眼睛眨啊眨~登入密碼的顯示/隱藏應用篇
系列文
快搭上姐姐的`微`前端便車30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
fufu
iT邦新手 5 級 ‧ 2023-05-02 15:00:02

不好意思可以請問一下
為什麼pdf只能載入前面5頁的內容?
以後的內容全部都為空白
要如何修改呢?

感謝

感謝您發現問題!已更改程式碼囉~

以下是我詢問ChatGPT的解法:
本來的問題與PDF.js中getPage()方法的非同步特性有關。getpdf(url)函式中的for迴圈遍歷頁面並呼叫setcanvas()函式來渲染每個頁面。然而,渲染過程是非同步的,迴圈在前一個頁面的渲染完成之前繼續執行。

為了解決這個問題,使用Promise確保所有頁面的渲染完成後再調用loadApp()函式。

我要留言

立即登入留言