|
@@ -1,6 +1,6 @@
|
|
<template>
|
|
<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>
|
|
<div class="page-tool">
|
|
<div class="page-tool">
|
|
<div class="page-tool-item" @click="lastPage">上一页</div>
|
|
<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="PDFPrint">打印</div>
|
|
<div class="page-tool-item" @click="PDFDownload">下载</div>
|
|
<div class="page-tool-item" @click="PDFDownload">下载</div>
|
|
</div>
|
|
</div>
|
|
|
|
+ <div class="page-tool2">
|
|
|
|
+ <div class="page-tool-item" @click="lastPage">{{scaleData.pageNum}}/{{scaleData.numPages}}</div>
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
import VuePdfEmbed from 'vue-pdf-embed';
|
|
import VuePdfEmbed from 'vue-pdf-embed';
|
|
import testpdf1 from '../../assets/testpdf.pdf';
|
|
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缩放
|
|
// 实现pdf缩放
|
|
const scaleFun = computed(() => {
|
|
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({
|
|
const scaleData = reactive({
|
|
@@ -30,25 +37,24 @@ const scaleData = reactive({
|
|
scaleBtn: 0.4, // 缩放按钮缩放比例
|
|
scaleBtn: 0.4, // 缩放按钮缩放比例
|
|
rotate: 0, // 旋转角度
|
|
rotate: 0, // 旋转角度
|
|
pageNum: 1, // 当前页面
|
|
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 = () => {
|
|
const lastPage = () => {
|
|
- console.log(activePage.value)
|
|
|
|
- if (activePage.value > 1) {
|
|
|
|
- activePage.value--
|
|
|
|
-
|
|
|
|
|
|
+ if (scaleData.pageNum > 1) {
|
|
|
|
+ scaleData.pageNum--
|
|
|
|
+ scrollToPage()
|
|
}
|
|
}
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
const nextPage = () => {
|
|
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) {
|
|
if (scaleData.scale > scaleData.scaleMin) {
|
|
scaleData.scale -= scaleData.scaleNum;
|
|
scaleData.scale -= scaleData.scaleNum;
|
|
}
|
|
}
|
|
- console.log(scaleData.scale)
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-const onLoad=(pdf)=> {
|
|
|
|
- console.log( pdf.numPages)
|
|
|
|
- scaleData.numPages = pdf.numPages // 获取总页数
|
|
|
|
};
|
|
};
|
|
|
|
|
|
const PDFPrint = () => {
|
|
const PDFPrint = () => {
|
|
- vuePdfRef.value?.print(300, '', false)
|
|
|
|
|
|
+ vuePdfRef.value?.print(300, getPDFFileName(), true)
|
|
};
|
|
};
|
|
|
|
|
|
const PDFDownload = () => {
|
|
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>
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
<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 {
|
|
.page-tool {
|
|
position: absolute;
|
|
position: absolute;
|
|
bottom: 25%;
|
|
bottom: 25%;
|
|
@@ -105,14 +146,14 @@ const PDFDownload = () => {
|
|
margin: 0px auto;
|
|
margin: 0px auto;
|
|
width: 100%;
|
|
width: 100%;
|
|
position: relative;
|
|
position: relative;
|
|
- height: 100%;
|
|
|
|
- overflow: auto;
|
|
|
|
|
|
+ height: calc(100vh - 180px);
|
|
background: #e3e2e2;
|
|
background: #e3e2e2;
|
|
}
|
|
}
|
|
|
|
|
|
.vue-pdf-cs{
|
|
.vue-pdf-cs{
|
|
width: 100%;
|
|
width: 100%;
|
|
- height: 10%;
|
|
|
|
|
|
+ height: 100%;
|
|
|
|
+ overflow: auto;
|
|
text-align: center;
|
|
text-align: center;
|
|
display: flex;
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-direction: column;
|