使用Hammer.js缩放PDF.js

时间:2016-12-08 07:08:07

标签: javascript hammer.js pdf.js

我正在尝试使用Hammer.js使用我的PDF.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>

查看:

<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>

1 个答案:

答案 0 :(得分:0)

不是对于hammer.js ...但你可以使用(不准备生产)SVG后端将东西渲染到DOM中,这样你就不需要自己处理重画画布了。基于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>