2016-12-08 5 views
2

Ich versuche, Hammer.js zu verwenden, um eine Prise Zoom mit meiner PDF.js durchzuführen, jedoch funktioniert es trotz vieler Versuche nicht. Ich habe keine Fehler bekommen, wenn ich meine Codes auf meinem Handy debugge, aber ich kann immer noch nicht kneifen, um hinein und heraus zu zoomen. Bitte helfen Sie, wenn Sie wissen, was schief gelaufen ist, meine Codes sind wie folgt:Pinch zoom auf PDF.js mit Hammer.js

HTML:

<body>  
    <script type="text/javascript" src="reportviewer/hammer.js"></script> 
    <script> 
     var MIN_SCALE = 1; // 1=scaling when first loaded 
     var MAX_SCALE = 64; 

     // HammerJS fires "pinch" and "pan" events that are cumulative in nature and not 
     // deltas. Therefore, we need to store the "last" values of scale, x and y so that we can 
     // adjust the UI accordingly. It isn't until the "pinchend" and "panend" events are received 
     // that we can set the "last" values. 

     // Our "raw" coordinates are not scaled. This allows us to only have to modify our stored 
     // coordinates when the UI is updated. It also simplifies our calculations as these 
     // coordinates are without respect to the current scale. 

     var imgWidth = null; 
     var imgHeight = null; 
     var viewportWidth = null; 
     var viewportHeight = null; 
     var scale = null; 
     var lastScale = null; 
     var container = null; 
     var img = null; 
     var x = 0; 
     var lastX = 0; 
     var y = 0; 
     var lastY = 0; 
     var pinchCenter = null; 

     // We need to disable the following event handlers so that the browser doesn't try to 
     // automatically handle our image drag gestures. 
     var disableImgEventHandlers = function() { 
      var events = ['onclick', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 
          'onmouseup', 'ondblclick', 'onfocus', 'onblur']; 

      events.forEach(function (event) { 
       img[event] = function() { 
        return false; 
       }; 
      }); 
     }; 

     // Traverse the DOM to calculate the absolute position of an element 
     var absolutePosition = function (el) { 
      var x = 0, 
       y = 0; 

      while (el !== null) { 
       x += el.offsetLeft; 
       y += el.offsetTop; 
       el = el.offsetParent; 
      } 

      return { x: x, y: y }; 
     }; 

     var restrictScale = function (scale) { 
      if (scale < MIN_SCALE) { 
       scale = MIN_SCALE; 
      } else if (scale > MAX_SCALE) { 
       scale = MAX_SCALE; 
      } 
      return scale; 
     }; 

     var restrictRawPos = function (pos, viewportDim, imgDim) { 
      if (pos < viewportDim/scale - imgDim) { // too far left/up? 
       pos = viewportDim/scale - imgDim; 
      } else if (pos > 0) { // too far right/down? 
       pos = 0; 
      } 
      return pos; 
     }; 

     var updateLastPos = function (deltaX, deltaY) { 
      lastX = x; 
      lastY = y; 
     }; 

     var translate = function (deltaX, deltaY) { 
      // We restrict to the min of the viewport width/height or current width/height as the 
      // current width/height may be smaller than the viewport width/height 

      var newX = restrictRawPos(lastX + deltaX/scale, 
             Math.min(viewportWidth, curWidth), imgWidth); 
      x = newX; 
      img.style.marginLeft = Math.ceil(newX * scale) + 'px'; 

      var newY = restrictRawPos(lastY + deltaY/scale, 
             Math.min(viewportHeight, curHeight), imgHeight); 
      y = newY; 
      img.style.marginTop = Math.ceil(newY * scale) + 'px'; 
     }; 

     var zoom = function (scaleBy) { 
      scale = restrictScale(lastScale * scaleBy); 

      curWidth = imgWidth * scale; 
      curHeight = imgHeight * scale; 

      img.style.width = Math.ceil(curWidth) + 'px'; 
      img.style.height = Math.ceil(curHeight) + 'px'; 

      // Adjust margins to make sure that we aren't out of bounds 
      translate(0, 0); 
     }; 

     var rawCenter = function (e) { 
      var pos = absolutePosition(container); 

      // We need to account for the scroll position 
      var scrollLeft = window.pageXOffset ? window.pageXOffset : document.body.scrollLeft; 
      var scrollTop = window.pageYOffset ? window.pageYOffset : document.body.scrollTop; 

      var zoomX = -x + (e.center.x - pos.x + scrollLeft)/scale; 
      var zoomY = -y + (e.center.y - pos.y + scrollTop)/scale; 

      return { x: zoomX, y: zoomY }; 
     }; 

     var updateLastScale = function() { 
      lastScale = scale; 
     }; 

     var zoomAround = function (scaleBy, rawZoomX, rawZoomY, doNotUpdateLast) { 
      // Zoom 
      zoom(scaleBy); 

      // New raw center of viewport 
      var rawCenterX = -x + Math.min(viewportWidth, curWidth)/2/scale; 
      var rawCenterY = -y + Math.min(viewportHeight, curHeight)/2/scale; 

      // Delta 
      var deltaX = (rawCenterX - rawZoomX) * scale; 
      var deltaY = (rawCenterY - rawZoomY) * scale; 

      // Translate back to zoom center 
      translate(deltaX, deltaY); 

      if (!doNotUpdateLast) { 
       updateLastScale(); 
       updateLastPos(); 
      } 
     }; 

     var zoomCenter = function (scaleBy) { 
      // Center of viewport 
      var zoomX = -x + Math.min(viewportWidth, curWidth)/2/scale; 
      var zoomY = -y + Math.min(viewportHeight, curHeight)/2/scale; 

      zoomAround(scaleBy, zoomX, zoomY); 
     }; 

     var zoomIn = function() { 
      zoomCenter(2); 
     }; 

     var zoomOut = function() { 
      zoomCenter(1/2); 
     }; 

     var onLoad = function() { 

      img = document.getElementById('pinchzoom'); 
      container = img.parentElement; 

      disableImgEventHandlers(); 

      imgWidth = img.width; 
      imgHeight = img.height; 
      viewportWidth = img.parentElement.offsetWidth; 
      scale = viewportWidth/imgWidth; 
      lastScale = scale; 
      viewportHeight = img.parentElement.offsetHeight; 
      curWidth = imgWidth * scale; 
      curHeight = imgHeight * scale; 

      var hammer = new Hammer(container, { 
       domEvents: true 
      }); 

      hammer.get('pinch').set({ 
       enable: true 
      }); 

      hammer.on('pan', function (e) { 
       translate(e.deltaX, e.deltaY); 
      }); 

      hammer.on('panend', function (e) { 
       updateLastPos(); 
      }); 

      hammer.on('pinch', function (e) { 

       // We only calculate the pinch center on the first pinch event as we want the center to 
       // stay consistent during the entire pinch 
       if (pinchCenter === null) { 
        pinchCenter = rawCenter(e); 
        var offsetX = pinchCenter.x * scale - (-x * scale + Math.min(viewportWidth, curWidth)/2); 
        var offsetY = pinchCenter.y * scale - (-y * scale + Math.min(viewportHeight, curHeight)/2); 
        pinchCenterOffset = { x: offsetX, y: offsetY }; 
       } 

       // When the user pinch zooms, she/he expects the pinch center to remain in the same 
       // relative location of the screen. To achieve this, the raw zoom center is calculated by 
       // first storing the pinch center and the scaled offset to the current center of the 
       // image. The new scale is then used to calculate the zoom center. This has the effect of 
       // actually translating the zoom center on each pinch zoom event. 
       var newScale = restrictScale(scale * e.scale); 
       var zoomX = pinchCenter.x * newScale - pinchCenterOffset.x; 
       var zoomY = pinchCenter.y * newScale - pinchCenterOffset.y; 
       var zoomCenter = { x: zoomX/newScale, y: zoomY/newScale }; 

       zoomAround(e.scale, zoomCenter.x, zoomCenter.y, true); 
      }); 

      hammer.on('pinchend', function (e) { 
       updateLastScale(); 
       updateLastPos(); 
       pinchCenter = null; 
      }); 

      hammer.on('doubletap', function (e) { 
       var c = rawCenter(e); 
       zoomAround(2, c.x, c.y); 
      }); 

     }; 
    </script> 
</body> 

Ausblick:

<div data-options="dxView : { name: 'myViewer', title: 'My Viewer', disableCache: true } "> 
<div data-options="dxContent : { targetPlaceholder: 'content' } " class="dx-content-background"> 
    <div> 
     <iframe onload="onLoad()" data-bind="attr: { src: EmbedPDFLink }" class="viewReport"/> 
    </div> 
</div> 

+0

Niemand weiß, wie? – Anony

+0

Ich habe die gleichen Probleme. Hast du es in der Zwischenzeit zur Arbeit gebracht? Wenn ja, würden Sie bitte Ihre Lösung teilen? Vielen Dank! – Hans

Antwort

0

nicht für hammer.js ... Aber Sie können das SVG-Backend (nicht für die Produktion geeignet) verwenden, um Inhalte in DOM zu rendern, so dass Sie sich nicht ständig damit beschäftigen müssen, die Leinwand neu zu streichen. Basierend auf https://github.com/mozilla/pdf.js/blob/master/examples/components/pageviewer.html:

var url = "https://cdn.mozilla.net/pdfjs/tracemonkey.pdf"; 
 
var PAGE_TO_VIEW = 1; 
 
var SCALE = 1.0; 
 
var container = document.getElementById('container'); 
 
// Load document 
 
PDFJS.getDocument(url).then(function (doc) { 
 
     return doc.getPage(PAGE_TO_VIEW).then(function (pdfPage) { 
 
    // Add div with page view. 
 
    var pdfPageView = new PDFJS.PDFPageView({ 
 
     container: container, 
 
     renderer: 'svg', 
 
     id: PAGE_TO_VIEW, 
 
     scale: SCALE, 
 
     defaultViewport: pdfPage.getViewport(SCALE), 
 
     // We can enable text/annotations layers, if needed 
 
     textLayerFactory: new PDFJS.DefaultTextLayerFactory(), 
 
     annotationLayerFactory: new PDFJS.DefaultAnnotationLayerFactory() 
 
    }); 
 
    // Associates the actual page with the view, and drawing it 
 
    pdfPageView.setPdfPage(pdfPage); 
 
    return pdfPageView.draw();   
 
     }); 
 
});
<link href="https://npmcdn.com/pdfjs-dist/web/pdf_viewer.css" rel="stylesheet"/> 
 
<script src="https://npmcdn.com/pdfjs-dist/web/compatibility.js"></script> 
 
<script src="https://npmcdn.com/pdfjs-dist/build/pdf.js"></script> 
 
<script src="https://npmcdn.com/pdfjs-dist/web/pdf_viewer.js"></script> 
 

 
<div id="container" class="pdfViewer singlePageView"></div>