Просмотр исходного кода

feat: 幻灯片上下翻页 + 截图功能

ChenYangfan 6 лет назад
Родитель
Сommit
3055eb10ee

+ 2 - 3
src/App.vue

@@ -1,7 +1,5 @@
 <template>
-  <div>
-    <router-view/>
-  </div>
+  <router-view/>
 </template>
 
 <script>
@@ -14,6 +12,7 @@ export default {
 <style lang="scss">
 @import "~@/style/reset.scss";
 @import "~@/style/theme.scss";
+
 @font-face {
   font-family: 'iconfont';  /* project id 1598214 */
   src: url('//at.alicdn.com/t/font_1598214_vlz5n1dhzwa.eot');

+ 2 - 2
src/components/Icon.vue

@@ -1,10 +1,10 @@
 <template>
-  <div class="icon"><span>{{unicode}}</span></div>
+  <div class="icon" :title="title ? title : ''"><span>{{unicode}}</span></div>
 </template>
 
 <script>
 export default {
-  props: ['unicode']
+  props: ['unicode', 'title']
 }
 </script>
 

+ 28 - 10
src/components/PDF/Pdf.vue

@@ -4,33 +4,51 @@
 
 <script>
 import pdfjs from '@/utils/pdf'
+import downloadFile from '@/utils/download-base64'
 
 export default {
   props: ['src', 'page'],
   mounted () {
-    const canvas = document.getElementById('pdf-canvas')
-    const context = canvas.getContext('2d')
+    this._canvas = document.getElementById('pdf-canvas')
+    this._context = this._canvas.getContext('2d')
 
     // Default size
-    canvas.height = 1080
-    canvas.width = 1920
+    this._canvas.height = 1080
+    this._canvas.width = 1920
 
     const loadingTask = pdfjs.getDocument(this.src)
     loadingTask.promise.then(pdf => {
-      pdf.getPage(this.page ? this.page : 1).then(page => {
+      this._pdf = pdf
+      this.showPage()
+    })
+  },
+  watch: {
+    page (newPage) {
+      this.showPage()
+    }
+  },
+  methods: {
+    showPage() {
+      this._pdf.getPage(this.page ? this.page : 1).then(page => {
         const scale = 2
         const viewport = page.getViewport({ scale: scale })
 
-        canvas.height = viewport.height
-        canvas.width = viewport.width
+        this._canvas.height = viewport.height
+        this._canvas.width = viewport.width
 
         const renderContext = {
-          canvasContext: context,
+          canvasContext: this._context,
           viewport: viewport
         }
         page.render(renderContext)
+      }).catch(() => {
+        // todo 超出页码
       })
-    })
+    },
+    getScreenShot () {
+      const img = this._canvas.toDataURL('image/png')
+      downloadFile(img, '课程课件截图.png')
+    }
   }
 }
 </script>
@@ -66,7 +84,7 @@ canvas {
   canvas {
     max-width: 100vw;
     min-width: unset;
-    max-height: 50vh;
+    max-height: 80vh;
   }
 }
 

+ 14 - 8
src/components/PDF/PdfController.vue

@@ -1,14 +1,14 @@
 <template>
   <div class="pdf-controller">
     <icon :class="pageMarked ? 'active' : ''" @click.native="handleMarkButtonClicked"
-          :unicode="pageMarked ? iconMap['mark'] : iconMap['mark_border']"/>
+          :unicode="pageMarked ? iconMap['mark'] : iconMap['mark_border']" title="收藏本页"/>
     <div class="spacer"></div>
-    <icon @click.native="handlePrevious" :unicode="iconMap['previous']"/>
-    <icon @click.native="handleScreenShot" :unicode="iconMap['screen_shot']"/>
-    <icon @click.native="handleNext" :unicode="iconMap['next']"/>
+    <icon @click.native="handlePrevious" :unicode="iconMap['previous']" title="上一页"/>
+    <icon @click.native="handleScreenShot" :unicode="iconMap['screen_shot']" title="将本页截图"/>
+    <icon @click.native="handleNext" :unicode="iconMap['next']" title="下一页"/>
     <div class="spacer"></div>
     <icon :class="showDiscussion ? 'active' : ''" @click.native="handleDiscussionShowState"
-          :unicode="iconMap['discussion']"/>
+          :unicode="iconMap['discussion']" title="讨论区"/>
   </div>
 </template>
 
@@ -42,9 +42,15 @@ export default {
       this.showDiscussion = !this.showDiscussion
       this.$emit('change-discussion-show-state', this.showDiscussion)
     },
-    handlePrevious () {},
-    handleNext () {},
-    handleScreenShot () {}
+    handlePrevious () {
+      this.$emit('previous')
+    },
+    handleNext () {
+      this.$emit('next')
+    },
+    handleScreenShot () {
+      this.$emit('screen-shot')
+    }
   }
 }
 </script>

+ 21 - 1
src/components/PDF/PdfViewer.vue

@@ -1,8 +1,11 @@
 <template>
   <div>
-    <pdf :src="src"></pdf>
+    <pdf ref="pdf" :src="src" :page="page"></pdf>
     <pdf-controller
       @change-discussion-show-state="handleChangeDiscussionShowState"
+      @previous="handlePrevious"
+      @next="handleNext"
+      @screen-shot="handleScreenShot"
     ></pdf-controller>
   </div>
 </template>
@@ -13,9 +16,26 @@ import PdfController from '@/components/PDF/PdfController'
 export default {
   components: { PdfController, Pdf },
   props: ['src'],
+  data () {
+    return {
+      page: 1
+    }
+  },
   methods: {
     handleChangeDiscussionShowState (state) {
       this.$emit('change-discussion-show-state', state)
+    },
+    handlePrevious () {
+      if (this.page !== 1) {
+        this.page--
+      }
+    },
+    handleNext () {
+      this.page++
+    },
+    handleScreenShot () {
+      console.log(this.$refs.pdf)
+      this.$refs.pdf.getScreenShot()
     }
   }
 }

+ 26 - 0
src/utils/download-base64.js

@@ -0,0 +1,26 @@
+// 非原创,来源标注:http://www.fly63.com/article/detial/1265
+
+function downloadFile (content, fileName) { // 下载base64图片
+  const base64ToBlob = function (code) {
+    let parts = code.split(';base64,')
+    let contentType = parts[0].split(':')[1]
+    let raw = window.atob(parts[1])
+    let rawLength = raw.length
+    let uInt8Array = new Uint8Array(rawLength)
+    for (let i = 0; i < rawLength; ++i) {
+      uInt8Array[i] = raw.charCodeAt(i)
+    }
+    return new Blob([uInt8Array], {
+      type: contentType
+    })
+  }
+  let aLink = document.createElement('a')
+  let blob = base64ToBlob(content) // new Blob([content]);
+  let evt = document.createEvent('HTMLEvents')
+  evt.initEvent('click', true, true) // initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为
+  aLink.download = fileName
+  aLink.href = URL.createObjectURL(blob)
+  aLink.click()
+}
+
+export default downloadFile

+ 2 - 2
src/views/teacher/tabs/TeacherDiscussion.vue

@@ -1,8 +1,8 @@
 <template>
   <div class="tab">
     <h1 class="title">讨论区消息通知</h1>
-    <div class="tip"><span>&#xe610;</span> 您有 <span>{{2}}</span> 条未读消息</div>
-    <div class="sub-title">新帖子</div>
+    <div class="tip"><span>&#xe610;</span> 您有 <span>{{2}}</span> 个问题待回答</div>
+<!--    <div class="sub-title">新帖子</div>-->
   </div>
 </template>