lsc 5 dni temu
rodzic
commit
4c53de24a7

+ 55 - 33
src/views/Student/index.vue

@@ -1116,6 +1116,10 @@ const handleHomeworkSubmit = async () => {
             throw new Error('未能获取到iframe的body元素,无法截图')
           }
           try {
+            const a = iframe.getElementsByTagName('img')
+            for (let i = 0;i < a.length;i++) {
+              a[i].crossOrigin = 'anonymous'
+            }
             // 首先尝试使用html2canvas
             const html2canvas = await import('html2canvas')
             const canvas = await html2canvas.default(iframe, {
@@ -1129,6 +1133,10 @@ const handleHomeworkSubmit = async () => {
               removeContainer: true
             })
             imageData = canvas.toDataURL('image/png', 0.95)
+            const _a = iframe.getElementsByTagName('img')
+            for (let i = 0; i < _a.length; i++) {
+              _a[i].removeAttribute('crossorigin')
+            }
             console.log('使用html2canvas截图成功')
           }
           catch (html2canvasError) {
@@ -1282,15 +1290,29 @@ const getRefreshButtonRight = () => {
 const handleKeydown = (e: KeyboardEvent) => {
   switch (e.key) {
     case 'ArrowLeft':
+      e.preventDefault()
+      if (!isFollowModeActive.value || props.type == '1') {
+        previousSlide()
+      }
+      break
     case 'PageUp':
       e.preventDefault()
-      previousSlide()
+      if (!isFollowModeActive.value || props.type == '1') {
+        previousSlide()
+      }
       break
     case 'ArrowRight':
+      e.preventDefault()
+      if (!isFollowModeActive.value || props.type == '1') {
+        nextSlide()
+      }
+      break
     case 'PageDown':
     case ' ':
       e.preventDefault()
-      nextSlide()
+      if (!isFollowModeActive.value || props.type == '1') {
+        nextSlide()
+      }
       break
     case 'F11':
       e.preventDefault()
@@ -1376,37 +1398,37 @@ const getCourseDetail = async () => {
   }
   finally {
     isLoading.value = false
-    if (props.type == '2') {
-      console.log('判断是否是学生进入全屏')
-      function panFull() {
-        console.log('判断是否是学生进入全屏111')
-        if (!document.fullscreenElement) {
-          setTimeout(() => {
-            if (!document.fullscreenElement) {
-              if (document.documentElement.requestFullscreen) {
-                document.documentElement.requestFullscreen()
-              }
-              else if (document.documentElement.mozRequestFullScreen) { // Firefox
-                document.documentElement.mozRequestFullScreen()
-              }
-              else if (document.documentElement.webkitRequestFullscreen) { // Chrome, Safari and Opera
-                document.documentElement.webkitRequestFullscreen()
-              }
-              else if (document.documentElement.msRequestFullscreen) { // IE/Edge
-                document.documentElement.msRequestFullscreen()
-              }
-              panFull()
-            }
-          }, 50)
-        }           
-      }
-      nextTick(() => {
-        setTimeout(() => {
-          // enterFullscreen(); 
-          panFull()     
-        }, 50)
-      })
-    }
+    // if (props.type == '2') {
+    //   console.log('判断是否是学生进入全屏')
+    //   function panFull() {
+    //     console.log('判断是否是学生进入全屏111')
+    //     if (!document.fullscreenElement) {
+    //       setTimeout(() => {
+    //         if (!document.fullscreenElement) {
+    //           if (document.documentElement.requestFullscreen) {
+    //             document.documentElement.requestFullscreen()
+    //           }
+    //           else if (document.documentElement.mozRequestFullScreen) { // Firefox
+    //             document.documentElement.mozRequestFullScreen()
+    //           }
+    //           else if (document.documentElement.webkitRequestFullscreen) { // Chrome, Safari and Opera
+    //             document.documentElement.webkitRequestFullscreen()
+    //           }
+    //           else if (document.documentElement.msRequestFullscreen) { // IE/Edge
+    //             document.documentElement.msRequestFullscreen()
+    //           }
+    //           panFull()
+    //         }
+    //       }, 50)
+    //     }           
+    //   }
+    //   nextTick(() => {
+    //     setTimeout(() => {
+    //       // enterFullscreen(); 
+    //       panFull()     
+    //     }, 50)
+    //   })
+    // }
   }
 }
 

+ 1 - 0
src/views/components/ThumbnailSlide/ThumbnailElement.vue

@@ -9,6 +9,7 @@
     <component
       :is="currentElementComponent"
       :elementInfo="elementInfo"
+      :is-thumbnail="true"
       target="thumbnail"
     ></component>
   </div>

+ 63 - 2
src/views/components/element/FrameElement/BaseFrameElement.vue

@@ -12,7 +12,7 @@
       :style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
     >
       <div class="element-content">
-        <iframe 
+        <!-- <iframe 
           :key="`html-${iframeKey}`"
           :srcdoc="elementInfo.url" 
           v-if="elementInfo.isHTML"
@@ -31,8 +31,33 @@
           :frameborder="0" 
           :allowfullscreen="true"
           allow="camera *; microphone *; display-capture; midi; encrypted-media; fullscreen; geolocation; clipboard-read; clipboard-write; accelerometer; autoplay; gyroscope; payment; picture-in-picture; usb; xr-spatial-tracking;"
+        ></iframe> -->
+        <iframe 
+          :key="`html-${iframeKey}`"
+          :srcdoc="elementInfo.url" 
+          v-if="elementInfo.isHTML && !isThumbnail"
+          :width="elementInfo.width"
+          :height="elementInfo.height"
+          :frameborder="0" 
+          :allowfullscreen="true"
+          allow="camera *; microphone *; display-capture; midi; encrypted-media; fullscreen; geolocation; clipboard-read; clipboard-write; accelerometer; autoplay; gyroscope; payment; picture-in-picture; usb; xr-spatial-tracking;"
         ></iframe>
-
+        <iframe 
+          :key="`src-${iframeKey}`"
+          v-else-if="!isThumbnail"
+          :src="elementInfo.url"
+          :width="elementInfo.width"
+          :height="elementInfo.height"
+          :frameborder="0" 
+          :allowfullscreen="true"
+          allow="camera *; microphone *; display-capture; midi; encrypted-media; fullscreen; geolocation; clipboard-read; clipboard-write; accelerometer; autoplay; gyroscope; payment; picture-in-picture; usb; xr-spatial-tracking;"
+        ></iframe>
+        <div v-else-if="isThumbnail" class="thumbnail-content">
+          <div class="thumbnail-content-inner">
+            <div>互动工具</div>
+            <div>({{ getTypeLabel(Number(elementInfo.toolType)) }})</div>
+          </div>
+        </div>
         <!-- 在放映模式下不显示遮罩层,允许用户与iframe交互 -->
         <div class="mask" v-if="false"></div>
       </div>
@@ -50,6 +75,10 @@ const props = defineProps({
     type: Object as PropType<PPTFrameElement>,
     required: true,
   },
+  isThumbnail: {
+    type: Boolean,
+    default: false,
+  },
 })
 
 // 用于强制刷新iframe的key
@@ -62,6 +91,17 @@ watch(() => props.elementInfo.url, (newUrl, oldUrl) => {
     iframeKey.value++
   }
 })
+
+// 获取类型标签
+const getTypeLabel = (type: number) => {
+  const typeMap: Record<number, string> = {
+    45: '选择题',
+    15: '问答题',
+    72: 'AI应用',
+    73: 'H5页面'
+  }
+  return typeMap[type] || '未知'
+}
 </script>
 
 <style lang="scss" scoped>
@@ -85,4 +125,25 @@ watch(() => props.elementInfo.url, (newUrl, oldUrl) => {
   height: 100%;
   overflow: hidden;
 }
+.thumbnail-content {
+  width: 100%;
+  height: 100%;
+  background-color: #fff;
+}
+
+
+.thumbnail-content-inner {
+  width: 100%;
+  height: 100%;
+  color: #3681fc;
+  font-size: 110px;
+  font-weight: 600;
+  text-align: center;
+  line-height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  gap: 50px;
+}
 </style>