mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 01:27:26 +08:00
1 parent
7bf9f7b3b7
commit
656adbecfe
3 files changed
+62
-60
No files matched your search
+17
-18
@@ -91,11 +91,18 @@
|
|||||||
</select>
|
</select>
|
||||||
<button id="objectStyleButton" class="editor-group-action" type="button" title="对象样式" aria-label="对象样式" aria-haspopup="dialog" aria-controls="objectStylePanel" disabled>对象</button>
|
<button id="objectStyleButton" class="editor-group-action" type="button" title="对象样式" aria-label="对象样式" aria-haspopup="dialog" aria-controls="objectStylePanel" disabled>对象</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-group editor-erase">
|
<div class="editor-group editor-transform">
|
||||||
<button id="eraseObjectButton" class="button" type="button" title="整对象擦除" aria-label="整对象擦除" aria-pressed="false">对象</button>
|
<select id="objectRotate" class="order-select" aria-label="对象旋转" disabled>
|
||||||
<button id="eraseRegionButton" class="button" type="button" title="矩形擦除(视觉裁剪)" aria-label="矩形擦除" aria-pressed="false">矩形</button>
|
<option value="" hidden>旋转</option>
|
||||||
<button id="erasePathButton" class="button" type="button" title="套索擦除(视觉裁剪)" aria-label="套索擦除" aria-pressed="false">套索</button>
|
<option value="90">右转90°</option>
|
||||||
<span>擦除</span>
|
<option value="-90">左转90°</option>
|
||||||
|
</select>
|
||||||
|
<select id="objectFlip" class="order-select" aria-label="对象翻转" disabled>
|
||||||
|
<option value="" hidden>翻转</option>
|
||||||
|
<option value="horizontal">水平</option>
|
||||||
|
<option value="vertical">垂直</option>
|
||||||
|
</select>
|
||||||
|
<button id="objectBoundsButton" class="editor-group-action" type="button" title="位置尺寸" aria-label="位置尺寸" aria-haspopup="dialog" aria-controls="objectBoundsPanel" disabled>变换</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-group">
|
<div class="editor-group">
|
||||||
<button id="insertTextButton" class="button" type="button" aria-label="添加文字" aria-pressed="false">文字</button>
|
<button id="insertTextButton" class="button" type="button" aria-label="添加文字" aria-pressed="false">文字</button>
|
||||||
@@ -109,7 +116,7 @@
|
|||||||
<div class="editor-group">
|
<div class="editor-group">
|
||||||
<div class="text-font"><div class="font-picker"><input id="textFont" type="text" role="combobox" aria-label="字体" title="字体" aria-autocomplete="list" aria-controls="textFontList" aria-expanded="false" autocomplete="off" spellcheck="false" disabled><button id="textFontToggle" type="button" title="选择字体" aria-label="选择字体" tabindex="-1" disabled></button></div><button id="textFontAdd" class="icon-button" type="button" title="添加字体" aria-label="添加字体">+</button></div>
|
<div class="text-font"><div class="font-picker"><input id="textFont" type="text" role="combobox" aria-label="字体" title="字体" aria-autocomplete="list" aria-controls="textFontList" aria-expanded="false" autocomplete="off" spellcheck="false" disabled><button id="textFontToggle" type="button" title="选择字体" aria-label="选择字体" tabindex="-1" disabled></button></div><button id="textFontAdd" class="icon-button" type="button" title="添加字体" aria-label="添加字体">+</button></div>
|
||||||
<div id="textFontList" class="font-listbox" role="listbox" aria-label="字体列表" popover="manual"></div>
|
<div id="textFontList" class="font-listbox" role="listbox" aria-label="字体列表" popover="manual"></div>
|
||||||
<div class="editor-number"><input id="textSize" type="number" min="1" step="any" required aria-label="字号" disabled><span>pt</span></div>
|
<label class="editor-field"><span>字号</span><span class="editor-number"><input id="textSize" type="number" min="1" step="any" required aria-label="字号" disabled><span>pt</span></span></label>
|
||||||
<input id="textColor" class="color-input" type="color" value="#000000" aria-label="文字颜色" title="文字颜色" disabled>
|
<input id="textColor" class="color-input" type="color" value="#000000" aria-label="文字颜色" title="文字颜色" disabled>
|
||||||
<span>文字</span>
|
<span>文字</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -142,18 +149,10 @@
|
|||||||
<button id="resetCropButton" class="button" type="button" aria-label="还原图片" disabled>还原</button>
|
<button id="resetCropButton" class="button" type="button" aria-label="还原图片" disabled>还原</button>
|
||||||
<span>图片</span>
|
<span>图片</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-group editor-transform">
|
<div class="editor-group editor-erase">
|
||||||
<select id="objectRotate" class="order-select" aria-label="对象旋转" disabled>
|
<button id="eraseButton" class="button" type="button" title="擦除" aria-label="擦除" aria-pressed="false">擦除</button>
|
||||||
<option value="" hidden>旋转</option>
|
<select id="eraseMode" aria-label="擦除方式" title="擦除方式,矩形和套索为视觉裁剪"><option value="erase-object">对象</option><option value="erase-region">矩形</option><option value="erase-path">套索</option></select>
|
||||||
<option value="90">右转90°</option>
|
<span>擦除</span>
|
||||||
<option value="-90">左转90°</option>
|
|
||||||
</select>
|
|
||||||
<select id="objectFlip" class="order-select" aria-label="对象翻转" disabled>
|
|
||||||
<option value="" hidden>翻转</option>
|
|
||||||
<option value="horizontal">水平</option>
|
|
||||||
<option value="vertical">垂直</option>
|
|
||||||
</select>
|
|
||||||
<button id="objectBoundsButton" class="editor-group-action" type="button" title="位置尺寸" aria-label="位置尺寸" aria-haspopup="dialog" aria-controls="objectBoundsPanel" disabled>变换</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-group">
|
<div class="editor-group">
|
||||||
<select id="addPageButton" aria-label="新增页面" title="新增页面"><option value="" hidden>新增</option><option value="blank">空白</option><option value="import">插页</option></select>
|
<select id="addPageButton" aria-label="新增页面" title="新增页面"><option value="" hidden>新增</option><option value="blank">空白</option><option value="import">插页</option></select>
|
||||||
|
|||||||
+26
-23
@@ -89,7 +89,6 @@ a:focus-visible {
|
|||||||
display: flex;
|
display: flex;
|
||||||
max-height: 40dvh;
|
max-height: 40dvh;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
gap: 8px;
|
|
||||||
padding: 8px 10px 6px;
|
padding: 8px 10px 6px;
|
||||||
border-bottom: 1px solid var(--line);
|
border-bottom: 1px solid var(--line);
|
||||||
background: var(--panel);
|
background: var(--panel);
|
||||||
@@ -102,35 +101,32 @@ a:focus-visible {
|
|||||||
|
|
||||||
.editor-group {
|
.editor-group {
|
||||||
display: grid;
|
display: grid;
|
||||||
flex: 0 0 auto;
|
flex: 1 0 auto;
|
||||||
|
justify-content: center;
|
||||||
grid-template-columns: repeat(3, max-content);
|
grid-template-columns: repeat(3, max-content);
|
||||||
grid-template-rows: repeat(2, 28px) 16px;
|
grid-template-rows: repeat(2, 28px) 16px;
|
||||||
column-gap: 4px;
|
column-gap: 4px;
|
||||||
row-gap: 4px;
|
row-gap: 4px;
|
||||||
padding-right: 8px;
|
padding: 0 8px;
|
||||||
border-right: 1px solid var(--line);
|
border-right: 1px solid var(--line);
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-file,
|
.editor-file,
|
||||||
.editor-erase,
|
|
||||||
.editor-image {
|
.editor-image {
|
||||||
grid-template-columns: repeat(2, max-content);
|
grid-template-columns: repeat(2, max-content);
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-transform {
|
.editor-transform,
|
||||||
|
.editor-erase {
|
||||||
grid-template-columns: max-content;
|
grid-template-columns: max-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
#eraseObjectButton {
|
|
||||||
grid-row: span 2;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-image > select {
|
.editor-image > select {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-paragraph > .editor-field {
|
.editor-paragraph > .editor-field,
|
||||||
|
.editor-group:has(#textFont) > .editor-field {
|
||||||
grid-column: auto;
|
grid-column: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +138,8 @@ a:focus-visible {
|
|||||||
display: grid;
|
display: grid;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
grid-template-columns: 2em minmax(0, 1fr);
|
grid-template-columns: 2em 86px;
|
||||||
|
justify-content: space-between;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@@ -189,17 +186,15 @@ a:focus-visible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.editor-group:has(#textFont) {
|
.editor-group:has(#textFont) {
|
||||||
grid-template-columns: 102px 54px;
|
grid-template-columns: 160px 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-paragraph {
|
.editor-paragraph {
|
||||||
width: 194px;
|
grid-template-columns: 54px max-content;
|
||||||
grid-template-columns: 54px minmax(0, 1fr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-group:has(#shapeFill) {
|
.editor-group:has(#shapeFill) {
|
||||||
width: 180px;
|
grid-template-columns: repeat(2, 84px);
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-file #saveButton {
|
.editor-file #saveButton {
|
||||||
@@ -211,11 +206,6 @@ a:focus-visible {
|
|||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#textFont {
|
|
||||||
width: 100%;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font-picker {
|
.font-picker {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
@@ -227,6 +217,7 @@ a:focus-visible {
|
|||||||
.font-picker #textFont {
|
.font-picker #textFont {
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
width: 0;
|
width: 0;
|
||||||
|
min-width: 0;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
padding: 0 6px;
|
padding: 0 6px;
|
||||||
border: 0;
|
border: 0;
|
||||||
@@ -333,7 +324,15 @@ a:focus-visible {
|
|||||||
accent-color: var(--accent);
|
accent-color: var(--accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.editor-group:first-child {
|
||||||
|
flex-grow: 0.5;
|
||||||
|
justify-content: start;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.editor-group:last-child {
|
.editor-group:last-child {
|
||||||
|
flex-grow: 0.5;
|
||||||
|
justify-content: end;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
border-right: 0;
|
border-right: 0;
|
||||||
}
|
}
|
||||||
@@ -766,12 +765,16 @@ button:not(:disabled):hover {
|
|||||||
|
|
||||||
.text-font {
|
.text-font {
|
||||||
display: grid;
|
display: grid;
|
||||||
width: 160px;
|
width: 196px;
|
||||||
grid-template-columns: minmax(0, 1fr) auto;
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-font .icon-button {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
.form-row input[aria-invalid="true"] {
|
.form-row input[aria-invalid="true"] {
|
||||||
border-color: #b14343;
|
border-color: #b14343;
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-19
@@ -152,9 +152,8 @@ const el = {
|
|||||||
arrowTool: document.querySelector("#arrowTool"),
|
arrowTool: document.querySelector("#arrowTool"),
|
||||||
drawRectangleButton: document.querySelector("#drawRectangleButton"),
|
drawRectangleButton: document.querySelector("#drawRectangleButton"),
|
||||||
drawEllipseButton: document.querySelector("#drawEllipseButton"),
|
drawEllipseButton: document.querySelector("#drawEllipseButton"),
|
||||||
eraseObjectButton: document.querySelector("#eraseObjectButton"),
|
eraseButton: document.querySelector("#eraseButton"),
|
||||||
eraseRegionButton: document.querySelector("#eraseRegionButton"),
|
eraseMode: document.querySelector("#eraseMode"),
|
||||||
erasePathButton: document.querySelector("#erasePathButton"),
|
|
||||||
shapeFill: document.querySelector("#shapeFill"),
|
shapeFill: document.querySelector("#shapeFill"),
|
||||||
shapeFillColor: document.querySelector("#shapeFillColor"),
|
shapeFillColor: document.querySelector("#shapeFillColor"),
|
||||||
shapeStroke: document.querySelector("#shapeStroke"),
|
shapeStroke: document.querySelector("#shapeStroke"),
|
||||||
@@ -547,19 +546,13 @@ el.resetCropButton.addEventListener("click", () => {
|
|||||||
});
|
});
|
||||||
editorClick(el.undoButton, () => changeDocument("ofdgoUndo"));
|
editorClick(el.undoButton, () => changeDocument("ofdgoUndo"));
|
||||||
editorClick(el.redoButton, () => changeDocument("ofdgoRedo"));
|
editorClick(el.redoButton, () => changeDocument("ofdgoRedo"));
|
||||||
for (const [button, tool] of [[el.drawLineButton, "line"], [el.drawRectangleButton, "rectangle"], [el.drawEllipseButton, "ellipse"],
|
for (const [button, tool] of [[el.drawLineButton, "line"], [el.drawRectangleButton, "rectangle"], [el.drawEllipseButton, "ellipse"]]) {
|
||||||
[el.eraseObjectButton, "erase-object"], [el.eraseRegionButton, "erase-region"], [el.erasePathButton, "erase-path"]]) {
|
editorClick(button, () => toggleDrawingTool(tool));
|
||||||
editorClick(button, () => {
|
|
||||||
if (!state.editing || document.body.hasAttribute("aria-busy")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const next = canvasEditor.tool === tool ? "" : tool;
|
|
||||||
state.selectObjects = true;
|
|
||||||
setPan(false);
|
|
||||||
canvasEditor.setTool(next);
|
|
||||||
el.viewerPanel.focus({ preventScroll: true });
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
editorClick(el.eraseButton, () => toggleDrawingTool(el.eraseMode.value));
|
||||||
|
el.eraseMode.addEventListener("change", () => {
|
||||||
|
if (canvasEditor.tool.startsWith("erase-")) canvasEditor.setTool(el.eraseMode.value);
|
||||||
|
});
|
||||||
for (const input of [el.shapeFill, el.shapeFillColor, el.shapeStroke, el.shapeStrokeColor, el.shapeWidth]) {
|
for (const input of [el.shapeFill, el.shapeFillColor, el.shapeStroke, el.shapeStrokeColor, el.shapeWidth]) {
|
||||||
input.addEventListener("change", changeShapeStyle);
|
input.addEventListener("change", changeShapeStyle);
|
||||||
}
|
}
|
||||||
@@ -1647,6 +1640,15 @@ async function changeShapeStyle() {
|
|||||||
updateDrawingControls();
|
updateDrawingControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleDrawingTool(tool) {
|
||||||
|
if (!state.editing || document.body.hasAttribute("aria-busy")) return;
|
||||||
|
const next = canvasEditor.tool === tool ? "" : tool;
|
||||||
|
state.selectObjects = true;
|
||||||
|
setPan(false);
|
||||||
|
canvasEditor.setTool(next);
|
||||||
|
el.viewerPanel.focus({ preventScroll: true });
|
||||||
|
}
|
||||||
|
|
||||||
function updateDrawingControls() {
|
function updateDrawingControls() {
|
||||||
const tool = canvasEditor.tool;
|
const tool = canvasEditor.tool;
|
||||||
el.insertTextButton.setAttribute("aria-pressed", String(tool === "text"));
|
el.insertTextButton.setAttribute("aria-pressed", String(tool === "text"));
|
||||||
@@ -1661,10 +1663,8 @@ function updateDrawingControls() {
|
|||||||
button.disabled = disabled || !pageCan("insert");
|
button.disabled = disabled || !pageCan("insert");
|
||||||
button.setAttribute("aria-pressed", String(tool === name));
|
button.setAttribute("aria-pressed", String(tool === name));
|
||||||
}
|
}
|
||||||
for (const [button, name] of [[el.eraseObjectButton, "erase-object"], [el.eraseRegionButton, "erase-region"], [el.erasePathButton, "erase-path"]]) {
|
el.eraseButton.disabled = el.eraseMode.disabled = disabled;
|
||||||
button.disabled = disabled;
|
el.eraseButton.setAttribute("aria-pressed", String(tool.startsWith("erase-")));
|
||||||
button.setAttribute("aria-pressed", String(tool === name));
|
|
||||||
}
|
|
||||||
el.selectObjectButton.setAttribute("aria-pressed", String(canvasEditor.enabled && !tool));
|
el.selectObjectButton.setAttribute("aria-pressed", String(canvasEditor.enabled && !tool));
|
||||||
const styleDisabled = disabled || (canvasEditor.selected?.type === "PathObject"
|
const styleDisabled = disabled || (canvasEditor.selected?.type === "PathObject"
|
||||||
? !canEditObject(canvasEditor.selected, "update") : !pageCan("insert"));
|
? !canEditObject(canvasEditor.selected, "update") : !pageCan("insert"));
|
||||||
|
|||||||
Reference in new issue
Block a user