app.jsx
import './App.css'
import * as pdfjs from "pdfjs-dist";
import "pdfjs-dist/web/pdf_viewer.css";
import { useEffect, useRef, useState } from 'react'
import { PDFViewer, PDFLinkService, EventBus } from 'pdfjs-dist/web/pdf_viewer';
pdfjs.GlobalWorkerOptions.workerSrc = 'https://cdn.bootcdn.net/ajax/libs/pdf.js/2.11.338/pdf.worker.min.js'
function App() {
useEffect(() => {
initPdfView();
}, [])
// pdfView自动缩放
const autoScale = (viewer) => {
// 缩放模式: "page-fit" ,"auto" ,"page-width"
viewer.currentScaleValue = 'page-width';
}
// 监听pdfView外部容器变化,主要是配合自动缩放
const onResize = (viewer) => {
const resizeObserver = new ResizeObserver(entries => { // 创建观察对象
autoScale(viewer) // entries[0].contentRect
});
resizeObserver.observe(containerRef.current); // 指定要观察的dom
}
// 定义一些页面所需变量
const [viewer, setViewer] = useState({});
const [page, setPage] = useState(1);
const [pages, setPages] = useState(0);
const containerRef = useRef(null);
/**
* 初始化pdfView
*/
const initPdfView = () => {
const pdfUrl = 'https://cos.dingshaohua.cn/aegis/1.pdf';
const linkService = new PDFLinkService();
const eventBus = new EventBus();
eventBus.on("pagesinit", (e) => {
onResize(e.source) // 同一次轮回 是拿不到view的,所以只能通过e.source取出
});
const newViewer = new PDFViewer({
container: containerRef.current, // 显示PDF的容器dom
linkService,
eventBus,
textLayerMode: 2,
renderer: "canvas",
});
linkService.setViewer(newViewer);
pdfjs.getDocument(pdfUrl).promise.then((pdf) => {
linkService.setDocument(pdf);
newViewer.setDocument(pdf);
setPages(pdf.numPages);
})
setViewer(newViewer)
}
/**
* 下一页
*/
const onNext = () => {
if (viewer.currentPageNumber < pages) {
viewer.currentPageNumber++;
setPage(viewer.currentPageNumber)
}
}
/**
* 跳转页面
*/
const onSkip = () => {
if (viewer.currentPageNumber < pages) {
viewer.currentPageNumber = page;
}
}
return (
<>
<div className='skip'>
<input type="number" value={page} onChange={(e) => { setPage(Number(e.target.value)) }} />/{pages}
<div onClick={onSkip}>跳转</div> <div onClick={onNext}>下一页</div>
</div>
<div ref={containerRef} className='container'>
<div id="viewer" className="pdfViewer"></div>
</div>
</>
)
}
export default App
app.css
.container{
position: absolute;
margin: auto;
left: 0;
right: 0;
width: 50%;
height: 100%;
overflow: auto;
}
.skip{
background-color: aqua;
width: 180px;
position: fixed;
right: 0;
top: 0;
padding: 10px;
display: flex;
z-index: 3;
}
.skip input{
width:20%;
}
.skip div{
background-color: gray;
cursor: pointer;
user-select: none;
margin-left: 10px;
}
效果