<template>
  <div class="w-full">
    <div class="w-full">
      <canvas :id="`pdfCanvas${page}`" v-for="page in n" :key="page"></canvas>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { reactive, nextTick, onMounted, computed } from "vue";
import * as PDF from "pdfjs-dist";
import entry from "pdfjs-dist/build/pdf.worker.entry"; // 引入时会报红线错误，不影响运行

const props = withDefaults(
  defineProps<{
    pdfPath: string;
    renderPageSize?: number;
  }>(),
  {
    pdfPath: "proxyPdf",
    renderPageSize: 1,
  }
);

const data = reactive({
  pdfPages: [] as any, // 页数
  pdfWidth: "", // 宽度
  pdfSrc: "", // 地址
  pdfDoc: "" as any, // 文档内容
  pdfScale: 1.0, // 放大倍数
});

const n = computed(() => {
  return props.renderPageSize > data.pdfPages
    ? data.pdfPages
    : props.renderPageSize;
});

onMounted(() => {
  PDF.GlobalWorkerOptions.workerSrc = entry;
  loadFile(props.pdfPath);
});

const loadFile = (url: string) => {
  let loadingTask = PDF.getDocument(url);
  loadingTask.promise.then((pdf: any) => {
    data.pdfDoc = pdf;
    data.pdfPages = pdf.numPages;
    nextTick(() => {
      renderPage(1);
    });
  });
};

const renderPage = (num: number) => {
  if (num > n.value) return;
  data.pdfDoc.getPage(num).then((page: any) => {
    let canvas: any = document.getElementById("pdfCanvas" + 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({ scale: data.pdfScale });
    canvas.width = viewport.width * ratio;
    canvas.height = viewport.height * ratio;
    canvas.style.width = "100%";
    canvas.style.height = "100%";
    data.pdfWidth = viewport.width + "px";
    ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
    let renderContext = {
      canvasContext: ctx,
      viewport: viewport,
    };
    page.render(renderContext);
    if (data.pdfPages > num) {
      renderPage(num + 1);
    }
  });
};
</script>
<style scoped lang="scss"></style>
