Browse Source

优化pdf组件

cxs 1 month ago
parent
commit
8a734dbd90
1 changed files with 67 additions and 26 deletions
  1. 67 26
      src/components/PDFEmbed/PdfViewer.vue

+ 67 - 26
src/components/PDFEmbed/PdfViewer.vue

@@ -1,6 +1,6 @@
 <template>
-  <div class="vue-pdf">
-    <vue-pdf-embed :source="testpdf1" ref="vuePdfRef" :style="scaleFun" class="vue-pdf-cs"  @load="onLoad"   :page="activePage" :renderPageNumber="true" />
+  <div class="vue-pdf" >
+    <vue-pdf-embed :source="testpdf1" ref="vuePdfRef" :style="scaleFun" class="vue-pdf-cs" @scroll="onScroll"  @loaded="onPdfLoaded"  :renderPageNumber="true" />
   </div>
   <div class="page-tool">
     <div class="page-tool-item" @click="lastPage">上一页</div>
@@ -10,16 +10,23 @@
     <div class="page-tool-item" @click="PDFPrint">打印</div>
     <div class="page-tool-item" @click="PDFDownload">下载</div>
   </div>
+  <div class="page-tool2">
+    <div class="page-tool-item" @click="lastPage">{{scaleData.pageNum}}/{{scaleData.numPages}}</div>
+  </div>
 </template>
 
 <script setup lang="ts">
 import VuePdfEmbed from 'vue-pdf-embed';
 import testpdf1 from '../../assets/testpdf.pdf';
-import {computed, reactive, ref} from "vue";
-const activePage = ref<number>(1);
+import {computed, onMounted, reactive, ref} from "vue";
 // 实现pdf缩放
 const scaleFun = computed(() => {
-  return `transform:scale(${scaleData.scale});transition: all 0.3s;`;
+  return {
+    transform: `scale(${scaleData.scale})`,
+    transition: 'all 0.3s',
+    transformOrigin: 'top',
+    height: '135vh'
+  };
 });
 
 const scaleData = reactive({
@@ -30,25 +37,24 @@ const scaleData = reactive({
   scaleBtn: 0.4, // 缩放按钮缩放比例
   rotate: 0, // 旋转角度
   pageNum: 1, // 当前页面
-  numPages: 10, // 总页数
+  url: 'http://www.fao.fudan.edu.cn/_upload/article/files/f5/53/8b40af524563b9b60049899b2dd3/c9a205b4-4188-4af3-863e-bc4e56872e33.pdf',
+  numPages: 0
 });
 
-
-const vuePdfRef = ref(null)
+const vuePdfRef = ref<InstanceType<typeof VuePdfEmbed> | null>(null);
 
 const lastPage = () => {
-  console.log(activePage.value)
-  if (activePage.value > 1) {
-    activePage.value--
-
+  if (scaleData.pageNum > 1) {
+    scaleData.pageNum--
+    scrollToPage()
   }
 
 };
 
 const nextPage = () => {
-  if (activePage.value < scaleData.numPages) {
-    activePage.value++
-    console.log( activePage.value)
+  if (scaleData.pageNum < scaleData.numPages) {
+    scaleData.pageNum++
+    scrollToPage()
   }
 };
 
@@ -62,26 +68,61 @@ const pageZoomIn = () => {
   if (scaleData.scale > scaleData.scaleMin) {
     scaleData.scale -= scaleData.scaleNum;
   }
-  console.log(scaleData.scale)
-};
-
-const onLoad=(pdf)=> {
-  console.log( pdf.numPages)
-  scaleData.numPages = pdf.numPages // 获取总页数
 };
 
 const PDFPrint = () => {
-  vuePdfRef.value?.print(300, '', false)
+  vuePdfRef.value?.print(300, getPDFFileName(), true)
 };
 
 const PDFDownload = () => {
-  vuePdfRef.value?.download('text1')
+  vuePdfRef.value?.download(getPDFFileName())
+};
+const getPDFFileName = () => {
+  const last_index= scaleData.url.lastIndexOf('/');
+  return  scaleData.url.slice(last_index+ 1);
+};
+
+
+const onPdfLoaded = (data: { numPages: number }) => {
+  scaleData.numPages = data.numPages
 };
 
+const scrollToPage = () => {
+  const pdfContainer = vuePdfRef.value.$el;
+  const pageHeight = pdfContainer.scrollHeight / scaleData.numPages;
+  const targetScrollPosition = (scaleData.pageNum-1) * pageHeight;
+
+  pdfContainer.scrollTo({
+    top: targetScrollPosition,
+    behavior: 'smooth'
+  });
+};
+const onScroll = () => {
+  const pdfContainer = vuePdfRef.value.$el;
+  const scrollTop = pdfContainer.scrollTop+100;
+  const pageHeight = pdfContainer.scrollHeight / scaleData.numPages;
+  const currentPage = Math.floor(scrollTop / pageHeight) + 1;
+  scaleData.pageNum = currentPage;
+};
 
 </script>
 
 <style scoped>
+.page-tool2 {
+  position: absolute;
+  bottom: 18%;
+  padding-left: 10px;
+  padding-right: 10px;
+  align-items: center;
+  background: rgba(3, 67, 109, 0.075);
+  color: rgba(2, 1, 41, 0.507);
+  border-radius: 19px;
+  z-index: 100;
+  cursor: pointer;
+  margin-left: 80%;
+  margin-right:50px; /* 修改这里 */
+}
+
 .page-tool {
   position: absolute;
   bottom: 25%;
@@ -105,14 +146,14 @@ const PDFDownload = () => {
   margin: 0px auto;
   width: 100%;
   position: relative;
-  height: 100%;
-  overflow: auto;
+  height: calc(100vh - 180px);
   background: #e3e2e2;
 }
 
 .vue-pdf-cs{
   width: 100%;
-  height: 10%;
+  height: 100%;
+  overflow: auto;
   text-align: center;
   display: flex;
   flex-direction: column;