<template>
  <div class="box" v-show="open">
    <div id="scroller"
      class="pdf-viewer"
      @mousedown="startSelection"
      @mousemove="updateSelection"
      @mouseup="endSelection"
      @scroll="handleScroll">
      <canvas ref="pdfCanvas" />
      <canvas ref="tempCanvas" v-show="false" />
      <div v-if="selection" class="selection-box" :style="selectionStyle"></div>
    </div>
    <div class="tool-box">
      <a-button type="primary" class="tool-button" :icon="h(MinusOutlined)" @click="zoomOut"/>
      <span>{{ Math.round(zoomLevel * 100) }}%</span>
      <a-button type="primary" class="tool-button" :icon="h(PlusOutlined)" @click="zoomIn" />
      <a-button type="primary" style="border-radius: 8px; margin-left: 10px;" :icon="h(CloseOutlined)" @click="close">取 消</a-button>
    </div>
    <a-button type="primary" class="btn" v-show="captureButtonVisible" :style="captureButtonStyle" :icon="h(ScissorOutlined)" @click="captureSelection">截 图</a-button>
  </div>
</template>
<script>
  import * as pdfjsLib from 'pdfjs-dist';
  import {h} from "vue";
  import {
    CloseOutlined,
    MinusOutlined,
    PlusOutlined,
    ScissorOutlined
  } from "@ant-design/icons-vue";
  pdfjsLib.GlobalWorkerOptions.workerSrc = import.meta.env.VITE_GLOB_WORK_SRC;

  export default {
    name: 'PdfViewer',
    data() {
      return {
        open: false,
        zoomLevel: 1,
        start: false,
        selection: null,
        startPoint: null,
        scrollPoint: null,
        selectionStyle: null,
        captureButtonStyle: null,
        captureButtonVisible: false,
        pdfData: undefined,
      }
    },
    methods: {
      MinusOutlined,
      PlusOutlined,
      CloseOutlined,
      ScissorOutlined,
      h,
      async loadPdf() {
        let loadingTask = pdfjsLib.getDocument({data: this.pdfData.slice()});
        const pdf = await loadingTask.promise;
        const page = await pdf.getPage(1); // 获取第一页
        const viewport = page.getViewport({scale: this.zoomLevel});
        const canvas = this.$refs.pdfCanvas;
        const context = canvas.getContext('2d');
        console.log(viewport.width + '' + viewport.height);
        canvas.width = viewport.width;
        canvas.height = viewport.height;
        await page.render({
          canvasContext: context,
          viewport: viewport,
        }).promise;
      },
      show() {
        this.open = true;
        this.scrollPoint = {
          x: 0,
          y: 0
        };
        this.start = false;
        this.selection = null;
        this.startPoint = null;
        this.selectionStyle = null;
        this.captureButtonVisible = false;
      },
      close() {
        document.getElementById("scroller").scrollTop = 0;
        document.getElementById("scroller").scrollLeft = 0;
        this.open = false;
      },
      startSelection(event) {
        this.start = true;
        this.startPoint = {
          x: event.offsetX,
          y: event.offsetY
        };
        this.selection = {
          x: event.offsetX,
          y: event.offsetY,
          width: 0,
          height: 0,
        };
        this.selectionStyle = null;
        this.hideCaptureButton();
      },
      updateSelection(event) {
        if (!this.start)
          return;
        if (this.startPoint) {
          this.selection.width = Math.abs(event.offsetX - this.startPoint.x);
          this.selection.height = Math.abs(event.offsetY - this.startPoint.y);
          this.selection.x = Math.min(event.offsetX, this.startPoint.x);
          this.selection.y = Math.min(event.offsetY, this.startPoint.y);
          this.selectionStyle = {
            left: `${this.selection.x}px`,
            top: `${this.selection.y}px`,
            width: `${this.selection.width}px`,
            height: `${this.selection.height}px`,
            position: 'absolute',
            border: '2px dashed red',
          };
        }
      },
      endSelection() {
        this.start = false;
        this.showCaptureButton();
      },
      captureSelection() {
        const canvas = this.$refs.pdfCanvas;
        const context = canvas.getContext('2d');
        const tempCanvas = this.$refs.tempCanvas;
        tempCanvas.width = this.selection.width;
        tempCanvas.height = this.selection.height;
        const tempContext = tempCanvas.getContext('2d');
        tempContext.drawImage(
          canvas,
          this.selection.x,
          this.selection.y,
          this.selection.width,
          this.selection.height,
          0,
          0,
          tempCanvas.width,
          tempCanvas.height
        );
        const imageData = tempCanvas.toDataURL('image/png');
        this.$emit("onCapture", imageData);
        this.close();
      },
      handleScroll(event) {
        this.scrollPoint = {
          x: event.srcElement.scrollLeft,
          y: event.srcElement.scrollTop,
        }
        this.showCaptureButton();
      },
      showCaptureButton() {
        if (this.selection && this.selection.width > 50 && this.selection.height > 30) {

          this.captureButtonStyle = {
            left: `${this.selection.x - this.scrollPoint.x + 1}px`,
            top: `${this.selection.y - this.scrollPoint.y + 1}px`,
            position: 'absolute',
            borderRadius: 0,
          };
          this.captureButtonVisible = true;
        } else {
          this.captureButtonVisible = false;
        }
      },
      hideCaptureButton() {
        this.captureButtonVisible = false;
      },
      async zoomIn() {
        this.zoomLevel = Math.min(3, this.zoomLevel + 0.1);
        await this.loadPdf();
      },
      async zoomOut() {
        this.zoomLevel = Math.max(0.5, this.zoomLevel - 0.1);
        await this.loadPdf();
      },
    },
  };
</script>

<style scoped>
  .box {
    position: absolute;
    left: 0;
    top: 0;
    width: 100vw;
    height: 100vh;
    background-color: #0d1540;
    z-index: 9999;

    .pdf-viewer {
      text-align: center;
      position: absolute;
      left: 0;
      top: 0;
      width: 100vw;
      height: 100vh;
      background-color: #0d1540;
      overflow: auto;

      .selection-box {
        position: absolute;
        border: 2px dashed red;
      }
    }

    .btn {
      position: absolute;
      border-radius: 0;
      left: 0;
      top: 0;
    }
  }

  .tool-box {
    position: absolute;
    top: 5px;
    right: 20px;
    margin-right: 20px;
    padding: 5px;
    background: rgba(45,119,243,0.5);
    display: flex;
    justify-content: space-around;
    align-items: center;
    border-radius: 5px;

    .tool-button {
      border-radius: 100px;
      padding: 5px;
      width: 36px;
      height: 36px;
    }

    & > span {
      padding-left: 10px;
      padding-right: 10px;
      color: #ffffff;
    }
  }
</style>
