vue使用pdfjs+css实现翻页2

与turn.js掀页效果相比虽然不够炫酷,但这样就不用为了掀页效果而专门下载jQuery了。 

完整代码

<template>
  <div class="pdfCenter">
<!--    选择本地PDF -->
    <div class="btnBox">
      <input type="file" accept="application/pdf" @change="renderPdf" class="hiddenInput" />
      <span>{{pdfName}}</span>
    </div>
<!--    展示 -->

<!--    接收回显canvas-->
<!--    <div id="docView" ref="docView" ></div>-->

<!--    接收回显image-->
    <div class="flipBookBox">
      <div class="book">
        <div id="pages" class="pages">
          <div v-for="(item, i) in imgFiles" :key="i" class="page" :style="{zIndex:(i % 2 === 0)?(imgFiles.length-i):'0'}" @click="onTurn(i+1)">
            <img :src="item" :alt="'page'+ i">
          </div>
        </div>
      </div>
    </div>
  </div>

</template>

<script>
import * as pdfjs from 'pdfjs-dist'
import * as pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker

export default {
  name: "pdfjs",
  data() {
    return {
      imgFiles: [],
      pdfName: '',
    }
  },
  methods: {
    // 选择本地文件上传
   renderPdf(evt) {
      let that = this;
      let file = evt.target.files[0];
      // 文件名
      that.pdfName = file.name.substring(0, file.name.lastIndexOf("."));

      let reader = new FileReader();
      //将选取文件读取为 DataURL
      reader.readAsDataURL(file);
      //文件读取成功完成时触发
      reader.onload = function () {
        that.handlePdf(reader.result)
      }
    },
    async handlePdf(fileUrl) {
      let that = this
      const pdf = await pdfjs.getDocument(fileUrl).promise;
      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');

      for (let i = 1; i <= pdf._pdfInfo.numPages; i++) {
        const page = await pdf.getPage(i);
        // 获取页的尺寸
        const viewport = page.getViewport({scale: 1});

        // 设置canvas的尺寸
        canvas.width = viewport.width;
        canvas.height = viewport.height;

        // 异步加载,不然返回的图片可能顺序错乱
        // 将pdf页渲染到canvas上
        await page.render({canvasContext: context, viewport: viewport}).promise;

        // 将生成的canvas回显到页面
        // that.$refs['docView'].append(canvas);

        // canvas转为image
        let imgUrl = canvas.toDataURL('image/png')
        that.imgFiles.push(imgUrl)
      }
    },
    // 翻页
    onTurn(page) {
      const that = this
      that.$nextTick(()=>{
        let allPages = document.querySelectorAll(".page")
        if (parseInt(page) % 2 === 0) {
          allPages[page-1].classList.remove('flipped')
          allPages[page-2].classList.remove('flipped')
        } else {
          if (this.imgFiles.length === page){
            console.log("WoW~是奇數頁")
          }else {
            allPages[page].classList.add('flipped')
            allPages[page - 1].classList.add('flipped')
          }
        }
      })
    }
  }
}
</script>


<style scoped>
.pdfCenter{
  height: 100vh;
  display : flex;
  justify-content : center;
  align-items : center;
  background: #333333;
}

.page:nth-child(even) {
  clear: both;
}

.book {
  transition: opacity 0.4s 0.2s;
  perspective: 250vw;
}

.book .pages {
  width: 60vw;
  height: 44vw;
  position: relative;
  transform-style: preserve-3d;
  backface-visibility: hidden;
  border-radius: 4px;
}

.book .page {
  float: none;
  clear: none;
  margin: 0;
  position: absolute;
  top: 0;
  width: 30vw;
  height: 44vw;
  transform-origin: 0 0;
  transition: transform 1.4s;
  backface-visibility: hidden;
  transform-style: preserve-3d;
  cursor: pointer;
  user-select: none;
  background-color: #f0f0f0;
}

.book .page:before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0);
  transition: background 0.7s;
  z-index: 2;
}

.book .page:nth-child(odd) {
  pointer-events: all;
  transform: rotateY(0deg);
  right: 0;
  border-radius: 0 4px 4px 0;
  background-image: linear-gradient(to right, rgba(0, 0, 0, .15) 0%, rgba(0, 0, 0, 0) 10%);
  background-position : right top ;
}

.book .page:nth-child(odd):hover {
  transform: rotateY(-15deg);
}

.book .page:nth-child(odd):hover:before {
  background: rgba(0, 0, 0, 0.03);
}

.book .page:nth-child(odd):before {
  background: rgba(0, 0, 0, 0);
}

.book .page:nth-child(even) {
  pointer-events: none;
  transform: rotateY(180deg);
  transform-origin: 100% 0;
  left: 0;
  border-radius: 4px 0 0 4px;
  border-color: black;
  background-image: linear-gradient(to left, rgba(0, 0, 0, .12) 0%, rgba(0, 0, 0, 0) 10%);
}

.book .page:nth-child(even):before {
  background: rgba(0, 0, 0, 0.2);
}

.book .page.grabbing {
  transition: none;
}

.book .page.flipped:nth-child(odd) {
  pointer-events: none;
  transform: rotateY(-180deg);
}

.book .page.flipped:nth-child(odd):before {
  background: rgba(0, 0, 0, 0.2);
}

.book .page.flipped:nth-child(even) {
  pointer-events: all;
  transform: rotateY(0deg);
}

.book .page.flipped:nth-child(even):hover {
  transform: rotateY(15deg);
}

.book .page.flipped:nth-child(even):hover:before {
  background: rgba(0, 0, 0, 0.03);
}

.book .page.flipped:nth-child(even):before {
  background: rgba(0, 0, 0, 0);
}

.page img {
  width: 100%;
  max-height: 100%;
  object-fit: contain;
}

</style>


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值