pdf.js 添加手势缩放功能

        pdf.js是 mozilla 出品的一款 PDF 文件阅读的开源 js 库。

        github 仓库 : GitHub - mozilla/pdf.js: PDF Reader in JavaScript

        pdf.js 使得PDF文件可以在html页面中进行打开阅读, 自带的预览页面 viewer.html 包含了丰富的功能。预览效果如下图所示:

        页面自带有放大缩小的功能,需要用户点击对应的 “+”、“-” 按钮进行操作。但是在手机页面中,用户很常见的一个需求就是需要通过手势进行放大缩小,这也是很合理的用户习惯。而pdf.js默认不支持手势的缩放,此时就需要对其 viewer.html 进行调整以满足需求。

        本文分享的方法,不需要修改 pdf.js 本身的代码, 只需要在其自身代码基础上添加补充的方法。

        经过阅读可以发现 pdf.js 自带的放大缩小功能调用的方法为 PDFViewerApplication.zoomIn() 以及 PDFViewerApplication. zoomOut(),代码位于 viewer.js 的 812行:

        zoomIn(ticks) {
          if (this.pdfViewer.isInPresentationMode) {
            return;
          }
          let newScale = this.pdfViewer.currentScale;
          do {
            newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2);
            newScale = Math.ceil(newScale * 10) / 10;
            newScale = Math.min(_ui_utils.MAX_SCALE, newScale);
          } while (--ticks > 0 && newScale < _ui_utils.MAX_SCALE);
          this.pdfViewer.currentScaleValue = newScale;
        },
        zoomOut(ticks) {
          if (this.pdfViewer.isInPresentationMode) {
            return;
          }
          let newScale = this.pdfViewer.currentScale;
          do {
            newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2);
            newScale = Math.floor(newScale * 10) / 10;
            newScale = Math.max(_ui_utils.MIN_SCALE, newScale);
          } while (--ticks > 0 && newScale > _ui_utils.MIN_SCALE);
          this.pdfViewer.currentScaleValue = newScale;
        },

        可以看到,方法中包含一些当前工作模式的判断。为了不影响其自身原有的功能,我们可以另外添加两个额外的方法单独进行手势放大缩小的处理:

         //强制放大
         forceZoomIn() {
          let newScale = this.pdfViewer.currentScale;
          newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2);
          newScale = Math.ceil(newScale * 10) / 10;
          newScale = Math.min(_ui_utils.MAX_SCALE, newScale);
          this.pdfViewer.currentScaleValue = newScale;
        },
         //强制缩小
         forceZoomOut() {
          let newScale = this.pdfViewer.currentScale;
          newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2);
          newScale = Math.floor(newScale * 10) / 10;
          newScale = Math.max(_ui_utils.MIN_SCALE, newScale);
          this.pdfViewer.currentScaleValue = newScale;
        },

        然后在 viewer.html 添加手势事件的捕捉和调用处理方法就可以了:

  <script type="text/javascript">

    var touchState = null;   //记录触屏手势触点信息的对象
    
    //绑定触屏事件
    function addPinchListener() {
      let element = document.getElementById("viewerContainer");
      element.addEventListener("touchstart", onTouchStart, false);
      element.addEventListener("touchmove", onTouchMove, false);
      element.addEventListener("touchend", onTouchEnd, false);
    }

    //记录触屏触点坐标 记录起始和结束点
    function onTouchStart(evt) {
      touchState = {
        //多点触屏的第一点
        startX: evt.touches[0].pageX,
        startY: evt.touches[0].pageY,
        endX: evt.touches[0].pageX,
        endY: evt.touches[0].pageY,

        //多点触屏的第二点  单点触屏时记录坐标为 -1 
        startX2: evt.touches[1] ? evt.touches[1].pageX : -1,
        startY2: evt.touches[1] ? evt.touches[1].pageY : -1,
        endX2: evt.touches[1] ? evt.touches[1].pageX : -1,
        endY2: evt.touches[1] ? evt.touches[1].pageY : -1
      };
    }

    //记录触屏触点坐标 触屏移动时更新结束点坐标
    function onTouchMove(evt) {
      if (touchState === null) {
        return;
      }
      touchState.endX = evt.touches[0].pageX;
      touchState.endY = evt.touches[0].pageY;
      touchState.endX2 = evt.touches[1] ? evt.touches[1].pageX : -1;
      touchState.endY2 = evt.touches[1] ? evt.touches[1].pageY : -1;
    }


    //触屏结束时 判断是否放大缩小
    function onTouchEnd(evt) {
      if (touchState === null) {
        return;
      }
      //计算两点间距离
      var getDistance = function (startX, startY, endX, endY) {
        return Math.hypot(endX - startX, endY - startY);
      };

      if (touchState.startX2 != -1 && touchState.endX2 != -1 && touchState.startY2 != -1 && touchState.endY2 != -1) {
        let distanceStart = getDistance(touchState.startX, touchState.startY, touchState.startX2, touchState.startY2);
        let distanceEnd = getDistance(touchState.endX, touchState.endY, touchState.endX2, touchState.endY2);
        //起始时两点距离和结束时两单距离进行比较,判断是方法还是缩小
        if (distanceStart < distanceEnd) {
          PDFViewerApplication.forceZoomIn();
        } else if (distanceStart > distanceEnd) {
          PDFViewerApplication.forceZoomOut();
        }
      }
    }
    
    addPinchListener();
  </script>

        添加完以上代码,手机浏览器打开对应页面就可以使用手势进行PDF文件的放大和缩小了。

        代码打包下载:带手势缩放功能的pdf.js-Web开发文档类资源-CSDN下载

猜你喜欢

转载自blog.csdn.net/evanyanglibo/article/details/122036163#comments_25926719