因为最后渲染页面属于自己的定做的,因此这里根据直接引用 pdfjs-dist
中的软件,只解决canvas 3D渲染一部分,其它功能在这个基础上自主订制,下边遇到的困难也就是在应用软件开展 canvas 3D渲染时遇到的问题
1、工程项目连接 pdfjs 的时候在安卓系统60版本号下3D渲染不成功,并出错
因为 pdfjs-dist 中词法较高,如带有 ||= 等高端词法,因此在使用过程中,需要大量的给pdfjs-dist开展 babel 再编译程序。
在webpack 里的rule下新增加下列一部分,应注意应用"@babel/preset-env"
的时候需要设定 modules
为 commonjs
,不然默认设置 auto
的现象编译程序出来的编码是不能直接所使用的
{
test: /.m?js$/,
include: [
path.resolve("node_modules/pdfjs-dist/"),
],
use: {
loader: "babel-loader",
options: {
presets: [
[
require("@babel/preset-env"),
{
modules: "commonjs"
}
]
],
plugins: ["@babel/plugin-transform-runtime"]
}
}
},
2、node条件下一部分型号应用 pdfjs 时没法3D渲染,如洪蒙 p30
认证的时候发现使用中提醒
structuredClone is not defined
发觉 structuredClone
的兼容模式很差,不知为什么上边配备的 babel 降权怎么没把这个词法给下降。
查询 github 官方网 issue ,发觉的确有这种情况,在使用过程中应用 pdfjs-dist/legacy/build
下边相对应的文档就可以处理,官方文档里也有相对应的表明。
然后我就沉默了一下,发现这目录下可以解决兼容性问题,那样 难题1 是否也能通过这一问题改进,随后证明了一下,发觉真不可以,有一些词法仍然需要做 babel 解决,如 Private class fields
等高端词法依然在该版本号软件下应用
3、node条件下应用 pdf.worker.js,无出错,亦无3D渲染
因为在 node 条件下可以将 pdf.worker.js
设为 pdfjs
的 GlobalWorkerOptions.workerSrc
没法起效,因此这里要应用 pdf.worker.entry.js
做为 workerSrc
,相匹配 issue
这里留意采用的是 legacy
中的或是 build
中的需要和 pdfjs
提及的保持一致
4、容积难题
直接用软件时体积大,充分考虑应用min版本号时,pdf.work.entry
并没有相对应的min版本号,查看源码如下所示:
(typeof window !== "undefined"
? window
: {}
).pdfjsWorker = require("./pdf.worker.js");
那我使用中是不是立即按上述方法调节,来减少 worker 的相对应的容积呢,现象能,整理资料发觉,重量的增加量基本上就在那 worker 体积上展现了
const pdfjsLib = require("pdfjs-dist/legacy/build/pdf.min.js");
pdfjsLib.GlobalWorkerOptions.workerSrc = (typeof window !== "undefined"
? window
: {}
).pdfjsWorker = require("pdfjs-dist/legacy/build/pdf.worker.min.js");
原工程项目 | 1119k | ||
---|---|---|---|
连接build版本 | 3538k | 2419k | |
连接 legacy 版本号 | 4035k | 3916k | |
worker min 版本号 | worker 非 min 版本号 | ||
连接build min 版本号 | 2450k 1331k | 3657k 2538k | |
连接 legacy min 版本号 | 2793k 1674k | 3735k 3616k |
依据工程项目的兼容模式和容积要求,现阶段尝试使用 连接 legacy 的 min 版本号且 worker min 版本号
5、跨域问题
当 pdfjs 载入远程控制pdf时,免不了会有 CORS 跨域请求问题,3种解决方法,关键也是通过下载文件之后再浏览去解决
1、将 pdf 下载到当地,放进施工中开展当地引入,该方式不但提升工程项目容积,还没灵便
2、将 pdf 下载到静态资源服务器上,在施工中浏览静态资源网络服务器里的数据进行完成,该方式必须手动控制,较为低效能
3、根据启用网络服务器插口由服务器进行资源分享,待下载完了后通过网络服务器给予相对应的资源 ArrayBuffer
开展浏览,该方式非常灵活
根据我们工程项目的现况, 选了第三种方法
附则
实际上仿佛绝大多数难题都能在官方网表明中找到,只不过是遇到的困难可能会在文档里没说那样细,但细搜索下 issue 也是可以寻找相匹配解决方案。
下边简单写个应用的事例吧
const pdfjsLib = require("pdfjs-dist/legacy/build/pdf.min.js");
pdfjsLib.GlobalWorkerOptions.workerSrc = (typeof window !== "undefined"
? window
: {}
).pdfjsWorker = require("pdfjs-dist/legacy/build/pdf.worker.min.js");
function init(data) {
// data能够为url,还可以为服务器端返回 arrayBuffer 或服务器端返回 base64,前面转 arrayBuffer
try {
const loadingTask = pdfjsLib.getDocument(data);
this.pdf = await loadingTask.promise;
this.pageNum = await this.pdf.numPages || 0;
console.log('pageNum', this.pageNum)
this.initCanvas();
this.renderPdf(1);
} catch (err) {
this.onError({
message: "pdf 文档加载失败",
code: 1
})
}
}
function renderPdf(num = 1) {
this.pdf.getPage(num).then((page) => {
// 设定canvas有关的特性
const canvas = document.getElementById("pdfCanvas_" num);
const ctx = canvas.getContext("2d", {
alpha: false
});
const dpr = window.devicePixelRatio || 1;
const bsr =
ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||
1;
const ratio = dpr / bsr;
const viewport = page.getViewport({ scale: this.pdfScale * ratio }); // 设定放大比例
const viewRatio = viewport.height / viewport.width;
canvas.width = viewport.width * ratio;
canvas.height = viewport.height * ratio;
canvas.style.width = (this.container.clientWidth - 20) * this.pdfScale "px";
canvas.style.height = (this.container.clientWidth - 20) * viewRatio * this.pdfScale "px";
ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
const renderContext = {
canvasContext: ctx,
viewport: viewport
};
// 数据渲染到canvas画板上
page.render(renderContext);
if (this.pageNum > num) {
setTimeout(() => {
return this.renderPdf(num 1);
});
}
});
}
本站是一个以CSS、JavaScript、Vue、HTML为中心的前端开发技术网址。我们的使命是为众多前端工程师者提供全方位、全方位、好用的前端工程师专业知识和技术服务。
在网站上,大家可以学到最新前端开发技术,掌握前端工程师最新发布的趋势和良好实践。大家提供大量实例教程和实例,让大家可以快速上手前端工程师的关键技术和程序。
本站还提供了一系列好用的工具软件,帮助你更高效地开展前端工程师工作中。公司提供的一种手段和软件都要经过精心策划和改进,能够帮助你节约时间精力,提高研发效率。
此外,本站还拥有一个有活力的小区,你可以在社区里与其它前端工程师者沟通交流技术性、交流经验、处理问题。我们坚信,街道的能量能够帮助你能够更好地进步与成长。
在网站上,大家可以寻找你需要的一切前端工程师网络资源,使您成为一名更加出色的网页开发者。欢迎你添加我们的大家庭,一起探索前端工程师的无限潜能!