简体   繁体   English

平移缩放 PDF (Javascript)

[英]Pan-zoom a PDF (Javascript)

I'm trying to pan-zoom with the mouse a <div> that contains a PDF document.我正在尝试用鼠标对包含 PDF 文档的 <div> 进行平移缩放。 I'm using PDF.js and panzoom libraries (but other working alternatives are welcome)我正在使用PDF.jspanzoom库(但欢迎使用其他可行的替代方案)

The snippet below basically does this task, but unfortunately, after the <div> is panzoomed, the PDF is not re-rendered, then its image gets blurry (pan the PDF with the mouse and zoom it with the mouse-wheel):下面的代码片段基本上完成了这个任务,但不幸的是,在 <div> 被缩放之后,PDF 没有重新渲染,然后它的图像变得模糊(用鼠标平移 PDF 并用鼠标滚轮缩放它):

HTML HTML

<script src="https://mozilla.github.io/pdf.js/build/pdf.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@panzoom/panzoom@4.3.2/dist/panzoom.min.js"></script>

<div id="panzoom-container">
  <canvas id="the-canvas"></canvas>
</div>

<style>
#the-canvas {
  border: 1px solid black;
  direction: ltr;
}
</style>

JAVASCRIPT JAVASCRIPT

// Loaded via <script> tag, create shortcut to access PDF.js exports.
var pdfjsLib = window['pdfjs-dist/build/pdf'];
// The workerSrc property shall be specified.
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://mozilla.github.io/pdf.js/build/pdf.worker.js';

var pdfDoc = null,
    canvas = document.getElementById('the-canvas'),
    ctx = canvas.getContext('2d');

var container = document.getElementById("panzoom-container")

function renderPage(desiredHeight) {
  pdfDoc.getPage(1).then(function(page) {
    var viewport = page.getViewport({ scale: 1, });
    var scale = desiredHeight / viewport.height;
    var scaledViewport = page.getViewport({ scale: scale, });
    canvas.height = scaledViewport.height;
    canvas.width = scaledViewport.width;
    // Render PDF page into canvas context
    var renderContext = {
      canvasContext: ctx,
      viewport: scaledViewport
    };
    page.render(renderContext);
  });
}

// Get the PDF
var url = 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf';
pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) {
pdfDoc = pdfDoc_;
  // Initial/first page rendering
  renderPage(250);
});

var panzoom = Panzoom(container, {
  setTransform: (container, { scale, x, y }) => {
    // here I can re-render the page, but I don't know how
    // renderPage(container.getBoundingClientRect().height);
    panzoom.setStyle('transform', `scale(${scale}) translate(${x}px, ${y}px)`)
  }
})

container.addEventListener('wheel', zoomWithWheel)

function zoomWithWheel(event) {
  panzoom.zoomWithWheel(event)
}

https://jsfiddle.net/9rkh7o0e/5/ https://jsfiddle.net/9rkh7o0e/5/

I think that the procedure is correct, but unfortunately I'm stuck into two issues that must be fixed (then I ask for your help):我认为程序是正确的,但不幸的是我陷入了两个必须解决的问题(然后我请求你的帮助):

  1. I don't know how to re-render correctly the PDF after the panzoom happened.在 panzoom 发生后,我不知道如何正确重新渲染 PDF。
  2. consecutive renderings have to be queued in order to make this work properly (so that the PDF doesn't blink when panzooming) How could I fix 1 and 2?必须对连续渲染进行排队以使其正常工作(以便 PDF 在平移时不会闪烁)我该如何修复 1 和 2? I could not find any tool for doing that on a PDF, apart the panzoom lib.除了 panzoom 库之外,我在 PDF 上找不到任何工具来执行此操作。

Thanks谢谢

After some days of attempts, I solved the problem.经过几天的尝试,我解决了这个问题。 The tricky part was to scale down the contained canvas after the container has been scaled, with a transform-origin CSS attribute set:棘手的部分是在容器缩放后缩小包含的 canvas,并设置一个变换源 CSS 属性:

canvas.style.transform = "scale("+1/panzoom.getScale()+")"

Here is a fiddle of a PDF that can pan-zoomed.这是可以平移缩放的 PDF 的小提琴。 Each new render is done after a small delay (here it is set to 250ms) which corresponds to a sort of "wheel stop event".每个新的渲染都是在一个小的延迟(这里设置为 250 毫秒)之后完成的,这对应于一种“车轮停止事件”。

function zoomWithWheel(event) {
    panzoom.zoomWithWheel(event)
    clearTimeout(wheelTimeoutHandler);
    wheelTimeoutHandler = setTimeout(function() {
        canvas.style.transform = "scale("+1/panzoom.getScale()+")"
        if (pdfDoc)
            renderPage(panzoom.getScale());
    }, wheelTimeout)
}

https://jsfiddle.net/7tmk0z42/ https://jsfiddle.net/7tmk0z42/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM