|
@@ -1,275 +1,125 @@
|
|
|
<template>
|
|
|
- <div class="pdf">
|
|
|
- <div class="btnbox">
|
|
|
- <el-button type="primary" class="el-icon-tickets" size="mini" @click="outlineShow = !outlineShow"></el-button>
|
|
|
- <!-- <el-button type="primary" v-if="mode == 'pc'" class="el-icon-arrow-left left" size="mini" @click="pre_page"></el-button>
|
|
|
- <el-button type="primary" v-if="mode == 'pc'" class="el-icon-arrow-right right" size="mini" @click="next_page"></el-button> -->
|
|
|
- <el-button type="primary" v-if="mode == 'pc'" class="el-icon-plus" size="mini" @click="zoom_big"></el-button>
|
|
|
- <el-button type="primary" v-if="mode == 'pc'" class="el-icon-minus" size="mini" @click="zoom_small"></el-button>
|
|
|
- </div>
|
|
|
- <outline v-if="outlineShow" @outline_item="outline_item" :outlineData="outlineData" class="outline" :style="{ width: outlineWidth }"></outline>
|
|
|
- <div class="canvasBox">
|
|
|
- <!-- <canvas v-for="page in pdf_pages" :id="'the-canvas'+page" :key="page" class="canvas"></canvas> -->
|
|
|
- <canvas @mousewheel="mouseWheel" class="canvas" :id="'the-canvas'"></canvas>
|
|
|
- </div>
|
|
|
+ <div class="pdf-reader" id="pdf-reader">
|
|
|
+ <div ref="pdfContainer" class="pdf-container"></div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-// pdfjs-dist版本为2.2.228
|
|
|
-import PDFJS from 'pdfjs-dist'
|
|
|
-// 目录
|
|
|
-import outline from './outline.vue'
|
|
|
-// 时间处理
|
|
|
-import moment from 'moment'
|
|
|
+import $ from 'jquery'
|
|
|
+import turn from '../../public/turn'
|
|
|
+import pdfjsLib from 'pdfjs-dist'
|
|
|
+
|
|
|
export default {
|
|
|
- name: 'pdflib',
|
|
|
- components: {
|
|
|
- outline
|
|
|
- },
|
|
|
props: {
|
|
|
- pdf_src: { type: String, default: '/jpa.pdf' }
|
|
|
+ pdfSrc: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ }
|
|
|
},
|
|
|
data () {
|
|
|
return {
|
|
|
- mode: 'phone',
|
|
|
- flg: false,
|
|
|
- // pdf放大系数
|
|
|
- pdf_scale: 1,
|
|
|
- // 所有页
|
|
|
- pdf_pages: [],
|
|
|
- // 当前页
|
|
|
- is_page: 1,
|
|
|
pdfDoc: null,
|
|
|
- // 目录大纲
|
|
|
- outlineData: [],
|
|
|
- // 目录宽度
|
|
|
- outlineWidth: '100%',
|
|
|
- // 是否显示目录
|
|
|
- outlineShow: false,
|
|
|
- // 记录当前时间
|
|
|
- date: 0,
|
|
|
- // 默认阻断阈值 毫秒
|
|
|
- threshold: 200,
|
|
|
- // 目录默认点击后打开或关闭
|
|
|
- showAndHided: false
|
|
|
+ // 所有页
|
|
|
+ numPages: 0,
|
|
|
+ // 当前加载到的页码树
|
|
|
+ ispage: 1
|
|
|
}
|
|
|
},
|
|
|
mounted () {
|
|
|
- this.init()
|
|
|
- this.fingerInit()
|
|
|
+ this.loadPdf()
|
|
|
},
|
|
|
methods: {
|
|
|
- // 初始化屏幕触控
|
|
|
- fingerInit () {
|
|
|
- this.$finger(document.getElementsByTagName('canvas')[0], {
|
|
|
- pinch: this.zoom,
|
|
|
- swipe: this.swipeHandler
|
|
|
- })
|
|
|
- },
|
|
|
- // 初始化应用 判断屏幕宽度
|
|
|
- init () {
|
|
|
- const result = window.matchMedia('(min-width: 500px)').matches
|
|
|
- if (result) {
|
|
|
- this.pdf_scale = 0.3
|
|
|
- this.outlineWidth = '25%'
|
|
|
- this.showAndHided = true
|
|
|
- this.mode = 'pc'
|
|
|
- }
|
|
|
- this._loadFile(this.pdf_src)
|
|
|
- },
|
|
|
- // 初始化pdf 加载pdf文件
|
|
|
- _loadFile (url) {
|
|
|
- const loadingTask = PDFJS.getDocument(url)
|
|
|
- loadingTask.promise
|
|
|
- .then((pdf) => {
|
|
|
- this.pdfDoc = pdf
|
|
|
- this.pdf_pages = this.pdfDoc.numPages
|
|
|
- this.$nextTick(() => {
|
|
|
- this._renderPage(this.is_page)
|
|
|
- this.get_contents()
|
|
|
- })
|
|
|
+ // 加载pdf
|
|
|
+ async loadPdf () {
|
|
|
+ console.log(this.pdfSrc);
|
|
|
+ const loadingTask = pdfjsLib.getDocument(this.pdfSrc)
|
|
|
+ loadingTask.promise.then((pdf) => {
|
|
|
+ this.pdfDoc = pdf
|
|
|
+ this.numPages = pdf.numPages
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.setpage(1,pdf)
|
|
|
+ this.initTurnJs()
|
|
|
})
|
|
|
+ }).catch((err) => {
|
|
|
+ console.log(err);
|
|
|
+ });
|
|
|
},
|
|
|
- // 渲染pdf页
|
|
|
- _renderPage (num) {
|
|
|
- this.pdfDoc.getPage(num)
|
|
|
- .then((page) => {
|
|
|
- // 获取dom元素
|
|
|
- // const canvas = document.getElementById('the-canvas' + num)
|
|
|
- const canvas = document.getElementById('the-canvas')
|
|
|
- // 设置2D渲染
|
|
|
- const ctx = canvas.getContext('2d')
|
|
|
- // 设备像素比
|
|
|
- const dpr = window.devicePixelRatio || 1
|
|
|
- const bsr = ctx.webkitBackingStorePixelRatio ||
|
|
|
- ctx.mozBackingStorePixelRatio ||
|
|
|
- ctx.msBackingStorePixelRatio ||
|
|
|
- ctx.oBackingStorePixelRatio ||
|
|
|
- ctx.backingStorePixelRatio || 1
|
|
|
- const ratio = dpr / bsr
|
|
|
- // 参数为放大倍率
|
|
|
- const viewport = page.getViewport({ scale: (screen.availWidth / page.getViewport({ scale: 1 }).width) * this.pdf_scale })
|
|
|
- // 设置元素大小
|
|
|
- const { width, height } = viewport
|
|
|
- canvas.width = width * ratio
|
|
|
- canvas.height = height * ratio
|
|
|
- canvas.style.width = `${width}px`
|
|
|
- canvas.style.height = `${height}px`
|
|
|
- // 重绘cavas
|
|
|
- ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
|
|
|
- const renderContext = {
|
|
|
- canvasContext: ctx,
|
|
|
- viewport: viewport
|
|
|
+ // 创建动画js
|
|
|
+ initTurnJs () {
|
|
|
+ const _this = this;
|
|
|
+ $('.pdf-container').turn({
|
|
|
+ autoCenter: true,
|
|
|
+ height: '100vh', //高度
|
|
|
+ width: '100vw', //宽度
|
|
|
+ // width: 1440,
|
|
|
+ // height: 900,
|
|
|
+ display: 'single', //单页显示/双页显示 single/double
|
|
|
+ elevation: 0,
|
|
|
+ duration: 500, //翻页速度(毫秒), 默认600ms
|
|
|
+ gradients: true, //翻页时的阴影渐变, 默认true
|
|
|
+ autoCenter: true, //自动居中, 默认false
|
|
|
+ acceleration: true, //硬件加速, 默认true, 如果是触摸设备设置为true
|
|
|
+ page: 1, //设置当前显示第几页
|
|
|
+ pages: _this.numPages, //总页数
|
|
|
+ when:{
|
|
|
+ turned: function (event, pageNo, view) {
|
|
|
+ console.log(pageNo);
|
|
|
+ if (pageNo == 1 && _this.ispage == 1) _this.setcanvas(1,_this.pdfDoc,'canvaspage' + 1);
|
|
|
+ if(pageNo>1){
|
|
|
+ //如果没到最后一页,则加载下一页
|
|
|
+ if(pageNo < _this.numPages && pageNo > _this.ispage) _this.setcanvas(pageNo,_this.pdfDoc,'canvaspage' + (pageNo--));
|
|
|
+ }
|
|
|
+ _this.ispage = pageNo;
|
|
|
+ },
|
|
|
+ turning: function (event, pageNo, view) {
|
|
|
+ console.log(event, pageNo, view);
|
|
|
+ }
|
|
|
}
|
|
|
- // 渲染
|
|
|
- page.render(renderContext)
|
|
|
- this.flg = false
|
|
|
- // if (this.pdf_pages > num) {
|
|
|
- // this._renderPage(num + 1)
|
|
|
- // }
|
|
|
- })
|
|
|
- },
|
|
|
- // 获取目录
|
|
|
- get_contents () {
|
|
|
- this.pdfDoc.getOutline()
|
|
|
- .then((Outline) => {
|
|
|
- this.outlineData = Outline
|
|
|
- })
|
|
|
- },
|
|
|
- // 点击目录
|
|
|
- async outline_item (e) {
|
|
|
- const r = await this.pdfDoc.getDestination(e.dest)
|
|
|
- const p = await this.pdfDoc.getPageIndex(r[0])
|
|
|
- this.is_page = p + 1
|
|
|
- this._renderPage(this.is_page)
|
|
|
- this.outlineShow = this.showAndHided
|
|
|
- },
|
|
|
- // 上一页
|
|
|
- pre_page () {
|
|
|
- if (this.is_page <= 1) return
|
|
|
- this.is_page--
|
|
|
- this._renderPage(this.is_page)
|
|
|
- },
|
|
|
- // 下一页
|
|
|
- next_page () {
|
|
|
- if (this.is_page >= this.pdf_pages) return
|
|
|
- this.is_page++
|
|
|
- this._renderPage(this.is_page)
|
|
|
- },
|
|
|
- // 放大
|
|
|
- zoom_big () {
|
|
|
- this.pdf_scale += 0.1
|
|
|
- this._renderPage(this.is_page)
|
|
|
- },
|
|
|
- // 缩小
|
|
|
- zoom_small () {
|
|
|
- this.pdf_scale -= 0.1
|
|
|
- this._renderPage(this.is_page)
|
|
|
- },
|
|
|
- /*
|
|
|
- /* 以下为移动端触控事件
|
|
|
- */
|
|
|
- // 缩放
|
|
|
- zoom (e) {
|
|
|
- const prevent = this.prevent(100)
|
|
|
- if (!prevent) return
|
|
|
- this.flg = true
|
|
|
- const { zoom } = e
|
|
|
- this.pdf_scale = this.pdf_scale * zoom
|
|
|
- if (this.pdf_scale > 2) this.pdf_scale = 2
|
|
|
- if (this.pdf_scale < 1) this.pdf_scale = 1
|
|
|
- this.domScrol()
|
|
|
- this._renderPage(this.is_page)
|
|
|
- },
|
|
|
- // 移动方向翻页
|
|
|
- swipeHandler (evt) {
|
|
|
- if (this.flg) return
|
|
|
- const prevent = this.prevent(200)
|
|
|
- if (!prevent) return
|
|
|
- if (this.pdf_scale !== 0.3 && this.pdf_scale !== 1) {
|
|
|
- this.domScrol()
|
|
|
- return
|
|
|
- }
|
|
|
- if (evt?.direction === 'Up' || evt?.direction === 'Left') this.next_page()
|
|
|
- if (evt?.direction === 'Down' || evt?.direction === 'Right') this.pre_page()
|
|
|
- },
|
|
|
- // 移动端滚动位置
|
|
|
- domScrol (e) {
|
|
|
- const el = document.getElementsByClassName('canvasBox')[0]
|
|
|
- if (e) {
|
|
|
- el.scrollLeft = 0
|
|
|
- el.scrollTop = 0
|
|
|
- }
|
|
|
- el.scrollLeft -= 0.1
|
|
|
- el.scrollTop -= 0.1
|
|
|
+ })
|
|
|
},
|
|
|
- // pc滚动事件
|
|
|
- mouseWheel (e) {
|
|
|
- if (this.pdf_scale.toFixed(1) > 0.3) return
|
|
|
- const prevent = this.prevent(200)
|
|
|
- if (!prevent) return
|
|
|
- if (e.wheelDelta || e.detail) {
|
|
|
- // 当鼠标滚轮向上滚动时
|
|
|
- if (e.wheelDelta > 0 || e.detail < 0) {
|
|
|
- this.pre_page()
|
|
|
- }
|
|
|
- // 当鼠标滚轮向下滚动时
|
|
|
- if (e.wheelDelta < 0 || e.detail > 0) {
|
|
|
- this.next_page()
|
|
|
- }
|
|
|
+ //设定页码
|
|
|
+ async setpage(number,pdf){
|
|
|
+ for(var i=this.ispage; i <= pdf.numPages; i++){
|
|
|
+ var id = 'canvaspage' + i;
|
|
|
+ const canvas = '<canvas id="' + id + '"></canvas>';
|
|
|
+ $('.pdf-container').append(canvas);
|
|
|
}
|
|
|
},
|
|
|
- // 阻断连续调用
|
|
|
- prevent (num) {
|
|
|
- const date = moment().valueOf()
|
|
|
- if (date - this.data < num ?? this.threshold) return false
|
|
|
- this.data = date
|
|
|
- return true
|
|
|
+ //将将pdf添加到canvas里面
|
|
|
+ setcanvas(i, pdf, id){
|
|
|
+ pdf.getPage(i).then(function(page) {
|
|
|
+ const viewport = page.getViewport({ scale: 1.1 });
|
|
|
+ const canvas = document.getElementById(id);
|
|
|
+ let context = '';
|
|
|
+ if(canvas!=null&&canvas!=''){
|
|
|
+ const context = canvas.getContext('2d');
|
|
|
+ canvas.width = viewport.width;
|
|
|
+ canvas.height = viewport.height;
|
|
|
+ canvas.style.width = '100vw';
|
|
|
+ canvas.style.height = '100vh';
|
|
|
+ const renderContext = {
|
|
|
+ canvasContext: context,
|
|
|
+ viewport: viewport,
|
|
|
+ };
|
|
|
+ page.render(renderContext);
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
- }
|
|
|
+ },
|
|
|
+
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
-<style scoped lang="less">
|
|
|
-.pdf {
|
|
|
+<style>
|
|
|
+.pdf-reader {
|
|
|
width: 100vw;
|
|
|
height: 100vh;
|
|
|
}
|
|
|
-.canvasBox {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- overflow: auto;
|
|
|
- background: #000;
|
|
|
+.pdf-container {
|
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
- // justify-content: center;
|
|
|
-}
|
|
|
-.canvas {
|
|
|
- margin: 0 auto;
|
|
|
- display: block;
|
|
|
-}
|
|
|
-.btnbox {
|
|
|
- position: fixed;
|
|
|
- top: 10px;
|
|
|
- left: 5%;
|
|
|
- width: 90%;
|
|
|
- height: 5vh;
|
|
|
- .left {
|
|
|
- margin-left: 40%;
|
|
|
- }
|
|
|
- .right {
|
|
|
- margin-right: 40%;
|
|
|
- }
|
|
|
-}
|
|
|
-.outline {
|
|
|
- height: 95vh;
|
|
|
- top: 5vh;
|
|
|
- position: fixed;
|
|
|
- left: 0;
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
|
-.outline ::-webkit-scrollbar {
|
|
|
- width: 0px; /*对垂直流动条有效*/
|
|
|
- height: 0px; /*对水平流动条有效*/
|
|
|
+.page {
|
|
|
+ background-color: #fff !important;
|
|
|
}
|
|
|
</style>
|