vue3中使用pdf.js、实现移动端、PC端的PDF预览、支持绝大部分情况

业务场景

pdf.js可以说是预览PDF的全能插件,里面内置了很多方法供开发者使用。
之前一直使用的pdf.js+canvas的形式预览PDF,但是这有一个很大的弊端,就是canvas生成的图片太糊了,而且本质上这渲染的根本不是pdf,而是一张图片,很多pdf中带有的功能这里都不能实现
比如

  1. pdf全局搜索
  2. 缩小放大任能保持清晰度
  3. 指定页跳转,上下一页
  4. 对当前预览的文件,开启在线演示模式
  5. 支持在 viewer.html 添加水印
  6. …等等操作

本文只做最基础的,能让你在移动端,PC端正常预览PDF的功能,扩展操作不做解释

下载pdf.js源码

最新版下载地址,下载哪个自己选择,我没有细看他们之间的区别,我选择的下载第一个
在这里插入图片描述

历史版本下载地址
如果你需要下载历史版本的话,选择你想要的版本,点击Downloads进入下载页面
在这里插入图片描述
这里会告诉你这个版本都做哪些优化或者其他工作,之后拉到页面最下面,点击下载第一个

在这里插入图片描述
下载完成之后你会得到一个压缩包,(你可能会好奇,为什么不直接npm install这种下载形式,而要下载一个压缩包,没关系继续看)
会得到一个这样目录的压缩包
在这里插入图片描述
build文件夹
在这里插入图片描述
web文件夹
在这里插入图片描述
OK,到这里已经完成pdf.js的下载工作
接下来我会使用vite脚手架搭建一个新的vue3项目作为演示

引入PDF.JS并使用他来预览我们的第一份PDF文件

这是我创建的一个空的vue3项目,刚初始化完成的,我新建了一个 pdfJSDemo.vue 文件作为演示的入口

在这里插入图片描述
现在,将我们刚才下载好的pdf.js文件,放到项目的public文件下新建的pdfJS文件中(是不是public文件都无所谓,这里作为演示)
注意这里的viewer.html文件,你可能在其他博客中见到这个文件,他们指的都是这个文件,我们之后所有的操作都要针对这个文件进行
在这里插入图片描述
我们先打开一个pdf.js给我们提供的默认pdf看看效果,也就是下面这个文件

在这里插入图片描述
打开的方式是,启动你项目之后的 开发地址 + pdfJS/web/viewer.html (如果你是按照我的文件夹目录来的话,可以直接复制)

在这里插入图片描述
这是我的启动地址,所以拼接的地址就是 http://localhost:5173/pdfJS/web/viewer.html

如果你成功打开了这个页面,且没有任何报错,那就表示你的第一个预览PDF已经完成了

在这里插入图片描述

那么接下来我们来打开一个自己的PDF吧,自己的PDF有两种形式

  1. 本地的PDF文件,展示在页面上(那操作就和上面一模一样了,没啥好说的,重复上面的步骤就行)
  2. 后端返回的PDF链接,需要我们展示在页面上(这里以阿里云的PDF链接为例)

第二种预览形式,只需要在上面的连接上加上一个file=your-pdf-url就行了:开发地址 + pdfJS/web/viewer.html?file=your-pdf-url

举个例子 http://localhost:5173/pdfJS/web/viewer.html?file=http://wuneng-public.oss-cn-hangzhou.aliyuncs.com/wp/infoConfig/demo/NKRRQUGX20230908050411

这时,你可能会出现这么一个错误,然后pdf无法正确渲染出来,这是因为这个pdf链接发生了跨域

在这里插入图片描述

你要找到 throw new Error("file origin does not match viewer's"); 这段代码,并注释掉

在这里插入图片描述
保存之后刷新页面,这样一个链接形式的pdf就被渲染出来了

在这里插入图片描述

手机端的一个bug问题

因为我们使用pdfjs主要是解决手机端浏览器无法预览PDF的情况,但是pdfjs在手机端浏览器上有点bug

这是我使用微信浏览器打开的pdfjs官网给的一个demo页面,当在手机上进行缩放的时候,会导致显示错乱的情况,下面的图应该能很清楚的看到错乱情况
且很多其他浏览器,比如手机端的chrome浏览器,Safari浏览器,夸克浏览器会出现不同情况的缩放问题,总之很诡异。虽然官网上说他们的插件主要支持火狐浏览器,但是我试了火狐浏览器,还是有问题

请添加图片描述

手机端缩放bug,我的解决方式

  1. 限制页面不能进行缩放user-scalable=no,这可以避免(Chrome、Safari浏览器之类的缩放问题)
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  1. 设置页面属性zoom为1
body {
  zoom: 1; /* 设置缩放比例为1,即不缩放 */
}
  1. 根据页面的按钮点击事件,找到对应的源码,修改源码的缩放事件

我的理解是,在手机端使用手势缩放放大缩小pdf后,出现了错乱的情况,这时候我再手动调用一下源码中自带的 update 方法

在这里插入图片描述

我在源码中加了一个被我隐藏的按钮,并为其添加点击事件,在缩放完成后,调用点击事件,完成pdf的更新

 .myBtn {
   position: absolute;
   opacity: 0;
 }

在这里插入图片描述
viewer.js源码文件里,在这里添加根据 ID 获取 DOM 元素
在这里插入图片描述
viewer.js源码文件里,这一段代码中,注册DOM元素的点击事件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
有很多地方的事件注册,我这里应该是截图完了,单也可能是哪里忘记截图了

  1. 手势结束事件后,手动触发upadte事件
const c_viewerContainer = document.getElementById('viewer')

c_viewerContainer.addEventListener('touchend', handleTouchEnd, false)

// 手势结束事件
function handleTouchEnd(event) {
  myBtnUpdate.click()
}

抛砖引玉,我这个方法虽然可以解决,但是太僵硬了,为了解决而解决,肯定是有更好的办法的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue2使用Hammer.js实现移动端div的拖拽、放大缩小和旋转可以按照以下步骤进行。 首先,在Vue项目安装Hammer.js。 ``` npm install hammerjs ``` 然后,在需要使用拖拽、放大缩小和旋转功能的组件引入Hammer.js,并初始化一个Hammer实例,将其绑定到要拖拽、放大缩小和旋转的div元素上。 ``` import Hammer from 'hammerjs' export default { mounted() { const element = this.$refs.element // 获取div元素的引用 const mc = new Hammer.Manager(element) // 初始化Hammer实例并将其绑定到div元素上 // 添加拖拽、放大缩小和旋转的手势识别 mc.add(new Hammer.Pan({ threshold: 0, pointers: 0 })) mc.add(new Hammer.Pinch({ threshold: 0 })).recognizeWith(mc.get('pan')) mc.add(new Hammer.Rotate({ threshold: 0 })).recognizeWith(mc.get('pan')) // 初始化div元素的拖拽、放大缩小和旋转的初始状态值 let posX = 0 let posY = 0 let scale = 1 let lastScale = 1 let rotation = 0 // 监听拖拽事件 mc.on('pan', (e) => { // 实现拖拽 posX = e.deltaX posY = e.deltaY element.style.transform = `translate(${posX}px, ${posY}px) scale(${scale}) rotate(${rotation}deg)` }) // 监听放大缩小事件 mc.on('pinch', (e) => { // 实现放大缩小 scale = lastScale * e.scale element.style.transform = `translate(${posX}px, ${posY}px) scale(${scale}) rotate(${rotation}deg)` }) // 监听旋转事件 mc.on('rotate', (e) => { // 实现旋转 rotation = e.rotation element.style.transform = `translate(${posX}px, ${posY}px) scale(${scale}) rotate(${rotation}deg)` }) } } ``` 最后,在该组件的模板添加一个div元素,并给其添加初始样式。 ``` <template> <div ref="element" style="width: 200px; height: 200px; background-color: red;"></div> </template> ``` 这样,当你在移动端上访问这个页面时,就可以拖拽、放大缩小和旋转这个div元素了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值