web_ppt / frontend /public /test-production-vector-export.html
CatPtain's picture
Upload test-production-vector-export.html
744cf12 verified
<!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: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
margin: 0;
padding: 20px;
background: #f5f5f5;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
padding: 30px;
}
.header {
text-align: center;
margin-bottom: 40px;
padding-bottom: 20px;
border-bottom: 2px solid #e0e0e0;
}
.test-section {
margin-bottom: 40px;
padding: 20px;
border: 1px solid #e0e0e0;
border-radius: 6px;
background: #fafafa;
}
.test-title {
font-size: 18px;
font-weight: 600;
color: #333;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #ddd;
}
.vector-samples {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-top: 20px;
}
.vector-item {
background: white;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
text-align: center;
}
.vector-display {
width: 100%;
height: 120px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10px;
background: #f9f9f9;
border: 1px dashed #ccc;
}
.test-controls {
margin-top: 30px;
text-align: center;
}
.btn {
background: #007bff;
color: white;
border: none;
padding: 12px 24px;
border-radius: 4px;
cursor: pointer;
margin: 0 10px;
font-size: 14px;
transition: background 0.2s;
}
.btn:hover {
background: #0056b3;
}
.btn.secondary {
background: #6c757d;
}
.btn.secondary:hover {
background: #545b62;
}
.results {
margin-top: 30px;
padding: 20px;
background: #f8f9fa;
border-radius: 4px;
border-left: 4px solid #007bff;
}
.result-item {
margin-bottom: 10px;
font-family: monospace;
font-size: 12px;
}
.success { color: #28a745; }
.error { color: #dc3545; }
.warning { color: #ffc107; }
.info { color: #17a2b8; }
.performance-metrics {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-top: 20px;
}
.metric-card {
background: white;
padding: 15px;
border-radius: 4px;
border: 1px solid #e0e0e0;
text-align: center;
}
.metric-value {
font-size: 24px;
font-weight: bold;
color: #007bff;
}
.metric-label {
font-size: 12px;
color: #666;
margin-top: 5px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>PPTist 生产环境矢量图形导出测试</h1>
<p>测试矢量图形在生产环境下的导出功能和性能表现</p>
</div>
<!-- 基础SVG测试 -->
<div class="test-section">
<div class="test-title">基础SVG图形测试</div>
<div class="vector-samples">
<div class="vector-item">
<div class="vector-display">
<svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
<circle cx="40" cy="40" r="30" fill="#007bff" stroke="#0056b3" stroke-width="2"/>
</svg>
</div>
<div>圆形</div>
</div>
<div class="vector-item">
<div class="vector-display">
<svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="10" width="60" height="60" fill="#28a745" stroke="#1e7e34" stroke-width="2" rx="5"/>
</svg>
</div>
<div>矩形</div>
</div>
<div class="vector-item">
<div class="vector-display">
<svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
<polygon points="40,10 70,70 10,70" fill="#ffc107" stroke="#e0a800" stroke-width="2"/>
</svg>
</div>
<div>三角形</div>
</div>
</div>
</div>
<!-- 复杂路径测试 -->
<div class="test-section">
<div class="test-title">复杂路径图形测试</div>
<div class="vector-samples">
<div class="vector-item">
<div class="vector-display">
<svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
<path d="M40,10 L70,40 L40,70 L10,40 Z" fill="#dc3545" stroke="#c82333" stroke-width="2"/>
</svg>
</div>
<div>菱形路径</div>
</div>
<div class="vector-item">
<div class="vector-display">
<svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
<path d="M40,10 Q70,40 40,70 Q10,40 40,10" fill="#6f42c1" stroke="#59359a" stroke-width="2"/>
</svg>
</div>
<div>曲线路径</div>
</div>
<div class="vector-item">
<div class="vector-display">
<svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
<path d="M40,15 L50,35 L70,35 L56,50 L62,70 L40,58 L18,70 L24,50 L10,35 L30,35 Z" fill="#fd7e14" stroke="#e8590c" stroke-width="1"/>
</svg>
</div>
<div>星形路径</div>
</div>
</div>
</div>
<!-- 带特效的SVG测试 -->
<div class="test-section">
<div class="test-title">特效SVG测试(生产环境优化)</div>
<div class="vector-samples">
<div class="vector-item">
<div class="vector-display">
<svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#007bff;stop-opacity:1" />
<stop offset="100%" style="stop-color:#0056b3;stop-opacity:1" />
</linearGradient>
</defs>
<circle cx="40" cy="40" r="30" fill="url(#grad1)" vector-effect="non-scaling-stroke"/>
</svg>
</div>
<div>渐变圆形</div>
</div>
<div class="vector-item">
<div class="vector-display">
<svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="shadow">
<feDropShadow dx="2" dy="2" stdDeviation="2" flood-color="#000" flood-opacity="0.3"/>
</filter>
</defs>
<rect x="15" y="15" width="50" height="50" fill="#28a745" filter="url(#shadow)" vector-effect="non-scaling-stroke"/>
</svg>
</div>
<div>阴影矩形</div>
</div>
</div>
</div>
<!-- 测试控制 -->
<div class="test-controls">
<button class="btn" onclick="runBasicTests()">运行基础测试</button>
<button class="btn" onclick="runPerformanceTests()">性能测试</button>
<button class="btn" onclick="runExportTests()">导出测试</button>
<button class="btn secondary" onclick="clearResults()">清除结果</button>
</div>
<!-- 测试结果 -->
<div class="results" id="results" style="display: none;">
<h3>测试结果</h3>
<div id="result-content"></div>
</div>
<!-- 性能指标 -->
<div class="performance-metrics" id="metrics" style="display: none;">
<div class="metric-card">
<div class="metric-value" id="svg-render-time">-</div>
<div class="metric-label">SVG渲染时间 (ms)</div>
</div>
<div class="metric-card">
<div class="metric-value" id="export-success-rate">-</div>
<div class="metric-label">导出成功率 (%)</div>
</div>
<div class="metric-card">
<div class="metric-value" id="memory-usage">-</div>
<div class="metric-label">内存使用 (MB)</div>
</div>
<div class="metric-card">
<div class="metric-value" id="total-tests">-</div>
<div class="metric-label">总测试数</div>
</div>
</div>
</div>
<script>
// 测试结果存储
let testResults = [];
let performanceMetrics = {
renderTimes: [],
exportSuccessCount: 0,
totalTests: 0
};
// 环境检测
function detectEnvironment() {
const isProduction = location.hostname !== 'localhost' && location.hostname !== '127.0.0.1';
const isHuggingface = location.hostname.includes('hf.space') || location.hostname.includes('huggingface.co');
return {
isProduction,
isHuggingface,
userAgent: navigator.userAgent,
viewport: {
width: window.innerWidth,
height: window.innerHeight
}
};
}
// 添加测试结果
function addResult(type, message, data = null) {
const timestamp = new Date().toLocaleTimeString();
const result = { type, message, data, timestamp };
testResults.push(result);
const resultContent = document.getElementById('result-content');
const resultDiv = document.createElement('div');
resultDiv.className = `result-item ${type}`;
resultDiv.innerHTML = `[${timestamp}] ${message}`;
if (data) {
resultDiv.innerHTML += ` (${JSON.stringify(data)})`;
}
resultContent.appendChild(resultDiv);
document.getElementById('results').style.display = 'block';
}
// 更新性能指标
function updateMetrics() {
const avgRenderTime = performanceMetrics.renderTimes.length > 0
? (performanceMetrics.renderTimes.reduce((a, b) => a + b, 0) / performanceMetrics.renderTimes.length).toFixed(2)
: '0';
const successRate = performanceMetrics.totalTests > 0
? ((performanceMetrics.exportSuccessCount / performanceMetrics.totalTests) * 100).toFixed(1)
: '0';
const memoryUsage = performance.memory
? (performance.memory.usedJSHeapSize / 1024 / 1024).toFixed(1)
: 'N/A';
document.getElementById('svg-render-time').textContent = avgRenderTime;
document.getElementById('export-success-rate').textContent = successRate;
document.getElementById('memory-usage').textContent = memoryUsage;
document.getElementById('total-tests').textContent = performanceMetrics.totalTests;
document.getElementById('metrics').style.display = 'grid';
}
// 基础测试
async function runBasicTests() {
addResult('info', '开始基础SVG测试...');
const env = detectEnvironment();
addResult('info', '环境检测完成', env);
// 测试SVG元素渲染
const svgElements = document.querySelectorAll('svg');
let successCount = 0;
for (let i = 0; i < svgElements.length; i++) {
const svg = svgElements[i];
const startTime = performance.now();
try {
// 模拟SVG处理
const serializer = new XMLSerializer();
const svgString = serializer.serializeToString(svg);
// 检查是否包含problematic属性
const hasVectorEffect = svgString.includes('vector-effect');
const hasNamespace = svgString.includes('xmlns');
const renderTime = performance.now() - startTime;
performanceMetrics.renderTimes.push(renderTime);
performanceMetrics.totalTests++;
if (svgString.length > 0) {
successCount++;
performanceMetrics.exportSuccessCount++;
addResult('success', `SVG ${i + 1} 渲染成功`, {
renderTime: renderTime.toFixed(2) + 'ms',
hasVectorEffect,
hasNamespace,
size: svgString.length
});
} else {
addResult('error', `SVG ${i + 1} 渲染失败 - 空字符串`);
}
} catch (error) {
performanceMetrics.totalTests++;
addResult('error', `SVG ${i + 1} 渲染失败`, { error: error.message });
}
}
addResult('info', `基础测试完成: ${successCount}/${svgElements.length} 成功`);
updateMetrics();
}
// 性能测试
async function runPerformanceTests() {
addResult('info', '开始性能测试...');
const testIterations = 10;
const svgElements = document.querySelectorAll('svg');
for (let iteration = 0; iteration < testIterations; iteration++) {
for (let i = 0; i < svgElements.length; i++) {
const svg = svgElements[i];
const startTime = performance.now();
try {
// 模拟复杂的SVG处理
const clone = svg.cloneNode(true);
clone.removeAttribute('vector-effect');
const serializer = new XMLSerializer();
const svgString = serializer.serializeToString(clone);
const base64 = btoa(svgString);
const renderTime = performance.now() - startTime;
performanceMetrics.renderTimes.push(renderTime);
performanceMetrics.totalTests++;
performanceMetrics.exportSuccessCount++;
} catch (error) {
performanceMetrics.totalTests++;
addResult('warning', `性能测试迭代 ${iteration + 1}, SVG ${i + 1} 失败`, { error: error.message });
}
}
}
addResult('success', `性能测试完成: ${testIterations} 轮迭代`);
updateMetrics();
}
// 导出测试
async function runExportTests() {
addResult('info', '开始导出测试...');
const testContainer = document.querySelector('.container');
try {
// 模拟HTML导出
const htmlContent = testContainer.innerHTML;
const blob = new Blob([htmlContent], { type: 'text/html' });
addResult('success', 'HTML导出测试成功', {
size: blob.size + ' bytes',
type: blob.type
});
performanceMetrics.totalTests++;
performanceMetrics.exportSuccessCount++;
} catch (error) {
performanceMetrics.totalTests++;
addResult('error', 'HTML导出测试失败', { error: error.message });
}
// 模拟图像导出测试
try {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 600;
// 绘制测试内容
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#007bff';
ctx.fillText('导出测试', 50, 50);
const dataUrl = canvas.toDataURL('image/png');
addResult('success', '图像导出测试成功', {
format: 'PNG',
size: dataUrl.length + ' chars'
});
performanceMetrics.totalTests++;
performanceMetrics.exportSuccessCount++;
} catch (error) {
performanceMetrics.totalTests++;
addResult('error', '图像导出测试失败', { error: error.message });
}
updateMetrics();
}
// 清除结果
function clearResults() {
testResults = [];
performanceMetrics = {
renderTimes: [],
exportSuccessCount: 0,
totalTests: 0
};
document.getElementById('result-content').innerHTML = '';
document.getElementById('results').style.display = 'none';
document.getElementById('metrics').style.display = 'none';
}
// 页面加载完成后的初始化
document.addEventListener('DOMContentLoaded', function() {
addResult('info', 'PPTist 生产环境矢量图形导出测试页面已加载');
const env = detectEnvironment();
if (env.isProduction) {
addResult('info', '检测到生产环境');
}
if (env.isHuggingface) {
addResult('info', '检测到Huggingface环境');
}
});
</script>
</body>
</html>