songfens 2020-07-05
Ref: https://github.com/mozilla/pdf.js/blob/master/web/pdf_page_view.js
PDF.js 先创造canvas,再在上面渲染pdf的内容。
打开一次pdf,只需要渲染一次canvas,那么问题来了:
创建一个size大于screen的canvas,其移动的触发事件是默认就有的么?如何模拟?
paintOnCanvas(canvasWrapper) { const renderCapability = createPromiseCapability(); const result = { promise: renderCapability.promise, onRenderContinue(cont) { cont(); }, cancel() { renderTask.cancel(); }, }; const viewport = this.viewport; const canvas = document.createElement("canvas"); this.l10n .get("page_canvas", { page: this.id }, "Page {{page}}") .then(msg => { canvas.setAttribute("aria-label", msg); }); // Keep the canvas hidden until the first draw callback, or until drawing // is complete when `!this.renderingQueue`, to prevent black flickering. canvas.setAttribute("hidden", "hidden"); let isCanvasHidden = true; const showCanvas = function () { if (isCanvasHidden) { canvas.removeAttribute("hidden"); isCanvasHidden = false; } }; canvasWrapper.appendChild(canvas); this.canvas = canvas; if ( typeof PDFJSDev === "undefined" || PDFJSDev.test("MOZCENTRAL || GENERIC") ) { canvas.mozOpaque = true; } const ctx = canvas.getContext("2d", { alpha: false }); const outputScale = getOutputScale(ctx); this.outputScale = outputScale; if (this.useOnlyCssZoom) { const actualSizeViewport = viewport.clone({ scale: CSS_UNITS }); // Use a scale that makes the canvas have the originally intended size // of the page. outputScale.sx *= actualSizeViewport.width / viewport.width; outputScale.sy *= actualSizeViewport.height / viewport.height; outputScale.scaled = true; } if (this.maxCanvasPixels > 0) { const pixelsInViewport = viewport.width * viewport.height; const maxScale = Math.sqrt(this.maxCanvasPixels / pixelsInViewport); if (outputScale.sx > maxScale || outputScale.sy > maxScale) { outputScale.sx = maxScale; outputScale.sy = maxScale; outputScale.scaled = true; this.hasRestrictedScaling = true; } else { this.hasRestrictedScaling = false; } } const sfx = approximateFraction(outputScale.sx); const sfy = approximateFraction(outputScale.sy); canvas.width = roundToDivide(viewport.width * outputScale.sx, sfx[0]); canvas.height = roundToDivide(viewport.height * outputScale.sy, sfy[0]); canvas.style.width = roundToDivide(viewport.width, sfx[1]) + "px"; canvas.style.height = roundToDivide(viewport.height, sfy[1]) + "px"; // Add the viewport so it‘s known what it was originally drawn with. this.paintedViewportMap.set(canvas, viewport); // Rendering area const transform = !outputScale.scaled ? null : [outputScale.sx, 0, 0, outputScale.sy, 0, 0]; const renderContext = { canvasContext: ctx, transform, viewport: this.viewport, enableWebGL: this.enableWebGL, renderInteractiveForms: this.renderInteractiveForms, }; const renderTask = this.pdfPage.render(renderContext); renderTask.onContinue = function (cont) { showCanvas(); if (result.onRenderContinue) { result.onRenderContinue(cont); } else { cont(); } }; renderTask.promise.then( function () { showCanvas(); renderCapability.resolve(undefined); }, function (error) { showCanvas(); renderCapability.reject(error); } ); return result; }
Ref: https://www.runoob.com/html/html5-canvas.html
足够大后,在手机端,滑动确实是内置的功能。