html2canvas-pro
Version:
Screenshots with JavaScript. Next generation!
603 lines (519 loc) • 20.6 kB
HTML
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>html2canvas-pro 重构后功能测试</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background: #f5f5f5;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
border-radius: 10px;
margin-bottom: 30px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.test-section {
background: white;
padding: 20px;
margin-bottom: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.test-section h2 {
color: #333;
border-bottom: 2px solid #667eea;
padding-bottom: 10px;
margin-top: 0;
}
/* 背景测试 */
.bg-color {
width: 200px;
height: 100px;
background-color: #ff6b6b;
margin: 10px;
display: inline-block;
}
.bg-image {
width: 200px;
height: 100px;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><rect fill="%23f0f" width="50" height="50"/><rect fill="%230ff" x="50" width="50" height="50"/><rect fill="%23ff0" y="50" width="50" height="50"/><rect fill="%230f0" x="50" y="50" width="50" height="50"/></svg>');
background-size: cover;
margin: 10px;
display: inline-block;
}
.bg-linear {
width: 200px;
height: 100px;
background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
margin: 10px;
display: inline-block;
}
.bg-radial {
width: 200px;
height: 100px;
background: radial-gradient(circle, #ffd93d, #ff6b6b);
margin: 10px;
display: inline-block;
}
/* 边框测试 */
.border-solid {
width: 150px;
height: 80px;
border: 5px solid #667eea;
margin: 10px;
display: inline-block;
padding: 10px;
}
.border-dashed {
width: 150px;
height: 80px;
border: 5px dashed #ff6b6b;
margin: 10px;
display: inline-block;
padding: 10px;
}
.border-dotted {
width: 150px;
height: 80px;
border: 5px dotted #4ecdc4;
margin: 10px;
display: inline-block;
padding: 10px;
}
.border-double {
width: 150px;
height: 80px;
border: 8px double #764ba2;
margin: 10px;
display: inline-block;
padding: 10px;
}
.border-rounded {
width: 150px;
height: 80px;
border: 5px solid #ffd93d;
border-radius: 15px;
margin: 10px;
display: inline-block;
padding: 10px;
}
/* 文本测试 */
.text-basic {
font-size: 18px;
color: #333;
margin: 10px 0;
}
.text-letter-spacing {
font-size: 18px;
letter-spacing: 5px;
color: #667eea;
margin: 10px 0;
}
.text-decoration {
font-size: 18px;
text-decoration: underline wavy #ff6b6b;
margin: 10px 0;
}
.text-shadow {
font-size: 24px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
color: #764ba2;
margin: 10px 0;
}
.text-overflow {
width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
border: 1px solid #ddd;
padding: 5px;
margin: 10px 0;
}
/* 效果测试 */
.effect-opacity {
width: 150px;
height: 80px;
background: #ff6b6b;
opacity: 0.5;
margin: 10px;
display: inline-block;
}
.effect-transform {
width: 150px;
height: 80px;
background: #4ecdc4;
transform: rotate(10deg) scale(0.9);
margin: 10px 20px;
display: inline-block;
}
.effect-clip {
width: 150px;
height: 80px;
background: #ffd93d;
clip-path: polygon(0 0, 100% 0, 100% 70%, 50% 100%, 0 70%);
margin: 10px;
display: inline-block;
}
/* Shadow DOM 测试 */
.shadow-host {
padding: 20px;
border: 2px solid #667eea;
border-radius: 8px;
margin: 10px 0;
}
/* 复合测试 */
.complex-box {
width: 300px;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: 5px solid #fff;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
color: white;
font-size: 18px;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
margin: 20px auto;
transform: perspective(500px) rotateY(5deg);
}
.button {
background: #667eea;
color: white;
border: none;
padding: 12px 30px;
font-size: 16px;
border-radius: 6px;
cursor: pointer;
margin: 10px 5px;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
transition: all 0.3s;
}
.button:hover {
background: #764ba2;
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
transform: translateY(-2px);
}
.button.success {
background: #4ecdc4;
}
.button.danger {
background: #ff6b6b;
}
.results {
margin-top: 30px;
padding: 20px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.results canvas {
border: 1px solid #ddd;
margin: 10px;
max-width: 100%;
}
.log {
background: #f8f9fa;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
margin: 10px 0;
font-family: 'Courier New', monospace;
font-size: 12px;
max-height: 300px;
overflow-y: auto;
}
.log-entry {
margin: 5px 0;
padding: 3px 0;
border-bottom: 1px solid #eee;
}
.log-entry.error {
color: #ff6b6b;
}
.log-entry.success {
color: #4ecdc4;
}
.status {
display: inline-block;
padding: 5px 15px;
border-radius: 20px;
font-size: 14px;
font-weight: bold;
margin: 5px;
}
.status.pass {
background: #d4edda;
color: #155724;
}
.status.fail {
background: #f8d7da;
color: #721c24;
}
.status.pending {
background: #fff3cd;
color: #856404;
}
</style>
</head>
<body>
<div class="header">
<h1>🎨 html2canvas-pro 重构后功能测试</h1>
<p>完整测试所有渲染器:Background, Border, Text, Effects</p>
<p><strong>Phase 2 完成:</strong> CanvasRenderer 从 1458行 → 681行 (-53.3%)</p>
</div>
<div class="test-section">
<h2>1. BackgroundRenderer 测试 (265行)</h2>
<div id="bg-test">
<div class="bg-color">纯色背景</div>
<div class="bg-image">图片背景</div>
<div class="bg-linear">线性渐变</div>
<div class="bg-radial">径向渐变</div>
</div>
</div>
<div class="test-section">
<h2>2. BorderRenderer 测试 (218行)</h2>
<div id="border-test">
<div class="border-solid">实心边框</div>
<div class="border-dashed">虚线边框</div>
<div class="border-dotted">点线边框</div>
<div class="border-double">双线边框</div>
<div class="border-rounded">圆角边框</div>
</div>
</div>
<div class="test-section">
<h2>3. TextRenderer 测试 (597行)</h2>
<div id="text-test">
<p class="text-basic">基础文本渲染:The quick brown fox jumps over the lazy dog</p>
<p class="text-letter-spacing">字距渲染:L E T T E R S P A C I N G</p>
<p class="text-decoration">文本装饰:下划线和波浪线效果</p>
<p class="text-shadow">文本阴影:Shadow Effect Text</p>
<p class="text-overflow">文本溢出:这是一段很长的文本,会被截断并显示省略号</p>
</div>
</div>
<div class="test-section">
<h2>4. EffectsRenderer 测试 (121行)</h2>
<div id="effects-test">
<div class="effect-opacity">透明度效果</div>
<div class="effect-transform">变换效果</div>
<div class="effect-clip">裁剪效果</div>
</div>
</div>
<div class="test-section">
<h2>5. Shadow DOM 测试 (Issue #206 修复)</h2>
<div id="shadow-test">
<div class="shadow-host">
<p>这是 Shadow DOM 宿主元素</p>
<slot>默认内容</slot>
</div>
</div>
</div>
<div class="test-section">
<h2>6. 复合功能测试</h2>
<div id="complex-test">
<div class="complex-box">
<h3 style="margin-top: 0;">完整功能展示</h3>
<p>渐变背景 + 边框 + 圆角 + 阴影 + 文本阴影 + 3D变换</p>
</div>
</div>
</div>
<div class="test-section">
<h2>7. 性能监控测试</h2>
<div>
<p>启用性能监控,查看各阶段耗时:</p>
<button class="button" onclick="testWithPerformanceMonitoring()">运行性能监控测试</button>
</div>
</div>
<div class="test-section">
<h2>8. 输入验证测试 (Validator)</h2>
<div>
<p>测试新的输入验证和安全特性:</p>
<button class="button" onclick="testValidator()">运行验证器测试</button>
</div>
</div>
<div class="test-section">
<h2>控制面板</h2>
<button class="button" onclick="runAllTests()">🚀 运行所有测试</button>
<button class="button success" onclick="runBasicTest()">基础测试</button>
<button class="button" onclick="runRenderersTest()">渲染器测试</button>
<button class="button danger" onclick="clearResults()">清除结果</button>
</div>
<div class="results">
<h2>测试结果</h2>
<div id="status-panel">
<span class="status pending">等待测试...</span>
</div>
<div class="log" id="log"></div>
<div id="canvas-results"></div>
</div>
<script src="../dist/html2canvas-pro.js"></script>
<script>
const log = document.getElementById('log');
const statusPanel = document.getElementById('status-panel');
const canvasResults = document.getElementById('canvas-results');
function addLog(message, type = 'info') {
const entry = document.createElement('div');
entry.className = `log-entry ${type}`;
entry.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
log.appendChild(entry);
log.scrollTop = log.scrollHeight;
}
function updateStatus(text, type = 'pending') {
statusPanel.innerHTML = `<span class="status ${type}">${text}</span>`;
}
function clearResults() {
log.innerHTML = '';
canvasResults.innerHTML = '';
updateStatus('等待测试...', 'pending');
addLog('测试结果已清除');
}
async function runBasicTest() {
addLog('开始基础渲染测试...');
updateStatus('测试中...', 'pending');
try {
const element = document.querySelector('.header');
const canvas = await html2canvas(element, {
logging: true,
scale: 2
});
const section = document.createElement('div');
section.innerHTML = '<h3>基础测试结果:</h3>';
section.appendChild(canvas);
canvasResults.appendChild(section);
addLog(`✅ 基础测试完成 (${canvas.width}x${canvas.height})`, 'success');
updateStatus('基础测试通过', 'pass');
} catch (error) {
addLog(`❌ 基础测试失败: ${error.message}`, 'error');
updateStatus('基础测试失败', 'fail');
}
}
async function runRenderersTest() {
addLog('开始渲染器功能测试...');
updateStatus('测试中...', 'pending');
const tests = [
{ id: 'bg-test', name: 'BackgroundRenderer' },
{ id: 'border-test', name: 'BorderRenderer' },
{ id: 'text-test', name: 'TextRenderer' },
{ id: 'effects-test', name: 'EffectsRenderer' }
];
const rendererSection = document.createElement('div');
const rendererTitle = document.createElement('h3');
rendererTitle.textContent = '渲染器测试结果:';
rendererSection.appendChild(rendererTitle);
let passCount = 0;
for (const test of tests) {
try {
addLog(`测试 ${test.name}...`);
const element = document.getElementById(test.id);
const canvas = await html2canvas(element, {
logging: false,
scale: 1
});
const wrapper = document.createElement('div');
const title = document.createElement('h4');
title.textContent = `${test.name} ✅`;
wrapper.appendChild(title);
wrapper.appendChild(canvas);
rendererSection.appendChild(wrapper);
addLog(`✅ ${test.name} 测试通过`, 'success');
passCount++;
} catch (error) {
addLog(`❌ ${test.name} 测试失败: ${error.message}`, 'error');
}
}
canvasResults.appendChild(rendererSection);
const status = passCount === tests.length ? 'pass' : 'fail';
updateStatus(`渲染器测试: ${passCount}/${tests.length} 通过`, status);
}
async function testWithPerformanceMonitoring() {
addLog('开始性能监控测试...');
updateStatus('性能测试中...', 'pending');
try {
const element = document.querySelector('.complex-box');
// 启用性能监控
const canvas = await html2canvas(element, {
logging: true,
enablePerformanceMonitoring: true,
scale: 2
});
addLog('✅ 性能监控测试完成,请查看控制台输出', 'success');
addLog('📊 应该看到详细的性能分析数据', 'success');
updateStatus('性能监控正常', 'pass');
const perfSection = document.createElement('div');
const perfTitle = document.createElement('h3');
perfTitle.textContent = '性能监控测试:';
const perfDesc = document.createElement('p');
perfDesc.textContent = '请查看浏览器控制台的性能数据输出';
perfSection.appendChild(perfTitle);
perfSection.appendChild(perfDesc);
perfSection.appendChild(canvas);
canvasResults.appendChild(perfSection);
} catch (error) {
addLog(`❌ 性能监控测试失败: ${error.message}`, 'error');
updateStatus('性能监控失败', 'fail');
}
}
async function testValidator() {
addLog('开始验证器测试...');
try {
// 测试1: 正常情况
addLog('测试1: 正常URL...');
const element1 = document.createElement('div');
element1.innerHTML = '<img src="https://example.com/image.jpg">';
// 这应该正常工作(如果没有配置验证器)
addLog('✅ 正常URL测试通过', 'success');
// 测试2: 检查是否支持自定义验证器
addLog('测试2: 检查验证器支持...');
if (typeof window.html2canvas === 'function') {
addLog('✅ html2canvas 函数可用', 'success');
}
// 测试3: 检查新导出
if (window.createDefaultValidator || window.Validator) {
addLog('✅ 验证器类已导出', 'success');
} else {
addLog('⚠️ 验证器类未在全局导出(可能是模块化)', 'info');
}
addLog('✅ 验证器测试完成', 'success');
updateStatus('验证器正常', 'pass');
} catch (error) {
addLog(`❌ 验证器测试失败: ${error.message}`, 'error');
updateStatus('验证器失败', 'fail');
}
}
async function runAllTests() {
clearResults();
addLog('======================================');
addLog('🎯 开始完整功能测试');
addLog('======================================');
addLog(`测试环境: ${navigator.userAgent}`);
addLog(`测试时间: ${new Date().toLocaleString()}`);
addLog('--------------------------------------');
updateStatus('运行完整测试...', 'pending');
// 依次运行所有测试
await runBasicTest();
await new Promise(resolve => setTimeout(resolve, 500));
await runRenderersTest();
await new Promise(resolve => setTimeout(resolve, 500));
await testWithPerformanceMonitoring();
await new Promise(resolve => setTimeout(resolve, 500));
await testValidator();
addLog('--------------------------------------');
addLog('✅ 所有测试完成!', 'success');
addLog('======================================');
updateStatus('所有测试完成 ✅', 'pass');
}
// 页面加载完成后自动记录
window.addEventListener('load', () => {
addLog('页面加载完成');
addLog('html2canvas-pro 重构版本已加载');
addLog('点击按钮开始测试...');
});
</script>
</body>
</html>