|
<!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> |