feat(前端界面): 优化水印选中与批注显示,修复PDF多余边框,统一弹窗文案与布局
build.yaml / build (push) Successful in 38s

This commit is contained in:
xiaoqidun committed 2026-09-18 09:10:51 +08:00
1 parent f90b8c80c3
commit 526a207aa6
4 files changed
+34 -18

No files matched your search

+2 -2
View File
@@ -270,11 +270,11 @@
<form id="annotationCreateForm"> <form id="annotationCreateForm">
<label class="form-row" data-annotation="watermark"><span>类型</span><select id="annotationContent"><option value="text">文字</option><option value="image">图片</option></select></label> <label class="form-row" data-annotation="watermark"><span>类型</span><select id="annotationContent"><option value="text">文字</option><option value="image">图片</option></select></label>
<label class="form-row" data-annotation="replace"><span>原文</span><select id="annotationOld"></select></label> <label class="form-row" data-annotation="replace"><span>原文</span><select id="annotationOld"></select></label>
<label class="form-row" data-annotation="replace"><span>字体</span><select id="annotationFont"><option value="keep">原字体</option><option value="current">当前字体</option></select></label> <label class="form-row" data-annotation="replace"><span>字体</span><select id="annotationFont"><option value="keep">原有</option><option value="current">当前</option></select></label>
<label class="form-row" id="annotationTextRow"><span>内容</span><textarea id="annotationText" rows="2" required></textarea></label> <label class="form-row" id="annotationTextRow"><span>内容</span><textarea id="annotationText" rows="2" required></textarea></label>
<label class="form-row" id="annotationImageRow" hidden><span>图片</span><input id="annotationImage" type="file" accept="image/png,image/jpeg,image/bmp,image/tiff,image/gif,image/webp"></label> <label class="form-row" id="annotationImageRow" hidden><span>图片</span><input id="annotationImage" type="file" accept="image/png,image/jpeg,image/bmp,image/tiff,image/gif,image/webp"></label>
<label class="form-row" data-annotation="note watermark stamp link"><span>作者</span><input id="annotationAuthor" type="text"></label> <label class="form-row" data-annotation="note watermark stamp link"><span>作者</span><input id="annotationAuthor" type="text"></label>
<label class="form-row" data-annotation="link"><span>目标</span><select id="annotationLinkKind"><option value="uri">网址</option><option value="page">页面</option><option value="keep" hidden>原链接</option></select></label> <label class="form-row" data-annotation="link"><span>目标</span><select id="annotationLinkKind"><option value="uri">网址</option><option value="page">页面</option><option value="keep" hidden>原有</option></select></label>
<label class="form-row" data-annotation="link" id="annotationAddressRow"><span>网址</span><input id="annotationAddress" type="text"></label> <label class="form-row" data-annotation="link" id="annotationAddressRow"><span>网址</span><input id="annotationAddress" type="text"></label>
<label class="form-row" data-annotation="link" id="annotationTargetRow"><span>页码</span><input id="annotationTarget" type="number" min="1" value="1"></label> <label class="form-row" data-annotation="link" id="annotationTargetRow"><span>页码</span><input id="annotationTarget" type="number" min="1" value="1"></label>
<div class="form-pair" data-annotation="note watermark stamp link"> <div class="form-pair" data-annotation="note watermark stamp link">
+14 -4
View File
@@ -1316,6 +1316,7 @@ button.outline-link:hover {
.navigation-tabs[hidden], .navigation-tabs[hidden],
.page-selection-tools[hidden], .page-selection-tools[hidden],
.form-row[hidden], .form-row[hidden],
.form-pair[hidden],
.form-actions > [hidden], .form-actions > [hidden],
.annotation-detail[hidden], .annotation-detail[hidden],
.tool-group[hidden], .tool-group[hidden],
@@ -1644,10 +1645,6 @@ button.outline-link:hover {
content: ""; content: "";
} }
.edit-object.selected {
background: rgba(15, 123, 104, 0.04);
}
.edit-object.erasing { .edit-object.erasing {
background: var(--accent-soft); background: var(--accent-soft);
outline-style: dashed; outline-style: dashed;
@@ -1849,6 +1846,19 @@ button.outline-link:hover {
--note-rotation: calc(-1 * var(--surface-rotation, 0deg)); --note-rotation: calc(-1 * var(--surface-rotation, 0deg));
} }
.edit-note-icon {
position: absolute;
inset: 0;
display: grid;
place-items: center;
border: 1px solid var(--line-strong);
background: var(--panel);
color: var(--accent-strong);
font-size: 16px;
line-height: 1;
pointer-events: none;
}
.annotation-detail { .annotation-detail {
display: grid; display: grid;
gap: 8px; gap: 8px;
+9 -2
View File
@@ -303,14 +303,21 @@ export class CanvasEditor {
node.setAttribute("aria-label", { ImageObject: "图片对象", TextObject: "文字对象", PathObject: "图形对象", CompositeObject: "复合对象", CompositeGraphicUnit: "复合对象", Annotation: "注解对象" }[object.type]); node.setAttribute("aria-label", { ImageObject: "图片对象", TextObject: "文字对象", PathObject: "图形对象", CompositeObject: "复合对象", CompositeGraphicUnit: "复合对象", Annotation: "注解对象" }[object.type]);
const item = { ...object, index, page: { width: page.width, height: page.height }, node, surface }; const item = { ...object, index, page: { width: page.width, height: page.height }, node, surface };
item.artwork = artwork.get(object.id)?.node; item.artwork = artwork.get(object.id)?.node;
if (object.type === "PathObject" && (object.shape || object.outline) || (object.scoped || object.type === "CompositeObject" || object.type === "CompositeGraphicUnit" || object.type === "Annotation") && object.contours?.length) { if (object.note) {
const icon = document.createElement("span");
icon.className = "edit-note-icon";
icon.setAttribute("aria-hidden", "true");
icon.textContent = "\u24d8";
node.append(icon);
}
if (object.type === "PathObject" && (object.shape || object.outline || object.contours?.length)) {
node.classList.add("edit-contour"); node.classList.add("edit-contour");
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.classList.add("edit-outline"); svg.classList.add("edit-outline");
svg.setAttribute("aria-hidden", "true"); svg.setAttribute("aria-hidden", "true");
svg.setAttribute("preserveAspectRatio", "none"); svg.setAttribute("preserveAspectRatio", "none");
let contour; let contour;
if (object.type === "PathObject" && (object.shape || object.oriented || !object.contours?.length)) { if (object.shape || object.oriented || !object.contours?.length) {
const shape = object.shape || object.oriented?.kind; const shape = object.shape || object.oriented?.kind;
contour = document.createElementNS("http://www.w3.org/2000/svg", shape === "line" ? "line" : shape === "ellipse" ? "ellipse" : shape === "rectangle" ? "rect" : "path"); contour = document.createElementNS("http://www.w3.org/2000/svg", shape === "line" ? "line" : shape === "ellipse" ? "ellipse" : shape === "rectangle" ? "rect" : "path");
if (!shape) contour.setAttribute("d", object.outline); if (!shape) contour.setAttribute("d", object.outline);
+9 -10
View File
@@ -898,9 +898,15 @@ func editorObjects(index int, text *ofdgo.PageText) ([]any, error) {
mixed = true mixed = true
} }
} }
objects = append(objects, map[string]any{"id": "annotation:" + annotation.ID, "type": "Annotation", "annotationType": annotation.Type, item := map[string]any{"id": "annotation:" + annotation.ID, "type": "Annotation", "annotationType": annotation.Type,
"x": box.X, "y": box.Y, "width": box.W, "height": box.H, "contours": paths, "remark": annotation.Remark, "creator": annotation.Creator, "x": box.X, "y": box.Y, "width": box.W, "height": box.H, "remark": annotation.Remark, "creator": annotation.Creator,
"alpha": alpha, "alphaMixed": mixed, "capabilities": capabilities}) "alpha": alpha, "alphaMixed": mixed, "capabilities": capabilities}
if len(annotation.Appearance.Objects) == 0 && strings.TrimSpace(annotation.Remark) != "" {
item["note"] = true
} else {
item["contours"] = paths
}
objects = append(objects, item)
} }
return objects, nil return objects, nil
} }
@@ -1066,13 +1072,6 @@ func writeAnnotation(args []js.Value) (any, error) {
switch options.Kind { switch options.Kind {
case "note": case "note":
annotation.Type, annotation.Remark = "Path", options.Text annotation.Type, annotation.Remark = "Path", options.Text
shape, shapeErr := ofdgo.NewShape(ofdgo.ShapeRectangle, ofdgo.Box{W: box.W, H: box.H})
if shapeErr != nil {
return shapeErr
}
shape.LineWidth = 0.3
shape.StrokeColor = &ofdgo.StrokeColor{Value: "0 128 112"}
annotation.Appearance.Objects = []ofdgo.GraphicObject{{Type: "PathObject", PathObject: shape}}
case "watermark", "stamp": case "watermark", "stamp":
annotation.Type = "Watermark" annotation.Type = "Watermark"
if options.Kind == "stamp" { if options.Kind == "stamp" {