jack 3 недель назад
Родитель
Сommit
212ae7d473
1 измененных файлов с 80 добавлено и 20 удалено
  1. 80 20
      src/views/Student/index.vue

+ 80 - 20
src/views/Student/index.vue

@@ -1904,11 +1904,12 @@ const handleHomeworkSubmit = async () => {
             message.error(lang.ssFailedGetIframeBody)
             throw new Error('未能获取到iframe的body元素,无法截图')
           }
-
           try {
             const a = iframeBody.getElementsByTagName('img')
             const b = iframeBody.getElementsByTagName('video')
-            //const c = iframeBody.getElementsByTagName('canvas')
+            const webglCanvases = iframeBody.getElementsByTagName('canvas')
+
+
             iframeBody.style.cssText += 'width:100%;height:100%;position:absolute;top:0;left:0;'
             iframehtml.style.cssText += 'width:100%;height:100%;position:absolute;top:0;left:0;'
             for (let i = 0;i < a.length;i++) {
@@ -1918,24 +1919,83 @@ const handleHomeworkSubmit = async () => {
               b[i].crossOrigin = 'anonymous'
             }
             
-            // 直接对iframe内部的body进行截图
-            const html2canvas = await import('html2canvas')
-            const canvas = await html2canvas.default(iframeBody, {
-              // useCORS: true,
-              // allowTaint: true,
-              // scale: 1,
-              // backgroundColor: '#ffffff',
-              // logging: false,
-              // foreignObjectRendering: true,
-              // removeContainer: true
-              preserveDrawingBuffer: true,
-              antialias: true,
-              scale: 2, // 提高清晰度
-              allowTaint: false, // 是否允许跨域污染画布
-              useCORS: true, // 尝试跨域加载图片
-              logging: true,
-            })
-            imageData = canvas.toDataURL('image/png', 0.95)
+            try {
+              // 1. 转换所有 WebGL 画布为临时图片
+              const promises = [];
+              for (let i = 0; i < webglCanvases.length; i++) {
+                const originalCanvas = webglCanvases[i];
+                const promise = new Promise((resolve, reject) => {
+                  originalCanvas.toBlob(blob => {
+                    if (!blob) {
+                      reject(new Error('toBlob failed for canvas'));
+                      return;
+                    }
+                    const img = new Image();
+                    const url = URL.createObjectURL(blob);
+                    
+                    img.onload = () => {
+                      const rect = originalCanvas.getBoundingClientRect();
+                      img.style.position = 'absolute';
+                      img.style.left = rect.left + 'px';
+                      img.style.top = rect.top + 'px';
+                      img.style.width = originalCanvas.clientWidth + 'px';
+                      img.style.height = originalCanvas.clientHeight + 'px';
+                      img.style.zIndex = '9999';
+                      img.classList.add('temp-canvas-replacement');
+                      
+                      originalCanvas.parentNode.insertBefore(img, originalCanvas);
+                      originalCanvas.style.opacity = '0';
+                      
+                      resolve({
+                        originalCanvas,
+                        tempImage: img,
+                        blobUrl: url
+                      });
+                    };
+                    img.onerror = () => reject(new Error('Image load failed'));
+                    img.src = url;
+                  });
+                });
+                promises.push(promise);
+              }
+              
+              const replacements = await Promise.all(promises);
+
+              const html2canvas = await import('html2canvas')
+              // 2. 执行截图
+              const canvas = await html2canvas.default(iframeBody, {
+                scale: 2,
+                allowTaint: false,
+                useCORS: true,
+                logging: true,
+              });
+              
+              imageData = canvas.toDataURL('image/png', 0.95);
+              console.log('截图成功', imageData);
+              
+              // 3. 清理临时图片并恢复原画布
+              replacements.forEach(({ originalCanvas, tempImage, blobUrl }) => {
+                URL.revokeObjectURL(blobUrl);
+                tempImage.remove();
+                originalCanvas.style.opacity = '1';
+              });
+              
+              // 可选:将截图 canvas 添加到页面
+              document.body.appendChild(canvas);
+              
+              // 返回或使用 imageData
+              // return imageData;
+              
+            } catch (error) {
+              console.error('处理过程中出错:', error);
+              // 如果有部分替换成功,需要清理(这里简化处理,实际可以捕获已成功的替换)
+              // 可尝试清除所有带有 'temp-canvas-replacement' 类的图片
+              document.querySelectorAll('.temp-canvas-replacement').forEach(img => img.remove());
+              // 恢复所有被隐藏的画布
+              for (let i = 0; i < webglCanvases.length; i++) {
+                webglCanvases[i].style.opacity = '1';
+              }
+            }
             
             console.log('成功截图iframe内部内容')
           }