mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 17:27:08 +08:00
1 parent
61cfb79f25
commit
6299c0f8f9
4 files changed
+46
-17
No files matched your search
@@ -118,7 +118,7 @@
|
||||
<button id="textUnderline" class="button text-format-underline" data-text-format="underline" type="button" title="下划线" aria-label="下划线" aria-pressed="false" disabled>U</button>
|
||||
<button id="textStrikeout" class="button text-format-strikeout" data-text-format="strikeout" type="button" title="删除线" aria-label="删除线" aria-pressed="false" disabled>S</button>
|
||||
<button id="textShadow" class="button text-format-shadow" data-text-format="shadow" type="button" title="阴影" aria-label="阴影" aria-pressed="false" disabled>A</button>
|
||||
<div class="text-highlight"><button id="textHighlight" class="button" data-text-format="background" type="button" title="突出显示" aria-label="突出显示" aria-pressed="false" disabled><span aria-hidden="true">A</span></button><input id="textBackground" class="color-input" type="color" value="#ffff00" title="突出显示颜色" aria-label="突出显示颜色" disabled></div>
|
||||
<div class="text-highlight"><button id="textHighlight" class="button" data-text-format="background" type="button" title="底色" aria-label="底色" aria-pressed="false" disabled><span aria-hidden="true">A</span></button><input id="textBackground" class="color-input" type="color" value="#ffff00" title="选择底色" aria-label="选择底色" disabled></div>
|
||||
<input id="textColor" class="color-input" type="color" value="#000000" aria-label="文字颜色" title="文字颜色" disabled>
|
||||
<span>文字</span>
|
||||
</div>
|
||||
|
||||
@@ -673,6 +673,10 @@ const canvasEditor = new CanvasEditor(el.viewerPanel, {
|
||||
onPreviewText: (item, value, font, size) => callWASM("ofdgoPreviewText", item.index, item.id, value, font || null, size),
|
||||
onCommitRichText: saveRichText,
|
||||
onPreviewRichText: validateRichText,
|
||||
onTextError: (message, previous) => {
|
||||
if (message) setStatus(message);
|
||||
else if (el.statusText.textContent === previous) setStatus(state.doc ? pageStatus(state.pageIndex, state.doc.pageCount) : STATUS.ready);
|
||||
},
|
||||
onCommitText: (item, value, fontData, color = null) => item.draft
|
||||
? changeDocument("ofdgoInsertText", null, item.index, value, fontData || item.fontData, item.x, item.y, item.size, item.color, item.width, item.wrap, item.align, item.paragraphHeight, item.letterSpacing, ...textIndents(item))
|
||||
: changeDocument("ofdgoUpdateText", item, value, fontData || null, item.size, color),
|
||||
|
||||
+40
-15
@@ -150,12 +150,10 @@ export class RichTextSession {
|
||||
try {
|
||||
await this.editor.options.onPreviewRichText(editing.item, this.model, editing.frame.width, this.fonts);
|
||||
if (!current()) return;
|
||||
editing.input.removeAttribute("aria-invalid");
|
||||
editing.input.removeAttribute("title");
|
||||
this.editor.setTextError(null);
|
||||
} catch (error) {
|
||||
if (!current()) return;
|
||||
editing.input.setAttribute("aria-invalid", "true");
|
||||
editing.input.title = error.message;
|
||||
this.editor.setTextError(error);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
@@ -271,6 +269,7 @@ export class RichTextSession {
|
||||
line.append(document.createElement("br"));
|
||||
}
|
||||
input.replaceChildren(fragment);
|
||||
this.editor.fitTextInput();
|
||||
this.editing.range = null;
|
||||
input.focus({ preventScroll: true });
|
||||
restoreTextSelection(positions, this.caret);
|
||||
@@ -1485,16 +1484,12 @@ export class CanvasEditor {
|
||||
else paragraph.append(document.createElement("br"));
|
||||
input.append(paragraph);
|
||||
}
|
||||
const left = item.leftIndent || 0, right = item.rightIndent || 0;
|
||||
const left = item.leftIndent || 0;
|
||||
const frame = { ...(item.textFrame || { width: item.width, height: item.height, matrix: [1, 0, 0, 1, item.x, item.y] }) };
|
||||
if (item.wrap && item.paragraphWidth != null) frame.width = item.paragraphWidth;
|
||||
const [a, b, c, d, e, f] = frame.matrix;
|
||||
const autoSize = !source && !item.wrap && (!item.align || item.align === "left");
|
||||
Object.assign(input.style, {
|
||||
left: "0px", top: "0px",
|
||||
width: autoSize ? "max-content" : `${(frame.width - left - right) * PX_PER_MM + 4}px`,
|
||||
minWidth: autoSize ? "calc(1em + 4px)" : "0px",
|
||||
minHeight: autoSize ? "0px" : `${frame.height * PX_PER_MM + 4}px`,
|
||||
transform: `matrix(${a},${b},${c},${d},${(e + a * left) * PX_PER_MM},${(f + b * left) * PX_PER_MM})`,
|
||||
whiteSpace: item.wrap ? "pre-wrap" : "pre",
|
||||
unicodeBidi: "plaintext",
|
||||
@@ -1512,6 +1507,7 @@ export class CanvasEditor {
|
||||
item.artwork?.classList.add("edit-text-source");
|
||||
item.node.classList.add("edit-text-source");
|
||||
item.surface.append(input);
|
||||
this.fitTextInput();
|
||||
if (source) this.paintSourceText(source);
|
||||
input.addEventListener("input", () => {
|
||||
editing.rich?.readInput();
|
||||
@@ -1609,6 +1605,36 @@ export class CanvasEditor {
|
||||
else this.restoreSourceText(direction);
|
||||
}
|
||||
|
||||
fitTextInput() {
|
||||
const editing = this.input;
|
||||
if (!editing || editing.source) return;
|
||||
const { input, frame, item, rich } = editing;
|
||||
const layout = rich?.model.layout || item;
|
||||
const width = Math.max(0, frame.width - (layout.leftIndent || 0) - (layout.rightIndent || 0)) * PX_PER_MM + 4;
|
||||
const autoWidth = !layout.align || layout.align === "left";
|
||||
Object.assign(input.style, {
|
||||
width: autoWidth ? "max-content" : `${width}px`,
|
||||
maxWidth: layout.wrap ? `${width}px` : "none",
|
||||
minWidth: `${Math.min(width, (rich?.typing.size || editing.style?.size || item.size) * PX_PER_MM + 4)}px`,
|
||||
minHeight: "0px", height: "auto",
|
||||
});
|
||||
}
|
||||
|
||||
setTextError(error) {
|
||||
const editing = this.input;
|
||||
if (!editing) return;
|
||||
const previous = editing.error || "";
|
||||
editing.error = error ? String(error.message || error) : "";
|
||||
if (editing.error) {
|
||||
editing.input.setAttribute("aria-invalid", "true");
|
||||
editing.input.title = editing.error;
|
||||
} else {
|
||||
editing.input.removeAttribute("aria-invalid");
|
||||
editing.input.removeAttribute("title");
|
||||
}
|
||||
if (editing.error || previous) this.options.onTextError?.(editing.error, previous);
|
||||
}
|
||||
|
||||
promoteText(rich) {
|
||||
const editing = this.input;
|
||||
if (!editing || editing.rich || editing.composing || editing.saving) return false;
|
||||
@@ -1691,13 +1717,11 @@ export class CanvasEditor {
|
||||
try {
|
||||
const source = await this.options.onPreviewText(editing.item, value, font, size);
|
||||
if (!current()) return;
|
||||
editing.input.removeAttribute("aria-invalid");
|
||||
editing.input.removeAttribute("title");
|
||||
this.setTextError(null);
|
||||
this.paintSourceText(source);
|
||||
} catch (err) {
|
||||
if (!current()) return;
|
||||
editing.input.setAttribute("aria-invalid", "true");
|
||||
editing.input.title = err.message;
|
||||
this.setTextError(err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1783,6 +1807,7 @@ export class CanvasEditor {
|
||||
const item = { ...editing.item, ...editing.style };
|
||||
editing.input.style.fontSize = `${item.size * PX_PER_MM}px`;
|
||||
editing.input.style.color = item.color;
|
||||
this.fitTextInput();
|
||||
this.options.onTextChange();
|
||||
if ("size" in values) this.previewSourceText();
|
||||
}
|
||||
@@ -1817,8 +1842,7 @@ export class CanvasEditor {
|
||||
saved = editing.rich ? await this.options.onCommitRichText(editing.item, editing.rich.model, editing.rich.fonts)
|
||||
: await this.options.onCommitText(editing.style ? { ...editing.item, ...editing.style } : editing.item, value, editing.fontData, editing.style?.color ?? null);
|
||||
} catch (error) {
|
||||
editing.input.setAttribute("aria-invalid", "true");
|
||||
editing.input.title = error.message;
|
||||
if (this.input === editing) this.setTextError(error);
|
||||
}
|
||||
if (this.input !== editing) {
|
||||
return Boolean(saved);
|
||||
@@ -1835,6 +1859,7 @@ export class CanvasEditor {
|
||||
|
||||
closeText() {
|
||||
const editing = this.input;
|
||||
this.setTextError(null);
|
||||
this.input = null;
|
||||
if (editing) {
|
||||
editing.rich?.destroy();
|
||||
|
||||
@@ -103,7 +103,7 @@ export class FontPicker {
|
||||
if (!this.open) return;
|
||||
const rect = this.input.parentElement.getBoundingClientRect();
|
||||
if (rect.right <= 0 || rect.left >= window.innerWidth) { this.close(); return; }
|
||||
const width = Math.min(Math.max(rect.width, 300), window.innerWidth - 16);
|
||||
const width = Math.min(rect.width, window.innerWidth - 16);
|
||||
Object.assign(this.list.style, { left: `${Math.max(8, Math.min(rect.left, window.innerWidth - width - 8))}px`,
|
||||
top: `${rect.bottom + 4}px`, width: `${width}px`, maxHeight: `${Math.max(40, Math.min(280, window.innerHeight - rect.bottom - 12))}px` });
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user