Files
own-tools/cmd/toolbox/web/index.html
T
2026-02-23 19:59:40 -08:00

225 lines
7.1 KiB
HTML

<!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, Helvetica, Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f7;
color: #1d1d1f;
}
.container {
max-width: 1000px;
margin: 0 auto;
padding: 40px 20px;
display: flex;
flex-direction: column;
gap: 24px;
}
header {
text-align: center;
margin-bottom: 10px;
}
header h1 { font-size: 32px; margin-bottom: 8px; }
header p { color: #86868b; margin: 0; }
.card {
background: white;
border-radius: 16px;
padding: 28px;
box-shadow: 0 8px 30px rgba(0,0,0,0.04);
}
.form-layout {
display: flex;
flex-direction: column;
gap: 20px;
}
.input-row-top {
width: 100%;
}
.input-row-bottom {
display: flex;
gap: 16px;
align-items: flex-end;
}
.input-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.input-group.flex-main { flex: 2; }
.input-group.flex-side { flex: 1; }
label {
font-size: 13px;
font-weight: 600;
color: #1d1d1f;
text-transform: uppercase;
letter-spacing: 0.5px;
}
input[type="text"] {
width: 100%;
box-sizing: border-box;
padding: 14px 16px;
border: 1px solid #d2d2d7;
border-radius: 10px;
font-size: 18px;
background-color: #fbfbfd;
transition: all 0.2s;
}
input[type="text"]:focus {
border-color: #0071e3;
background-color: #fff;
box-shadow: 0 0 0 4px rgba(0,113,227,0.1);
outline: none;
}
select {
appearance: none;
padding: 12px 16px;
border: 1px solid #d2d2d7;
border-radius: 10px;
font-size: 15px;
background-color: #fbfbfd;
cursor: pointer;
}
button {
background-color: #0071e3;
color: white;
border: none;
padding: 14px 32px;
border-radius: 10px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
height: 48px;
}
button:hover { background-color: #0077ed; transform: translateY(-1px); }
button:active { transform: translateY(0); }
#preview-container {
width: 100%;
height: 850px;
border-radius: 16px;
overflow: hidden;
background: #fff;
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
display: none;
}
iframe { width: 100%; height: 100%; border: none; }
.empty-state {
text-align: center;
padding: 80px 0;
border: 2px dashed #d2d2d7;
border-radius: 16px;
color: #86868b;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>汉字字帖工具箱</h1>
<p>生成标准笔顺教学字帖,支持 A4/Letter 打印</p>
</header>
<div class="card">
<div class="form-layout">
<div class="input-row-top">
<div class="input-group">
<label for="chars">输入想要生成的汉字</label>
<input type="text" id="chars" placeholder="例如:永和九年,岁在癸丑..." value="永">
</div>
</div>
<div class="input-row-bottom">
<div class="input-group flex-main">
<label for="mode">布局模式</label>
<select id="mode">
<option value="teaching">2x3 教学方格 (带笔顺、箭头、序号)</option>
<option value="step">步进式分解 (逐笔展示过程)</option>
</select>
</div>
<div class="input-group flex-side">
<label for="paper_size">纸张大小</label>
<select id="paper_size">
<option value="A4">A4 (210x297mm)</option>
<option value="Letter">Letter (8.5x11in)</option>
</select>
</div>
<button onclick="generatePDF()">生成预览</button>
</div>
</div>
</div>
<div id="preview-container">
<iframe id="pdf-frame"></iframe>
</div>
<div id="empty-state" class="empty-state">
<p>在上方输入汉字并点击按钮,即可生成高清矢量字帖预览</p>
</div>
</div>
<script>
async function generatePDF() {
const chars = document.getElementById('chars').value;
const mode = document.getElementById('mode').value;
const paper_size = document.getElementById('paper_size').value;
if (!chars.trim()) {
alert('请输入汉字');
return;
}
const btn = document.querySelector('button');
const originalText = btn.innerText;
btn.innerText = '正在绘图中...';
btn.disabled = true;
try {
const response = await fetch('/api/jitie/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
chars: chars,
mode: mode,
flip_y: true,
paper_size: paper_size
})
});
if (response.ok) {
const blob = await response.blob();
const url = URL.createObjectURL(blob);
document.getElementById('empty-state').style.display = 'none';
const container = document.getElementById('preview-container');
container.style.display = 'block';
document.getElementById('pdf-frame').src = url;
} else {
const err = await response.json();
alert('生成失败: ' + (err.error || '未知错误'));
}
} catch (e) {
alert('网络请求失败,请检查后端服务是否运行');
} finally {
btn.innerText = originalText;
btn.disabled = false;
}
}
</script>
</body>
</html>