UNPKG

react-typescript-pdf-reader

Version:
207 lines (172 loc) 5.89 kB
import * as React from 'react'; import './PDFReader.css'; const PDFJS = require('pdfjs-dist') // tslint:disable-line /** * PDFReader * * @class PDFReader * @extends {React.Component<PDFReaderProps, PDFReaderState>} */ interface PDFReaderProps { pdfUrl?: string; } interface PDFReaderState { pdfUrl?: string; } class PDFReader extends React.Component<PDFReaderProps, PDFReaderState> { refs!: { canvas: HTMLCanvasElement, prev: HTMLElement, next: HTMLElement, page_num: HTMLElement, page_count: HTMLElement, zoomin: HTMLElement, zoomout: HTMLElement, downloadpdf: HTMLElement }; constructor(props: PDFReaderProps) { super(props); let pdfUrl = this.props.pdfUrl; if (pdfUrl && pdfUrl !== undefined ) { setTimeout(() => { this.readPDF(); }, 0); } } readPDF = () => { let url = this.props.pdfUrl; // Disable workers to avoid yet another cross-origin issue (workers need // the URL of the script to be loaded, and dynamically loading a cross-origin // script does not work).let canvas =this.refs.canvas PDFJS.disableWorker = true; let pdfDoc: any, pageNum = 1, pageRendering = false, pageNumPending: any, scale = 1, canvas = this.refs.canvas, ctx = canvas.getContext('2d'); /** * Get page info from document, resize canvas accordingly, and render page. * @param num Page number. */ let renderPage = (num: any) => { pageRendering = true; // Using promise to fetch the page pdfDoc.getPage(num).then((page: any) => { let viewport = page.getViewport(scale); canvas.height = viewport.height; canvas.width = viewport.width; // Render PDF page into canvas context let renderContext = { canvasContext: ctx, viewport: viewport }; let renderTask = page.render(renderContext); // Wait for rendering to finish renderTask.promise.then(() => { pageRendering = false; if (pageNumPending !== null && pageNumPending) { // New page rendering is pending renderPage(pageNumPending); pageNumPending = null; } }); }); // Update page counters this.refs.page_num.textContent = String(pageNum); }; /** * If another page rendering in progress, waits until the rendering is * finised. Otherwise, executes rendering immediately. */ function queueRenderPage(num: any) { if (pageRendering) { pageNumPending = num; } else { renderPage(num); } } /** * Displays previous page. */ function onPrevPage() { if (pageNum <= 1) { return; } pageNum--; queueRenderPage(pageNum); } this.refs.prev.addEventListener('click', onPrevPage); /** * Displays next page. */ function onNextPage() { if (pageNum >= pdfDoc.numPages) { return; } pageNum++; queueRenderPage(pageNum); } this.refs.next.addEventListener('click', onNextPage); /** * Asynchronously downloads PDF. */ PDFJS.getDocument(url).then((pdfDoc_: any) => { pdfDoc = pdfDoc_; this.refs.page_count.textContent = pdfDoc.numPages; // Initial/first page rendering renderPage(pageNum); }); /** * display page */ function displayPage(page_num: number) { console.log(page_num, 'page_num'); pdfDoc.getPage(page_num).then((page: any) => { renderPage(page_num); }); // pdfDoc.getPage(page_num).then(function getPage(page_num) { renderPage(page_num) }) } /** * zoom in scale by 0.25 */ function zoomIn() { scale = scale + 0.25; displayPage(pageNum); } this.refs.zoomin.addEventListener('click', zoomIn); /** * zoom out downscale by 0.25 */ function zoomOut() { if (scale <= 0.25) return; scale = scale - 0.25; displayPage(pageNum); } this.refs.zoomout.addEventListener('click', zoomOut); } render() { return (<div><div className="pdf-btn-wrap clearfix"> <div className="pdf-next-prev"> <button ref="prev"><i className="pdf pdf-arrow"></i></button> <button className="nextPage" ref="next"><i className="pdf pdf-arrow"></i></button> </div> <div className="pdf-page"> <span>Page: <span ref="page_num"></span> / <span ref="page_count"></span></span> </div> <div className="pdf-zoom"> <span ref="zoomin"><i className="pdf-zoom-in"></i></span> <span ref="zoomout"><i className="pdf pdf-zoom-out"></i></span> </div> <div className="pdf-download-wrap"> {this.props.pdfUrl ? (<a href={this.props.pdfUrl} download><i className="pdf pdf-download"></i></a>) : ''} </div> </div> <div className="pdf-file"> <canvas ref="canvas" /> </div> </div> ); } } export default PDFReader;