<template>
  <div class="pdf-container" style="overflow: scroll; height: 600px">
    <canvas
      style="margin-top: 20px; margin-bottom: 10px"
      v-for="page in pdfPages"
      :key="page"
      :id="`pdf-canvas-${page}`"
    />
    <el-backtop :right="100" :bottom="100">
      <div class="backtop">返回顶部</div>
    </el-backtop>
  </div>
</template>

<script setup>
//一定要引入下面两个依赖文件
import * as PdfJs from "pdfjs-dist";
import * as worker from "pdfjs-dist/build/pdf.worker.min";
import { nextTick, ref } from "vue";

let pdfDoc = null; // pdf整体实例
const pdfPages = ref(0); // pdf文件总页数
const pdfScale = ref(1.5); // pdf文件预览缩放
const props = defineProps({
  src: {
    type: Object,
    default: "",
  },
});

const loadFile = (src) => {
  if (src == "") {
    return;
  }
  PdfJs.GlobalWorkerOptions.workerSrc = worker;
  // PdfJs.disableWorker = true;
  //通过getDocument获取到PDf文档
  const loadingTask = PdfJs.getDocument(src);
  loadingTask.promise
    .then((pdf) => {
      pdfDoc = pdf; // 文件流
      pdfPages.value = pdf.numPages; // 文件总页数
      nextTick(() => {
        renderPage(1);
      });
    })
    .catch((error) => {});
};
const renderPage = (num) => {
  // 页数检测
  if (num <= 0 || num > pdfPages.value) {
    return;
  }
  pdfDoc
    .getPage(num)
    .then((page) => {
      const canvasId = "pdf-canvas-" + num;
      const canvas = document.getElementById(canvasId);
      const ctx = canvas.getContext("2d");
      //dpr和bsr设置pdf的比例尺寸
      const dpr = window.devicePixelRatio || 1;
      const bsr =
        ctx.webkitBackingStorePixelRatio ||
        ctx.mozBackingStorePixelRatio ||
        ctx.msBackingStorePixelRatio ||
        ctx.oBackingStorePixelRatio ||
        1;
      const ratio = dpr / bsr;
      const viewport = page.getViewport({ scale: pdfScale.value }); // 文件显示比例
      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); // 设置当pdf文件处于缩小或放大状态时，可以拖动

      // 将pdf文件的内容渲染到canvas中
      const renderContext = {
        canvasContext: ctx,
        viewport: viewport,
      };
      page.render(renderContext);

      if (num < pdfPages.value) {
        renderPage(num + 1);
      }
    })
    .catch((error) => {});
};
const closePdf = () => {
  pdfScale.value = 1;
  pdfPages.value = ref(0);
};
defineExpose({
  loadFile,
  closePdf,
});
</script>

<style scoped>
.pdf-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  height: 100%;
}
.backtop {
  height: 100%;
  width: 100%;
  background-color: #ffffff;
  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.12);
  text-align: center;
  line-height: 20px;
  font-size: 16px;
  color: #1989fa;
}
</style>
