PDF显示用的是 pdfjs-dist

1.vue中引入pdfjs依赖

   npm install pdfjs-dist --save

2.使用canvas当预览pdf文件的画布

<canvas v-for="page in pages" :id="'the-canvas'+page" :key="page"></canvas>

3.调用pdfjs的api进行文档渲染

let PDFJS = require('pdfjs-dist');
PDFJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.min');

_renderPage (num) {
     this.pdfDoc.getPage(num).then((page) => {
       let canvas = document.getElementById('the-canvas' + num)
      let ctx = canvas.getContext('2d')
       let dpr = window.devicePixelRatio || 1
       let bsr = ctx.webkitBackingStorePixelRatio ||
         ctx.mozBackingStorePixelRatio ||
         ctx.msBackingStorePixelRatio ||
         ctx.oBackingStorePixelRatio ||
         ctx.backingStorePixelRatio || 1
       let ratio = dpr / bsr
       let viewport = page.getViewport(screen.availWidth / page.getViewport(1).width)
       canvas.width = viewport.width * ratio
       canvas.height = viewport.height * ratio
       canvas.style.width = viewport.width + 'px'
       canvas.style.height = viewport.height + 'px'
      ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
       let renderContext = {
         canvasContext: ctx,
         viewport: viewport
       }
       page.render(renderContext)
       if (this.pages > num) {
         this._renderPage(num + 1)
       }
     })
   },
   _loadFile (url) {
     PDFJS.getDocument(url).then((pdf) => {
       this.pdfDoc = pdf
       console.log(pdf)
       this.pages = this.pdfDoc.numPages
       this.$nextTick(() => {
         this._renderPage(1)
       })
     })
   }

 实现盖章之前要了解  scrollTop 、 scrollLeft 、 clientX、clientY 、offsetLeft、offsetTop、clientWidth、clientHeight的区别

 clientX、clientY
点击位置距离当前body可视区域的x,y坐标

 以上这些属性最好自己写例子体验一下

 

盖章具体代码

注意要拖拽的图片需要以背景图的形式

<div class="seal-wrapper-item">
    <div class="sign-img" style="background-image: url('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1582010369901&di=b5a374b084d96817dd20ef9b082e99ce&imgtype=0&src=http%3A%2F%2Fbpic.588ku.com%2Felement_origin_min_pic%2F16%2F08%2F19%2F1357b69b5969b65.jpg');height: 100px;width: 100px"  @mousedown='signPic'>
      <div class="delete" @click.stop="deleteIt">删除</div>
    </div>
</div>
mouseenter(e) {
      e.currentTarget.childNodes[0].style.display = "block"
    },
    mouseleave(e) {
      e.currentTarget.childNodes[0].style.display = "none"
    },
    deleteIt(e) {
      document.querySelector('.pdf-box').removeChild(e.currentTarget.parentNode);
    },
signPic(e) {
      if (document.querySelectorAll('.mark').length >= 3) {
        this.$message.error("最多可以盖三个")
        return;
      }
      let dom = e.currentTarget.cloneNode(true);
      document.querySelector('#signContract').appendChild(dom);
      document.onmousemove = e => {
        dom.style.left = (this.getPos(e).x - parseInt(dom.clientWidth / 2) - 10) + 'px';
        dom.style.top = (this.getPos(e).y - parseInt(dom.clientHeight / 2) + this.scrollTop - 10) + 'px';
        dom.className = "sign-img mark";
      };
      // 鼠标抬开
      document.onmouseup = e => {
        dom.style.left = (this.getPos(e).x + document.querySelector('.pdf-container').scrollLeft - parseInt(dom.clientWidth / 2) - 10 - document.querySelector('.pdf-box').offsetLeft) + 'px';
        dom.style.top = (this.getPos(e).y + this.scrollTop - parseInt(dom.clientHeight / 2) - 105) + 'px';
        dom.style.height = 100 * this.scale + "px";
        dom.style.width = 100 * this.scale + "px";

        //限制区域
        if (parseInt(dom.style.left) < 0) {
          document.querySelector('#signContract').removeChild(dom);
          this.$message.error("请将印章拖拽到合同区域")
          return;
        } else if (parseInt(dom.style.left) > document.querySelector('.pdf-box').clientWidth - dom.clientWidth) {
          document.querySelector('#signContract').removeChild(dom);
          this.$message.error("请将印章拖拽到合同区域")
          return;
        }

        if (parseInt(dom.style.top) < 0) {
          document.querySelector('#signContract').removeChild(dom);
          this.$message.error("请将印章拖拽到合同区域")
          return;
        } else if (parseInt(dom.style.left) > document.querySelector('.pdf-box').clientHeight - dom.clientWidth) {
          document.querySelector('#signContract').removeChild(dom);
          this.$message.error("请将印章拖拽到合同区域")
          return;
        }

        document.querySelector('#signContract').removeChild(dom);
        document.querySelector('.pdf-box').appendChild(dom);
        document.onmousemove = null;
        document.onmouseup = null;
        dom.onmousedown = this.moveTo;
        dom.onmouseenter = this.mouseenter;
        dom.onmouseleave = this.mouseleave;
        dom.childNodes[0].onclick = this.deleteIt;
      };
    },
    moveTo(e) {
      let odiv = e.currentTarget; //获取目标元素
      //算出鼠标相对元素的位置
      let disX = e.clientX - odiv.offsetLeft;
      let disY = e.clientY - odiv.offsetTop;
      document.onmousemove = e => {
        let left = e.clientX - disX;
        let top = e.clientY - disY;

        //限制区域
        if (left <= 0) {
          left = 0;
        } else if (left >= document.querySelector('.pdf-box').clientWidth - odiv.clientWidth) {
          left = document.querySelector('.pdf-box').clientWidth - odiv.clientWidth;
        } else {
          left = left - 10
        }

        if (top <= 0) {
          top = 0;
        } else if (top >= document.querySelector('.pdf-box').clientHeight - odiv.clientWidth) {
          top = document.querySelector('.pdf-box').clientHeight - odiv.clientWidth;
        } else {
          top = top - 10
        }

        //移动当前元素
        odiv.style.left = left + "px";
        odiv.style.top = top + "px";
      };
      document.onmouseup = e => {
        document.onmousemove = null;
        document.onmouseup = null;
      };
    },
    getPos(ev) {
      return {x: ev.clientX, y: ev.clientY};
    },

最后效果:

最后增加GitHub的demo地址   有帮助到的请点个star https://github.com/harrietjia/vue-pdf-show (注意  如果pdf显示报错的话把/static/pdf下的build文件夹和lib文件夹把/node_modules/pdfjs-dist/下的同名文件夹替换覆盖掉)

参考链接:https://www.jianshu.com/p/94cf6ddcb299

https://segmentfault.com/a/1190000016963084

Logo

前往低代码交流专区

更多推荐