PdfView.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <template>
  2. <div class="home_wrap">
  3. <div class="pdf_down">
  4. <div class="pdf_set_left" @click="scaleD">➕</div>
  5. <div class="pdf_set_middle" @click="scaleX">➖</div>
  6. <!-- <div class="pdf-pre" @click="prePage">上一页</div> -->
  7. <!-- <div class="pdf-next" @click="nextPage">下一页</div> -->
  8. </div>
  9. <div :style="{ width: pdf_div_width, margin: '0 auto' }">
  10. <!-- <canvas id="the_canvas"></canvas> -->
  11. <canvas
  12. v-for="page in pdf_pages"
  13. :id="'the_canvas' + page"
  14. :key="page"
  15. ></canvas>
  16. </div>
  17. </div>
  18. </template>
  19. <script setup>
  20. import { ref, onMounted } from "vue"
  21. import * as PDF from "pdfjs-dist"
  22. import pdfWorkerUrl from "pdfjs-dist/build/pdf.worker.mjs?url"
  23. PDF.GlobalWorkerOptions.workerSrc = pdfWorkerUrl
  24. const props = defineProps({
  25. data: Array,
  26. })
  27. const pdf_scale = ref(1.0)
  28. const pdf_pages = ref([])
  29. const pdf_div_width = ref("")
  30. const currentPage = ref(1)
  31. let pdfDoc = null
  32. const scaleD = () => {
  33. let max = 3.0
  34. if (pdf_scale.value >= max) {
  35. return
  36. }
  37. pdf_scale.value = pdf_scale.value + 0.1
  38. loadFile()
  39. }
  40. const scaleX = () => {
  41. let min = 0.5
  42. if (pdf_scale.value <= min) {
  43. return
  44. }
  45. pdf_scale.value = pdf_scale.value - 0.1
  46. loadFile()
  47. }
  48. const loadFile = async () => {
  49. pdfDoc = await PDF.getDocument(props.data).promise
  50. pdf_pages.value = pdfDoc.numPages
  51. renderPage(1, true)
  52. }
  53. const renderPage = async (num = 1, isInit = false) => {
  54. currentPage.value = num
  55. const page = await pdfDoc.getPage(num)
  56. if (isInit && num === 1) {
  57. const viewport = page.getViewport({ scale: 1.0 })
  58. const container = document.querySelector('.preview-wrapper') || document.body
  59. if (container) {
  60. const availableWidth = container.clientWidth - 20
  61. if (availableWidth > 0 && availableWidth < viewport.width) {
  62. pdf_scale.value = availableWidth / viewport.width
  63. }
  64. }
  65. }
  66. const canvas = document.getElementById("the_canvas" + num)
  67. if (!canvas) return
  68. const ctx = canvas.getContext("2d")
  69. const dpr = window.devicePixelRatio || 1
  70. const bsr =
  71. ctx.webkitBackingStorePixelRatio ||
  72. ctx.mozBackingStorePixelRatio ||
  73. ctx.msBackingStorePixelRatio ||
  74. ctx.oBackingStorePixelRatio ||
  75. ctx.backingStorePixelRatio ||
  76. 1
  77. const ratio = dpr / bsr
  78. const viewport = page.getViewport({ scale: pdf_scale.value })
  79. canvas.width = viewport.width * ratio
  80. canvas.height = viewport.height * ratio
  81. canvas.style.width = viewport.width + "px"
  82. pdf_div_width.value = viewport.width + "px"
  83. canvas.style.height = viewport.height + "px"
  84. ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
  85. const renderContext = {
  86. canvasContext: ctx,
  87. viewport: viewport,
  88. }
  89. page.render(renderContext)
  90. if (pdf_pages.value > num) {
  91. setTimeout(() => {
  92. return renderPage(num + 1)
  93. })
  94. }
  95. }
  96. const nextPage = () => {
  97. if (pdf_pages.value > currentPage.value) {
  98. renderPage(currentPage.value + 1)
  99. }
  100. }
  101. const prePage = () => {
  102. if (currentPage.value > 1) {
  103. renderPage(currentPage.value - 1)
  104. }
  105. }
  106. onMounted(() => {
  107. loadFile()
  108. })
  109. </script>
  110. <style scoped>
  111. .home_wrap {
  112. width: 100%;
  113. height: 100%;
  114. }
  115. .home_wrap .pdf_down {
  116. position: fixed;
  117. display: flex;
  118. z-index: 20;
  119. right: 26px;
  120. bottom: 7%;
  121. cursor: pointer;
  122. }
  123. .home_wrap .pdf-pre {
  124. position: fixed;
  125. display: flex;
  126. z-index: 20;
  127. right: 160px;
  128. bottom: 9%;
  129. cursor: pointer;
  130. }
  131. .home_wrap .pdf-next {
  132. position: fixed;
  133. display: flex;
  134. z-index: 20;
  135. right: 100px;
  136. bottom: 9%;
  137. }
  138. .home_wrap .pdf_down .pdf_set_left {
  139. width: 30px;
  140. height: 40px;
  141. color: #408fff;
  142. font-size: 15px;
  143. padding-top: 25px;
  144. text-align: center;
  145. margin-right: 5px;
  146. cursor: pointer;
  147. }
  148. .home_wrap .pdf_down .pdf_set_middle {
  149. width: 30px;
  150. height: 40px;
  151. color: #408fff;
  152. font-size: 15px;
  153. padding-top: 25px;
  154. text-align: center;
  155. margin-right: 5px;
  156. cursor: pointer;
  157. }
  158. canvas {
  159. max-width: 100% !important;
  160. height: auto !important;
  161. }
  162. </style>