CatPtain commited on
Commit
744cf12
·
verified ·
1 Parent(s): a105c80

Upload test-production-vector-export.html

Browse files
frontend/public/test-production-vector-export.html ADDED
@@ -0,0 +1,529 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>生产环境矢量图形导出测试</title>
7
+ <style>
8
+ body {
9
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
10
+ margin: 0;
11
+ padding: 20px;
12
+ background: #f5f5f5;
13
+ }
14
+
15
+ .container {
16
+ max-width: 1200px;
17
+ margin: 0 auto;
18
+ background: white;
19
+ border-radius: 8px;
20
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
21
+ padding: 30px;
22
+ }
23
+
24
+ .header {
25
+ text-align: center;
26
+ margin-bottom: 40px;
27
+ padding-bottom: 20px;
28
+ border-bottom: 2px solid #e0e0e0;
29
+ }
30
+
31
+ .test-section {
32
+ margin-bottom: 40px;
33
+ padding: 20px;
34
+ border: 1px solid #e0e0e0;
35
+ border-radius: 6px;
36
+ background: #fafafa;
37
+ }
38
+
39
+ .test-title {
40
+ font-size: 18px;
41
+ font-weight: 600;
42
+ color: #333;
43
+ margin-bottom: 15px;
44
+ padding-bottom: 10px;
45
+ border-bottom: 1px solid #ddd;
46
+ }
47
+
48
+ .vector-samples {
49
+ display: grid;
50
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
51
+ gap: 20px;
52
+ margin-top: 20px;
53
+ }
54
+
55
+ .vector-item {
56
+ background: white;
57
+ border: 1px solid #ddd;
58
+ border-radius: 4px;
59
+ padding: 15px;
60
+ text-align: center;
61
+ }
62
+
63
+ .vector-display {
64
+ width: 100%;
65
+ height: 120px;
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: center;
69
+ margin-bottom: 10px;
70
+ background: #f9f9f9;
71
+ border: 1px dashed #ccc;
72
+ }
73
+
74
+ .test-controls {
75
+ margin-top: 30px;
76
+ text-align: center;
77
+ }
78
+
79
+ .btn {
80
+ background: #007bff;
81
+ color: white;
82
+ border: none;
83
+ padding: 12px 24px;
84
+ border-radius: 4px;
85
+ cursor: pointer;
86
+ margin: 0 10px;
87
+ font-size: 14px;
88
+ transition: background 0.2s;
89
+ }
90
+
91
+ .btn:hover {
92
+ background: #0056b3;
93
+ }
94
+
95
+ .btn.secondary {
96
+ background: #6c757d;
97
+ }
98
+
99
+ .btn.secondary:hover {
100
+ background: #545b62;
101
+ }
102
+
103
+ .results {
104
+ margin-top: 30px;
105
+ padding: 20px;
106
+ background: #f8f9fa;
107
+ border-radius: 4px;
108
+ border-left: 4px solid #007bff;
109
+ }
110
+
111
+ .result-item {
112
+ margin-bottom: 10px;
113
+ font-family: monospace;
114
+ font-size: 12px;
115
+ }
116
+
117
+ .success { color: #28a745; }
118
+ .error { color: #dc3545; }
119
+ .warning { color: #ffc107; }
120
+ .info { color: #17a2b8; }
121
+
122
+ .performance-metrics {
123
+ display: grid;
124
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
125
+ gap: 15px;
126
+ margin-top: 20px;
127
+ }
128
+
129
+ .metric-card {
130
+ background: white;
131
+ padding: 15px;
132
+ border-radius: 4px;
133
+ border: 1px solid #e0e0e0;
134
+ text-align: center;
135
+ }
136
+
137
+ .metric-value {
138
+ font-size: 24px;
139
+ font-weight: bold;
140
+ color: #007bff;
141
+ }
142
+
143
+ .metric-label {
144
+ font-size: 12px;
145
+ color: #666;
146
+ margin-top: 5px;
147
+ }
148
+ </style>
149
+ </head>
150
+ <body>
151
+ <div class="container">
152
+ <div class="header">
153
+ <h1>PPTist 生产环境矢量图形导出测试</h1>
154
+ <p>测试矢量图形在生产环境下的导出功能和性能表现</p>
155
+ </div>
156
+
157
+ <!-- 基础SVG测试 -->
158
+ <div class="test-section">
159
+ <div class="test-title">基础SVG图形测试</div>
160
+ <div class="vector-samples">
161
+ <div class="vector-item">
162
+ <div class="vector-display">
163
+ <svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
164
+ <circle cx="40" cy="40" r="30" fill="#007bff" stroke="#0056b3" stroke-width="2"/>
165
+ </svg>
166
+ </div>
167
+ <div>圆形</div>
168
+ </div>
169
+
170
+ <div class="vector-item">
171
+ <div class="vector-display">
172
+ <svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
173
+ <rect x="10" y="10" width="60" height="60" fill="#28a745" stroke="#1e7e34" stroke-width="2" rx="5"/>
174
+ </svg>
175
+ </div>
176
+ <div>矩形</div>
177
+ </div>
178
+
179
+ <div class="vector-item">
180
+ <div class="vector-display">
181
+ <svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
182
+ <polygon points="40,10 70,70 10,70" fill="#ffc107" stroke="#e0a800" stroke-width="2"/>
183
+ </svg>
184
+ </div>
185
+ <div>三角形</div>
186
+ </div>
187
+ </div>
188
+ </div>
189
+
190
+ <!-- 复杂路径测试 -->
191
+ <div class="test-section">
192
+ <div class="test-title">复杂路径图形测试</div>
193
+ <div class="vector-samples">
194
+ <div class="vector-item">
195
+ <div class="vector-display">
196
+ <svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
197
+ <path d="M40,10 L70,40 L40,70 L10,40 Z" fill="#dc3545" stroke="#c82333" stroke-width="2"/>
198
+ </svg>
199
+ </div>
200
+ <div>菱形路径</div>
201
+ </div>
202
+
203
+ <div class="vector-item">
204
+ <div class="vector-display">
205
+ <svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
206
+ <path d="M40,10 Q70,40 40,70 Q10,40 40,10" fill="#6f42c1" stroke="#59359a" stroke-width="2"/>
207
+ </svg>
208
+ </div>
209
+ <div>曲线路径</div>
210
+ </div>
211
+
212
+ <div class="vector-item">
213
+ <div class="vector-display">
214
+ <svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
215
+ <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"/>
216
+ </svg>
217
+ </div>
218
+ <div>星形路径</div>
219
+ </div>
220
+ </div>
221
+ </div>
222
+
223
+ <!-- 带特效的SVG测试 -->
224
+ <div class="test-section">
225
+ <div class="test-title">特效SVG测试(生产环境优化)</div>
226
+ <div class="vector-samples">
227
+ <div class="vector-item">
228
+ <div class="vector-display">
229
+ <svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
230
+ <defs>
231
+ <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
232
+ <stop offset="0%" style="stop-color:#007bff;stop-opacity:1" />
233
+ <stop offset="100%" style="stop-color:#0056b3;stop-opacity:1" />
234
+ </linearGradient>
235
+ </defs>
236
+ <circle cx="40" cy="40" r="30" fill="url(#grad1)" vector-effect="non-scaling-stroke"/>
237
+ </svg>
238
+ </div>
239
+ <div>渐变圆形</div>
240
+ </div>
241
+
242
+ <div class="vector-item">
243
+ <div class="vector-display">
244
+ <svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
245
+ <defs>
246
+ <filter id="shadow">
247
+ <feDropShadow dx="2" dy="2" stdDeviation="2" flood-color="#000" flood-opacity="0.3"/>
248
+ </filter>
249
+ </defs>
250
+ <rect x="15" y="15" width="50" height="50" fill="#28a745" filter="url(#shadow)" vector-effect="non-scaling-stroke"/>
251
+ </svg>
252
+ </div>
253
+ <div>阴影矩形</div>
254
+ </div>
255
+ </div>
256
+ </div>
257
+
258
+ <!-- 测试控制 -->
259
+ <div class="test-controls">
260
+ <button class="btn" onclick="runBasicTests()">运行基础测试</button>
261
+ <button class="btn" onclick="runPerformanceTests()">性能测试</button>
262
+ <button class="btn" onclick="runExportTests()">导出测试</button>
263
+ <button class="btn secondary" onclick="clearResults()">清除结果</button>
264
+ </div>
265
+
266
+ <!-- 测试结果 -->
267
+ <div class="results" id="results" style="display: none;">
268
+ <h3>测试结果</h3>
269
+ <div id="result-content"></div>
270
+ </div>
271
+
272
+ <!-- 性能指标 -->
273
+ <div class="performance-metrics" id="metrics" style="display: none;">
274
+ <div class="metric-card">
275
+ <div class="metric-value" id="svg-render-time">-</div>
276
+ <div class="metric-label">SVG渲染时间 (ms)</div>
277
+ </div>
278
+ <div class="metric-card">
279
+ <div class="metric-value" id="export-success-rate">-</div>
280
+ <div class="metric-label">导出成功率 (%)</div>
281
+ </div>
282
+ <div class="metric-card">
283
+ <div class="metric-value" id="memory-usage">-</div>
284
+ <div class="metric-label">内存使用 (MB)</div>
285
+ </div>
286
+ <div class="metric-card">
287
+ <div class="metric-value" id="total-tests">-</div>
288
+ <div class="metric-label">总测试数</div>
289
+ </div>
290
+ </div>
291
+ </div>
292
+
293
+ <script>
294
+ // 测试结果存储
295
+ let testResults = [];
296
+ let performanceMetrics = {
297
+ renderTimes: [],
298
+ exportSuccessCount: 0,
299
+ totalTests: 0
300
+ };
301
+
302
+ // 环境检测
303
+ function detectEnvironment() {
304
+ const isProduction = location.hostname !== 'localhost' && location.hostname !== '127.0.0.1';
305
+ const isHuggingface = location.hostname.includes('hf.space') || location.hostname.includes('huggingface.co');
306
+
307
+ return {
308
+ isProduction,
309
+ isHuggingface,
310
+ userAgent: navigator.userAgent,
311
+ viewport: {
312
+ width: window.innerWidth,
313
+ height: window.innerHeight
314
+ }
315
+ };
316
+ }
317
+
318
+ // 添加测试结果
319
+ function addResult(type, message, data = null) {
320
+ const timestamp = new Date().toLocaleTimeString();
321
+ const result = { type, message, data, timestamp };
322
+ testResults.push(result);
323
+
324
+ const resultContent = document.getElementById('result-content');
325
+ const resultDiv = document.createElement('div');
326
+ resultDiv.className = `result-item ${type}`;
327
+ resultDiv.innerHTML = `[${timestamp}] ${message}`;
328
+
329
+ if (data) {
330
+ resultDiv.innerHTML += ` (${JSON.stringify(data)})`;
331
+ }
332
+
333
+ resultContent.appendChild(resultDiv);
334
+ document.getElementById('results').style.display = 'block';
335
+ }
336
+
337
+ // 更新性能指标
338
+ function updateMetrics() {
339
+ const avgRenderTime = performanceMetrics.renderTimes.length > 0
340
+ ? (performanceMetrics.renderTimes.reduce((a, b) => a + b, 0) / performanceMetrics.renderTimes.length).toFixed(2)
341
+ : '0';
342
+
343
+ const successRate = performanceMetrics.totalTests > 0
344
+ ? ((performanceMetrics.exportSuccessCount / performanceMetrics.totalTests) * 100).toFixed(1)
345
+ : '0';
346
+
347
+ const memoryUsage = performance.memory
348
+ ? (performance.memory.usedJSHeapSize / 1024 / 1024).toFixed(1)
349
+ : 'N/A';
350
+
351
+ document.getElementById('svg-render-time').textContent = avgRenderTime;
352
+ document.getElementById('export-success-rate').textContent = successRate;
353
+ document.getElementById('memory-usage').textContent = memoryUsage;
354
+ document.getElementById('total-tests').textContent = performanceMetrics.totalTests;
355
+
356
+ document.getElementById('metrics').style.display = 'grid';
357
+ }
358
+
359
+ // 基础测试
360
+ async function runBasicTests() {
361
+ addResult('info', '开始基础SVG测试...');
362
+
363
+ const env = detectEnvironment();
364
+ addResult('info', '环境检测完成', env);
365
+
366
+ // 测试SVG元素渲染
367
+ const svgElements = document.querySelectorAll('svg');
368
+ let successCount = 0;
369
+
370
+ for (let i = 0; i < svgElements.length; i++) {
371
+ const svg = svgElements[i];
372
+ const startTime = performance.now();
373
+
374
+ try {
375
+ // 模拟SVG处理
376
+ const serializer = new XMLSerializer();
377
+ const svgString = serializer.serializeToString(svg);
378
+
379
+ // 检查是否包含problematic属性
380
+ const hasVectorEffect = svgString.includes('vector-effect');
381
+ const hasNamespace = svgString.includes('xmlns');
382
+
383
+ const renderTime = performance.now() - startTime;
384
+ performanceMetrics.renderTimes.push(renderTime);
385
+ performanceMetrics.totalTests++;
386
+
387
+ if (svgString.length > 0) {
388
+ successCount++;
389
+ performanceMetrics.exportSuccessCount++;
390
+ addResult('success', `SVG ${i + 1} 渲染成功`, {
391
+ renderTime: renderTime.toFixed(2) + 'ms',
392
+ hasVectorEffect,
393
+ hasNamespace,
394
+ size: svgString.length
395
+ });
396
+ } else {
397
+ addResult('error', `SVG ${i + 1} 渲染失败 - 空字符串`);
398
+ }
399
+ } catch (error) {
400
+ performanceMetrics.totalTests++;
401
+ addResult('error', `SVG ${i + 1} 渲染失败`, { error: error.message });
402
+ }
403
+ }
404
+
405
+ addResult('info', `基础测试完成: ${successCount}/${svgElements.length} 成功`);
406
+ updateMetrics();
407
+ }
408
+
409
+ // 性能测试
410
+ async function runPerformanceTests() {
411
+ addResult('info', '开始性能测试...');
412
+
413
+ const testIterations = 10;
414
+ const svgElements = document.querySelectorAll('svg');
415
+
416
+ for (let iteration = 0; iteration < testIterations; iteration++) {
417
+ for (let i = 0; i < svgElements.length; i++) {
418
+ const svg = svgElements[i];
419
+ const startTime = performance.now();
420
+
421
+ try {
422
+ // 模拟复杂的SVG处理
423
+ const clone = svg.cloneNode(true);
424
+ clone.removeAttribute('vector-effect');
425
+
426
+ const serializer = new XMLSerializer();
427
+ const svgString = serializer.serializeToString(clone);
428
+ const base64 = btoa(svgString);
429
+
430
+ const renderTime = performance.now() - startTime;
431
+ performanceMetrics.renderTimes.push(renderTime);
432
+ performanceMetrics.totalTests++;
433
+ performanceMetrics.exportSuccessCount++;
434
+
435
+ } catch (error) {
436
+ performanceMetrics.totalTests++;
437
+ addResult('warning', `性能测试迭代 ${iteration + 1}, SVG ${i + 1} 失败`, { error: error.message });
438
+ }
439
+ }
440
+ }
441
+
442
+ addResult('success', `性能测试完成: ${testIterations} 轮迭代`);
443
+ updateMetrics();
444
+ }
445
+
446
+ // 导出测试
447
+ async function runExportTests() {
448
+ addResult('info', '开始导出测试...');
449
+
450
+ const testContainer = document.querySelector('.container');
451
+
452
+ try {
453
+ // 模拟HTML导出
454
+ const htmlContent = testContainer.innerHTML;
455
+ const blob = new Blob([htmlContent], { type: 'text/html' });
456
+
457
+ addResult('success', 'HTML导出测试成功', {
458
+ size: blob.size + ' bytes',
459
+ type: blob.type
460
+ });
461
+
462
+ performanceMetrics.totalTests++;
463
+ performanceMetrics.exportSuccessCount++;
464
+
465
+ } catch (error) {
466
+ performanceMetrics.totalTests++;
467
+ addResult('error', 'HTML导出测试失败', { error: error.message });
468
+ }
469
+
470
+ // 模拟图像导出测试
471
+ try {
472
+ const canvas = document.createElement('canvas');
473
+ const ctx = canvas.getContext('2d');
474
+ canvas.width = 800;
475
+ canvas.height = 600;
476
+
477
+ // 绘制测试内容
478
+ ctx.fillStyle = '#ffffff';
479
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
480
+ ctx.fillStyle = '#007bff';
481
+ ctx.fillText('导出测试', 50, 50);
482
+
483
+ const dataUrl = canvas.toDataURL('image/png');
484
+
485
+ addResult('success', '图像导出测试成功', {
486
+ format: 'PNG',
487
+ size: dataUrl.length + ' chars'
488
+ });
489
+
490
+ performanceMetrics.totalTests++;
491
+ performanceMetrics.exportSuccessCount++;
492
+
493
+ } catch (error) {
494
+ performanceMetrics.totalTests++;
495
+ addResult('error', '图像导出测试失败', { error: error.message });
496
+ }
497
+
498
+ updateMetrics();
499
+ }
500
+
501
+ // 清除结果
502
+ function clearResults() {
503
+ testResults = [];
504
+ performanceMetrics = {
505
+ renderTimes: [],
506
+ exportSuccessCount: 0,
507
+ totalTests: 0
508
+ };
509
+
510
+ document.getElementById('result-content').innerHTML = '';
511
+ document.getElementById('results').style.display = 'none';
512
+ document.getElementById('metrics').style.display = 'none';
513
+ }
514
+
515
+ // 页面加载完成后的初始化
516
+ document.addEventListener('DOMContentLoaded', function() {
517
+ addResult('info', 'PPTist 生产环境矢量图形导出测试页面已加载');
518
+
519
+ const env = detectEnvironment();
520
+ if (env.isProduction) {
521
+ addResult('info', '检测到生产环境');
522
+ }
523
+ if (env.isHuggingface) {
524
+ addResult('info', '检测到Huggingface环境');
525
+ }
526
+ });
527
+ </script>
528
+ </body>
529
+ </html>