feat: 添加字体样式工具栏,支持加粗、斜体、颜色、字体、字号调整

This commit is contained in:
Zhukj
2026-04-16 10:27:25 +08:00
parent 09e2716de4
commit a296d88d2c
3 changed files with 211 additions and 1 deletions

View File

@@ -55,6 +55,86 @@ html, body {
background: #3a7bc8;
}
/* 文本编辑器工具栏 */
.text-editor-toolbar {
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
padding: 10px 16px;
background: #fff;
border-bottom: 1px solid #e0e0e0;
flex-shrink: 0;
}
.toolbar-btn {
width: 40px;
height: 40px;
font-size: 18px;
font-weight: bold;
border: 1px solid #ddd;
border-radius: 8px;
background: #fff;
color: #333;
cursor: pointer;
transition: all 0.2s;
}
.toolbar-btn:active {
background: #f0f0f0;
}
.toolbar-btn.active {
background: #4a90e2;
color: #fff;
border-color: #4a90e2;
}
.toolbar-btn.italic {
font-style: italic;
}
.toolbar-divider {
width: 1px;
height: 28px;
background: #ddd;
margin: 0 4px;
}
.toolbar-label {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
color: #666;
}
.toolbar-label select {
padding: 6px 8px;
font-size: 13px;
border: 1px solid #ddd;
border-radius: 6px;
background: #fff;
cursor: pointer;
}
#fontSizePicker {
min-width: 60px;
}
#fontPicker {
min-width: 55px;
}
.toolbar-label input[type="color"] {
width: 36px;
height: 36px;
padding: 2px;
border: 1px solid #ddd;
border-radius: 6px;
cursor: pointer;
}
/* 图片展示区 */
.canvas-area {
flex: 1;

View File

@@ -11,7 +11,42 @@
<!-- 顶部工具栏 -->
<div class="toolbar">
<button class="btn" id="addImageBtn">添加图片</button>
<button class="btn btn-primary" id="saveBtn">保存图片</button>
<button class="btn btn-primary" id="saveBtn">保存/预览</button>
</div>
<!-- 文本编辑器工具栏 -->
<div class="text-editor-toolbar" id="textEditorToolbar">
<button class="toolbar-btn" id="boldBtn" title="加粗">B</button>
<button class="toolbar-btn italic" id="italicBtn" title="斜体">I</button>
<div class="toolbar-divider"></div>
<label class="toolbar-label">
<span>颜色</span>
<input type="color" id="colorPicker" value="#000000">
</label>
<div class="toolbar-divider"></div>
<label class="toolbar-label">
<span>字体</span>
<select id="fontPicker">
<option value="Microsoft YaHei">雅黑</option>
<option value="SimHei">黑体</option>
<option value="SimSun">宋体</option>
<option value="Arial">Arial</option>
</select>
</label>
<div class="toolbar-divider"></div>
<label class="toolbar-label">
<span>字号</span>
<select id="fontSizePicker">
<option value="12">12px</option>
<option value="14">14px</option>
<option value="16" selected>16px</option>
<option value="18">18px</option>
<option value="20">20px</option>
<option value="24">24px</option>
<option value="28">28px</option>
<option value="32">32px</option>
</select>
</label>
</div>
<!-- 图片展示区 -->

View File

@@ -12,6 +12,12 @@
const exportCanvas = document.getElementById('exportCanvas');
const longPressTip = document.getElementById('longPressTip');
const canvasArea = document.getElementById('canvasArea');
const textEditorToolbar = document.getElementById('textEditorToolbar');
const boldBtn = document.getElementById('boldBtn');
const italicBtn = document.getElementById('italicBtn');
const colorPicker = document.getElementById('colorPicker');
const fontPicker = document.getElementById('fontPicker');
const fontSizePicker = document.getElementById('fontSizePicker');
let currentImage = null;
let selectedInput = null;
@@ -80,6 +86,9 @@
// 初始化右键菜单(只在3:5预览区域)
initContextMenu();
// 初始化文本编辑器工具栏
initTextEditorToolbar();
// 显示长按提示
setTimeout(() => {
longPressTip.classList.add('show');
@@ -429,6 +438,9 @@
element.contentEditable = 'true';
element.focus();
// 更新工具栏状态
updateToolbarState(element);
// 光标定位到末尾
const range = document.createRange();
const sel = window.getSelection();
@@ -450,6 +462,44 @@
editingInput = null;
}
// 更新工具栏状态
function updateToolbarState(element) {
const style = window.getComputedStyle(element);
const fontWeight = style.fontWeight;
const fontStyle = style.fontStyle;
const color = style.color;
const fontFamily = style.fontFamily.replace(/['"]/g, '');
const fontSize = parseInt(style.fontSize);
// 更新加粗按钮状态
boldBtn.classList.toggle('active', fontWeight === 'bold' || fontWeight === '700' || parseInt(fontWeight) >= 700);
// 更新斜体按钮状态
italicBtn.classList.toggle('active', fontStyle === 'italic');
// 更新颜色选择器
colorPicker.value = rgbToHex(color);
// 更新字体选择器
for (let option of fontPicker.options) {
if (option.value === fontFamily || fontFamily.includes(option.value)) {
fontPicker.value = option.value;
break;
}
}
// 更新字号选择器
fontSizePicker.value = fontSize.toString();
}
// RGB转十六进制
function rgbToHex(rgb) {
if (rgb.startsWith('#')) return rgb;
const match = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
if (!match) return '#000000';
return '#' + [match[1], match[2], match[3]].map(x => parseInt(x).toString(16).padStart(2, '0')).join('');
}
// 取消所有选中
function deselectAll() {
if (editingInput) {
@@ -512,6 +562,51 @@
});
}
// 初始化文本编辑器工具栏
function initTextEditorToolbar() {
// 加粗按钮
boldBtn.addEventListener('click', () => {
if (!editingInput) return;
const isBold = boldBtn.classList.contains('active');
if (isBold) {
editingInput.style.fontWeight = 'normal';
} else {
editingInput.style.fontWeight = 'bold';
}
boldBtn.classList.toggle('active');
});
// 斜体按钮
italicBtn.addEventListener('click', () => {
if (!editingInput) return;
const isItalic = italicBtn.classList.contains('active');
if (isItalic) {
editingInput.style.fontStyle = 'normal';
} else {
editingInput.style.fontStyle = 'italic';
}
italicBtn.classList.toggle('active');
});
// 颜色选择器
colorPicker.addEventListener('input', () => {
if (!editingInput) return;
editingInput.style.color = colorPicker.value;
});
// 字体选择器
fontPicker.addEventListener('change', () => {
if (!editingInput) return;
editingInput.style.fontFamily = fontPicker.value + ', sans-serif';
});
// 字号选择器
fontSizePicker.addEventListener('change', () => {
if (!editingInput) return;
editingInput.style.fontSize = fontSizePicker.value + 'px';
});
}
// 显示右键菜单
function showContextMenu(x, y) {
hideContextMenu();