| <!DOCTYPE html> |
| <html lang="zh-CN"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>矢量元素导出调试</title> |
| <style> |
| body { |
| font-family: Arial, sans-serif; |
| margin: 20px; |
| background-color: #f5f5f5; |
| } |
| .container { |
| max-width: 1200px; |
| margin: 0 auto; |
| background: white; |
| padding: 20px; |
| border-radius: 8px; |
| box-shadow: 0 2px 10px rgba(0,0,0,0.1); |
| } |
| .test-section { |
| margin-bottom: 30px; |
| padding: 20px; |
| border: 1px solid #ddd; |
| border-radius: 5px; |
| } |
| .test-title { |
| font-size: 18px; |
| font-weight: bold; |
| margin-bottom: 15px; |
| color: #333; |
| } |
| .svg-container { |
| display: inline-block; |
| margin: 10px; |
| border: 1px solid #ccc; |
| padding: 10px; |
| background: white; |
| } |
| .debug-info { |
| background: #f8f9fa; |
| padding: 10px; |
| margin-top: 10px; |
| border-radius: 4px; |
| font-family: monospace; |
| font-size: 12px; |
| } |
| button { |
| background: #007bff; |
| color: white; |
| border: none; |
| padding: 8px 16px; |
| border-radius: 4px; |
| cursor: pointer; |
| margin: 5px; |
| } |
| button:hover { |
| background: #0056b3; |
| } |
| .error { |
| color: #dc3545; |
| background: #f8d7da; |
| padding: 10px; |
| border-radius: 4px; |
| margin: 10px 0; |
| } |
| .success { |
| color: #155724; |
| background: #d4edda; |
| padding: 10px; |
| border-radius: 4px; |
| margin: 10px 0; |
| } |
| </style> |
| </head> |
| <body> |
| <div class="container"> |
| <h1>PPT矢量元素导出问题诊断</h1> |
| |
| <div class="test-section"> |
| <div class="test-title">1. 基础形状元素测试</div> |
| <div class="svg-container"> |
| <svg width="100" height="100" id="basic-shape"> |
| <path d="M10,10 L90,10 L90,90 L10,90 Z" |
| fill="#ff6b6b" |
| stroke="#333" |
| stroke-width="2" |
| vector-effect="non-scaling-stroke"/> |
| </svg> |
| <div class="debug-info">基础矩形 - 100x100px</div> |
| </div> |
| |
| <div class="svg-container"> |
| <svg width="100" height="100" id="circle-shape"> |
| <circle cx="50" cy="50" r="40" |
| fill="#4ecdc4" |
| stroke="#333" |
| stroke-width="2" |
| vector-effect="non-scaling-stroke"/> |
| </svg> |
| <div class="debug-info">圆形 - 半径40px</div> |
| </div> |
| </div> |
| |
| <div class="test-section"> |
| <div class="test-title">2. 复杂路径元素测试</div> |
| <div class="svg-container"> |
| <svg width="120" height="100" id="complex-path"> |
| <path d="M20,80 C20,80 20,20 50,20 S80,20 80,50 S80,80 50,80 S20,80 20,80" |
| fill="#45b7d1" |
| stroke="#333" |
| stroke-width="2" |
| vector-effect="non-scaling-stroke"/> |
| </svg> |
| <div class="debug-info">复杂曲线路径</div> |
| </div> |
| |
| <div class="svg-container"> |
| <svg width="100" height="100" id="star-shape"> |
| <path d="M50,5 L61,35 L95,35 L68,57 L79,91 L50,70 L21,91 L32,57 L5,35 L39,35 Z" |
| fill="#f7b731" |
| stroke="#333" |
| stroke-width="2" |
| vector-effect="non-scaling-stroke"/> |
| </svg> |
| <div class="debug-info">星形路径</div> |
| </div> |
| </div> |
| |
| <div class="test-section"> |
| <div class="test-title">3. 线条元素测试</div> |
| <div class="svg-container"> |
| <svg width="120" height="80" id="line-element"> |
| <path d="M10,40 L110,40" |
| stroke="#e74c3c" |
| stroke-width="3" |
| vector-effect="non-scaling-stroke" |
| marker-end="url(#arrowhead)"/> |
| <defs> |
| <marker id="arrowhead" markerWidth="10" markerHeight="7" |
| refX="9" refY="3.5" orient="auto"> |
| <polygon points="0 0, 10 3.5, 0 7" fill="#e74c3c"/> |
| </marker> |
| </defs> |
| </svg> |
| <div class="debug-info">带箭头的直线</div> |
| </div> |
| |
| <div class="svg-container"> |
| <svg width="120" height="80" id="curved-line"> |
| <path d="M10,60 Q60,10 110,60" |
| stroke="#9b59b6" |
| stroke-width="3" |
| fill="none" |
| vector-effect="non-scaling-stroke"/> |
| </svg> |
| <div class="debug-info">二次贝塞尔曲线</div> |
| </div> |
| </div> |
| |
| <div class="test-section"> |
| <div class="test-title">4. 导出测试功能</div> |
| <button onclick="testSVGSerialization()">测试SVG序列化</button> |
| <button onclick="testBase64Conversion()">测试Base64转换</button> |
| <button onclick="testElementDimensions()">测试元素尺寸</button> |
| <button onclick="runAllTests()">运行所有测试</button> |
| |
| <div id="test-results"></div> |
| </div> |
| |
| <div class="test-section"> |
| <div class="test-title">5. 问题诊断结果</div> |
| <div id="diagnosis-results"> |
| <p>点击上方按钮开始诊断...</p> |
| </div> |
| </div> |
| </div> |
| |
| <script> |
| |
| function testSVGSerialization() { |
| const results = document.getElementById('test-results'); |
| results.innerHTML = '<h4>SVG序列化测试结果:</h4>'; |
| |
| const svgElements = ['basic-shape', 'circle-shape', 'complex-path', 'star-shape', 'line-element', 'curved-line']; |
| |
| svgElements.forEach(id => { |
| const svg = document.getElementById(id); |
| if (svg) { |
| try { |
| const serializer = new XMLSerializer(); |
| const svgString = serializer.serializeToString(svg); |
| const isValid = svgString.length > 0 && svgString.includes('<svg'); |
| |
| results.innerHTML += ` |
| <div class="${isValid ? 'success' : 'error'}"> |
| <strong>${id}:</strong> ${isValid ? '✓ 序列化成功' : '✗ 序列化失败'}<br> |
| <small>长度: ${svgString.length} 字符</small> |
| </div> |
| `; |
| } catch (error) { |
| results.innerHTML += ` |
| <div class="error"> |
| <strong>${id}:</strong> ✗ 序列化异常: ${error.message} |
| </div> |
| `; |
| } |
| } |
| }); |
| } |
| |
| |
| function testBase64Conversion() { |
| const results = document.getElementById('test-results'); |
| results.innerHTML = '<h4>Base64转换测试结果:</h4>'; |
| |
| const svg = document.getElementById('basic-shape'); |
| if (svg) { |
| try { |
| const serializer = new XMLSerializer(); |
| const svgString = serializer.serializeToString(svg); |
| const base64 = btoa(unescape(encodeURIComponent(svgString))); |
| const dataUrl = `data:image/svg+xml;base64,${base64}`; |
| |
| results.innerHTML += ` |
| <div class="success"> |
| <strong>Base64转换:</strong> ✓ 成功<br> |
| <small>Data URL长度: ${dataUrl.length} 字符</small><br> |
| <img src="${dataUrl}" style="max-width: 100px; border: 1px solid #ccc; margin-top: 5px;"> |
| </div> |
| `; |
| } catch (error) { |
| results.innerHTML += ` |
| <div class="error"> |
| <strong>Base64转换:</strong> ✗ 失败: ${error.message} |
| </div> |
| `; |
| } |
| } |
| } |
| |
| |
| function testElementDimensions() { |
| const results = document.getElementById('test-results'); |
| results.innerHTML = '<h4>元素尺寸测试结果:</h4>'; |
| |
| const svgElements = ['basic-shape', 'circle-shape', 'complex-path']; |
| |
| svgElements.forEach(id => { |
| const svg = document.getElementById(id); |
| if (svg) { |
| const clientWidth = svg.clientWidth; |
| const clientHeight = svg.clientHeight; |
| const boundingRect = svg.getBoundingClientRect(); |
| |
| const isValidSize = clientWidth > 0 && clientHeight > 0; |
| |
| results.innerHTML += ` |
| <div class="${isValidSize ? 'success' : 'error'}"> |
| <strong>${id}:</strong><br> |
| clientWidth: ${clientWidth}px<br> |
| clientHeight: ${clientHeight}px<br> |
| boundingRect: ${boundingRect.width}x${boundingRect.height}px<br> |
| ${isValidSize ? '✓ 尺寸正常' : '✗ 尺寸异常 (可能导致导出失败)'} |
| </div> |
| `; |
| } |
| }); |
| } |
| |
| |
| function runAllTests() { |
| testSVGSerialization(); |
| setTimeout(() => { |
| testBase64Conversion(); |
| setTimeout(() => { |
| testElementDimensions(); |
| setTimeout(generateDiagnosis, 500); |
| }, 500); |
| }, 500); |
| } |
| |
| |
| function generateDiagnosis() { |
| const diagnosisDiv = document.getElementById('diagnosis-results'); |
| |
| diagnosisDiv.innerHTML = ` |
| <h4>诊断报告:</h4> |
| <div class="debug-info"> |
| <strong>可能的问题原因:</strong><br> |
| 1. SVG元素尺寸为0或负数 (clientWidth < 1 || clientHeight < 1)<br> |
| 2. SVG序列化失败或返回空字符串<br> |
| 3. Base64编码过程中出现错误<br> |
| 4. 特殊形状元素(special=true)的DOM查询失败<br> |
| 5. vector-effect="non-scaling-stroke"属性导致的兼容性问题<br><br> |
| |
| <strong>建议的解决方案:</strong><br> |
| 1. 在导出前检查SVG元素的实际渲染尺寸<br> |
| 2. 添加SVG序列化的错误处理和重试机制<br> |
| 3. 确保DOM元素在导出时已完全渲染<br> |
| 4. 考虑使用setTimeout延迟导出以确保渲染完成<br> |
| 5. 添加更详细的错误日志记录<br> |
| </div> |
| `; |
| } |
| |
| |
| window.addEventListener('load', () => { |
| console.log('矢量元素导出调试页面已加载'); |
| console.log('可用的测试函数:', { |
| testSVGSerialization, |
| testBase64Conversion, |
| testElementDimensions, |
| runAllTests |
| }); |
| }); |
| </script> |
| </body> |
| </html> |