|
@@ -1,196 +0,0 @@
|
|
|
-<template>
|
|
|
- <el-button
|
|
|
- v-if="contentType === 'button'"
|
|
|
- :type="btnType"
|
|
|
- :link="isLink"
|
|
|
- @click="showPdf"
|
|
|
- >
|
|
|
- {{ btnText }}
|
|
|
- </el-button>
|
|
|
- <VuePdfEmbed
|
|
|
- v-else
|
|
|
- :source="{ url: pdfSource, cMapUrl: '/cmaps/', cMapPacked: true }"
|
|
|
- :page="pageNumber"
|
|
|
- annotation-layer
|
|
|
- text-layer
|
|
|
- @click="showPdf"
|
|
|
- />
|
|
|
- <el-drawer
|
|
|
- v-if="needToShowPdf"
|
|
|
- v-model="visible"
|
|
|
- :footer="false"
|
|
|
- :header="false"
|
|
|
- :show-close="false"
|
|
|
- destroy-on-close
|
|
|
- direction="rtl"
|
|
|
- :append-to-body="true"
|
|
|
- size="60%"
|
|
|
- >
|
|
|
- <VuePdfEmbed
|
|
|
- v-if="needToShowPdf"
|
|
|
- :source="{
|
|
|
- url: pdfSource,
|
|
|
- cMapUrl: '/cmaps/',
|
|
|
- cMapPacked: true,
|
|
|
- }"
|
|
|
- :page="showPdfNumber"
|
|
|
- @rendered="rendered"
|
|
|
- annotation-layer
|
|
|
- text-layer
|
|
|
- />
|
|
|
- </el-drawer>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup>
|
|
|
-import VuePdfEmbed from "vue-pdf-embed";
|
|
|
-
|
|
|
-// either URL, Base64, binary, or document proxy
|
|
|
-const props = defineProps({
|
|
|
- pdfSource: {
|
|
|
- type: String,
|
|
|
- required: true,
|
|
|
- },
|
|
|
- pageNumber: {
|
|
|
- type: Number,
|
|
|
- default: 0,
|
|
|
- },
|
|
|
- needToShowPdf: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- contentType: {
|
|
|
- type: String,
|
|
|
- default: "pdf",
|
|
|
- },
|
|
|
- btnText: {
|
|
|
- type: String,
|
|
|
- default: "预览",
|
|
|
- },
|
|
|
- btnType: {
|
|
|
- type: String,
|
|
|
- default: "primary",
|
|
|
- },
|
|
|
- isLink: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- showPdfNumber: {
|
|
|
- type: Number,
|
|
|
- default: 0,
|
|
|
- },
|
|
|
-});
|
|
|
-
|
|
|
-const visible = ref(false);
|
|
|
-
|
|
|
-const showPdf = () => {
|
|
|
- visible.value = true;
|
|
|
-};
|
|
|
-const rendered = () => {
|
|
|
- const clickableElementsA = document.querySelectorAll(
|
|
|
- ".el-drawer__body .vue-pdf-embed div"
|
|
|
- );
|
|
|
- const clickableElements = document.querySelectorAll(
|
|
|
- ".el-drawer__body .vue-pdf-embed .vue-pdf-embed__page"
|
|
|
- );
|
|
|
- clickableElementsA.forEach((element) => {
|
|
|
- element.style.display = "flex";
|
|
|
- element.style.alignItems = "center";
|
|
|
- element.style.justifyContent = "center";
|
|
|
- });
|
|
|
- clickableElements.forEach((element, index) => {
|
|
|
- let rotationAngle = 0;
|
|
|
- element.addEventListener("click", () => {
|
|
|
- const currentWidth = element.offsetWidth;
|
|
|
- const currentHeight = element.offsetHeight;
|
|
|
- const parent = element.parentNode;
|
|
|
- let distance = 0;
|
|
|
- if (currentHeight > currentWidth) {
|
|
|
- distance = currentHeight - currentWidth;
|
|
|
- } else {
|
|
|
- element.style.width = `${currentHeight}px`;
|
|
|
- element.style.height = `${currentWidth}px`;
|
|
|
- }
|
|
|
- rotationAngle = (rotationAngle + 90) % 360;
|
|
|
- if (rotationAngle == 0) {
|
|
|
- if (distance > 0) {
|
|
|
- element.style.transform = `rotate(${rotationAngle}deg) `;
|
|
|
- element.firstElementChild.style.transform = `translateY(0px) `;
|
|
|
- } else {
|
|
|
- element.style.transform = `rotate(${rotationAngle}deg) `;
|
|
|
- element.firstElementChild.style.transform = `translateY(0px) `;
|
|
|
- }
|
|
|
- }
|
|
|
- if (rotationAngle == 90) {
|
|
|
- if (distance > 0) {
|
|
|
- element.style.transform = `rotate(${rotationAngle}deg)`;
|
|
|
- element.firstElementChild.style.transform = `translateY(-${distance / 2}px) `;
|
|
|
- } else {
|
|
|
- element.style.transform = `rotate(${rotationAngle}deg)`;
|
|
|
- element.firstElementChild.style.transform = `translateY(0px) `;
|
|
|
- }
|
|
|
- }
|
|
|
- if (rotationAngle === 180) {
|
|
|
- if (distance > 0) {
|
|
|
- element.style.transform = `rotate(${rotationAngle}deg) `;
|
|
|
- element.firstElementChild.style.transform = `translateY(0px) `;
|
|
|
- } else {
|
|
|
- element.style.transform = `rotate(${rotationAngle}deg) `;
|
|
|
- element.firstElementChild.style.transform = `translateY(0px) `;
|
|
|
- }
|
|
|
- }
|
|
|
- if (rotationAngle === 270) {
|
|
|
- if (distance > 0) {
|
|
|
- element.style.transform = `rotate(${rotationAngle}deg) `;
|
|
|
- element.firstElementChild.style.transform = `translateY(${distance / 2}px) `;
|
|
|
- } else {
|
|
|
- element.style.transform = `rotate(${rotationAngle}deg) `;
|
|
|
- element.firstElementChild.style.transform = `translateY(0px) `;
|
|
|
- }
|
|
|
- }
|
|
|
- parent.style.width = `${currentWidth}px`;
|
|
|
- parent.style.height = `${currentHeight}px`;
|
|
|
- });
|
|
|
- element.addEventListener("wheel", function (event) {
|
|
|
- const currentWidth = element.offsetWidth;
|
|
|
- const currentHeight = element.offsetHeight;
|
|
|
- const parent = element.parentNode;
|
|
|
- if (event.ctrlKey) {
|
|
|
- event.preventDefault();
|
|
|
-
|
|
|
- // 获取当前的transform值并解析
|
|
|
- const transform = getComputedStyle(element).transform;
|
|
|
- let scale = 1,
|
|
|
- rotate = 0;
|
|
|
-
|
|
|
- if (transform && transform !== "none") {
|
|
|
- const transformMatrix = new WebKitCSSMatrix(transform);
|
|
|
- scale = Math.sqrt(
|
|
|
- Math.pow(transformMatrix.a, 2) + Math.pow(transformMatrix.b, 2)
|
|
|
- );
|
|
|
- rotate =
|
|
|
- Math.atan2(transformMatrix.b, transformMatrix.a) * (180 / Math.PI);
|
|
|
- }
|
|
|
-
|
|
|
- // 根据滚轮方向调整缩放级别
|
|
|
- if (event.deltaY < 0) {
|
|
|
- // 向上滚动,放大
|
|
|
- scale += 0.1;
|
|
|
- } else {
|
|
|
- // 向下滚动,缩小
|
|
|
- scale -= 0.1;
|
|
|
- }
|
|
|
- // 确保缩放级别不会变成负数或过小
|
|
|
- scale = Math.max(0.1, Math.min(scale, 5));
|
|
|
-
|
|
|
- // 应用新的缩放级别和原有的旋转角度
|
|
|
- element.style.transform = `scale(${scale}) rotate(${rotate}deg)`;
|
|
|
- //同步放大展示盒子
|
|
|
- parent.style.width = `${currentWidth * scale}px`;
|
|
|
- parent.style.height = `${currentHeight * scale}px`;
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
-};
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="scss" scoped></style>
|