目录
1、安装并使用 pdfjs-dist、pubsub-js,初始化工作
6、点击左侧略缩图列表中的某略缩页,中间的展示区滚动到该页的位置
0、简单效果展示

1、安装并使用 pdfjs-dist、pubsub-js,初始化工作
安装pdfjs-dist:
npm i pdfjs-dist
引入并配置工作者源文件:
import * as PDF from 'pdfjs-dist'
import workerSrc from 'pdfjs-dist/build/pdf.worker.entry'
PDF.GlobalWorkerOptions.workerSrc = workerSrc;
安装 pubsub-js(消息订阅与发布):
npm i pubsub-js
引入到项中:
import pubsub from 'pubsub-js'
定义一个用于包裹绘制 pdf 的 canvas 列表的容器:
// 承装所有 canvas 的容器的类名
const allCanvasParentNodeClassName = 'canvas-parent-container';
2、使用 pdfjs-dist 绘制给定PDF的首页或整体
封装函数 displayPDF 实现该功能。
该函数接收六个参数:
(1)给定 pdf 的地址;
(2)承载要展示pdf区域的父元素(dom);
(3)是否展示完整个pdf(false 就是只展示 pdf 的首页);
(4)指定 canvas 的类名(PDF的每一页都会在一个canvas画布上绘制,为这一组画布确定一个共同的类名);
(5)自定义pdf的缩放倍数;
(6)pdf渲染完成后的一个回调函数。
/*
绘制整个pdf,一个canvas绘制一页
传入 pdf 的地址、父容器标签元素、是否展示全部(false 即展示首页) 、指定canvas类名, 自定义缩放大小、自定义内联样式
*/
function displayPDF(pdfURL, parentNode, isAllPages, canvasClassName, customScale, callback){
// 使用 PDF 加载指定的 .pdf 文档
const loadingTask = PDF.getDocument(pdfURL);
loadingTask.promise.then(async pdf=>{
// pdf._pdfInfo.numPages 为 pdf 的总页数,isAllPage 为boolean值,表示是否展示全部
const pageNumber = isAllPages ? pdf._pdfInfo.numPages : 1;
/*
当前显示设备的物理像素分辨率与CSS像素分辨率之比,它告诉浏览器应使用多少屏幕实际像素来绘制单个CSS像素
<canvas>可能在视网膜屏幕上显得太模糊。 使用window.devicePixelRatio确定应添加多少额外的像素密度以使图像更清晰。
*/
const outputScale = window.devicePixelRatio || 1;
const allCanvasParentNode = document.createElement('div');
allCanvasParentNode.className = allCanvasParentNodeClassName;
allCanvasParentNode.style = `
width: 100%;
height: 100%;
overflow: auto;
padding: 0;
margin: 0;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
`
// 将 canvas 列表的容器添加到给定的容器中
parentNode.appendChild(allCanvasParentNode);
// 根据 isAllPages 确定渲染多少页
mainAreaAsyncRender(pdf, pageNumber, 1, customScale, canvasClassName, outputScale, allCanvasParentNode, callback);
})
}
其中 mainAreaAsyncRender 函数为解决 pdf 页面异步渲染的一个方案。即 使 PDF 的每一页在渲染完成后,都可以直接呈现到页面上,不必等待 PDF 的所有页面都渲染完成再一次过呈现到页面上(这种一般直接使用 for 循环来完成),避免用户过多的等待。
该函数接收以下几个参数:
(1)使用 pdfjs-dist 的 getDocument 加载后进行期约构造成功后返回的 pdf 对象;
(2)当前 pdf 的总页数;
(3)当前所绘制的是第几页;
(4)自定义的缩放比例;
(5)自定义的 canvas 类名;
(6)当前显示设备的物理像素分辨率与CSS像素分辨率之比;
(7)承装所有 canvas 的容器(dom元素);
(8)所有页面渲染完成后执行的回调函数(这里设置回调函数有一个参数,为该pdf的总页数,用于展示pdf的总页数);
// 主要展示区 异步渲染解决方案,使之一上来就有页面
async function mainAreaAsyncRender(pdf, pageNumber, i, customScale, canvasClassName, outputScale, allCanvasParentNode, callback){
// 获取 pdf 指定页
let page = await pdf.getPage(i);
// 设置 canvas 整体缩放的倍数
let scale = customScale || 1.4;
let viewport = page.getViewport({ scale });
// 创建 canvas 共同的容器
let canvas = document.createElement('canvas');
canvas.className = canvasClassName || '';
let context = canvas.getContext("2d");
// 设置 canvas 和内容 大小
canvas.width = Math.floor(viewport.width * outputScale);
canvas.height = Math.floor(viewport.height * outputScale);
canvas.style.width = Math.floor(viewport.width) + "px";
canvas.style.height = Math.floor(viewport.height) + "px";
canvas.style.margin = '10px 0';
let transform = (outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null);
// 将指定页渲染到 canvas
let renderContext = {
canvasContext: context,
transform,
viewport,
};
page.render(renderContext);
// 将当前 canvas(当前页) 添加到父容器中
allCanvasParentNode.appendChild(canvas);
i++;
if(i <= pageNumber){
requestAnimationFrame(()=>
mainAreaAsyncRender(pdf, pageNumber, i, customScale, canvasClassName, outputScale, allCanvasParentNode, callback));
}else{
// 传入 pdf 总页数
if(callback) callback(pdf._pdfInfo.numPages);
// 发布渲染完成的消息
pubsub.publish('renderFinish');
}
};
渲染完成后, 发布消息 ‘renderFinish’ 告诉组件渲染已完成。
3、侧边的略缩图列表
/*
侧边导航略缩图
参数:pdf地址、父容器元素、中心展示区域设置的canvas的类名,设置当前canvas的类名,自定义当前canvas列表的缩放大小,回调函数
*/
function displayPDFLeftNav(pdfURL, parentNode, centerAreaCanvasClassName, canvasClassName, customScale){

本文详细介绍了如何利用pdfjs-dist库和pubsub-js消息订阅库,实现PDF文档的分页渲染、侧边略缩图列表、中心区域PDF的缩放以及页面滚动功能。关键步骤包括初始化工作、PDF页面的异步渲染、略缩图列表的生成、PDF区域的放大缩小以及页面跳转操作。代码示例展示了具体实现过程。
最低0.47元/天 解锁文章
5710

被折叠的 条评论
为什么被折叠?



