Explorar el Código

PDF展示组件实现旋转放大

dengrui hace 5 meses
padre
commit
3bca6035f1
Se han modificado 1 ficheros con 110 adiciones y 3 borrados
  1. 110 3
      src/components/PDFView/index.vue

+ 110 - 3
src/components/PDFView/index.vue

@@ -9,7 +9,7 @@
   </el-button>
   <VuePdfEmbed
     v-else
-    :source="pdfSource"
+    :source="{ url: pdfSource, cMapUrl: '/cmaps/', cMapPacked: true }"
     :page="pageNumber"
     annotation-layer
     text-layer
@@ -33,13 +33,14 @@
         cMapPacked: true,
       }"
       :page="showPdfNumber"
+      @rendered="rendered"
       annotation-layer
       text-layer
     />
   </el-drawer>
 </template>
 
-<script lang="ts" setup>
+<script setup>
 import VuePdfEmbed from "vue-pdf-embed";
 // essential styles
 import "vue-pdf-embed/dist/style/index.css";
@@ -63,7 +64,7 @@ const props = defineProps({
     default: false,
   },
   contentType: {
-    type: String as PropType<"button" | "pdf">,
+    type: String,
     default: "pdf",
   },
   btnText: {
@@ -89,6 +90,112 @@ 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>