feat(前端界面): 优化工具栏数值输入与对齐,修复页面栏自动跟随时的上下留白
build.yaml / build (push) Successful in 38s

This commit is contained in:
xiaoqidun committed 2026-09-17 01:59:23 +08:00
1 parent 656adbecfe
commit 35f0722d36
2 files changed
+30 -28

No files matched your search

+5 -4
View File
@@ -138,8 +138,7 @@ 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 86px; grid-template-columns: 2em minmax(0, 1fr);
justify-content: space-between;
gap: 6px; gap: 6px;
white-space: nowrap; white-space: nowrap;
} }
@@ -190,7 +189,7 @@ a:focus-visible {
} }
.editor-paragraph { .editor-paragraph {
grid-template-columns: 54px max-content; grid-template-columns: 54px 120px;
} }
.editor-group:has(#shapeFill) { .editor-group:has(#shapeFill) {
@@ -871,6 +870,7 @@ body[data-hide-meta] .meta-panel {
.outline-list summary, .outline-list summary,
.outline-link { .outline-link {
scroll-margin-top: 51px; scroll-margin-top: 51px;
scroll-margin-bottom: 12px;
} }
.meta-panel { .meta-panel {
@@ -954,6 +954,7 @@ body[data-hide-meta] .meta-panel {
padding-top: 12px; padding-top: 12px;
border-bottom: 1px solid var(--line); border-bottom: 1px solid var(--line);
background: var(--panel); background: var(--panel);
box-shadow: 0 10px var(--panel);
} }
.navigation-tabs button { .navigation-tabs button {
@@ -1133,7 +1134,7 @@ button.outline-link:hover {
.page-list { .page-list {
display: grid; display: grid;
gap: 8px; gap: 12px;
} }
.page-list-item { .page-list-item {
+25 -24
View File
@@ -426,8 +426,6 @@ editorClick(el.editObjectButton, () => {
} }
}); });
el.textSize.addEventListener("change", () => changeTextStyle(false)); el.textSize.addEventListener("change", () => changeTextStyle(false));
el.textSize.addEventListener("focus", () => updateObjectControls(canvasEditor.selected, true));
el.textSize.addEventListener("blur", () => updateObjectControls(canvasEditor.selected, true));
el.textColor.addEventListener("change", () => changeTextStyle(true)); el.textColor.addEventListener("change", () => changeTextStyle(true));
editorClick(el.textWrap, () => changeParagraph(!currentTextStyle().wrap)); editorClick(el.textWrap, () => changeParagraph(!currentTextStyle().wrap));
el.textAlign.addEventListener("change", () => changeParagraph()); el.textAlign.addEventListener("change", () => changeParagraph());
@@ -1540,8 +1538,13 @@ async function insertObject(event) {
} }
} }
function textPoints(size) { function displayPoints(length) {
return Number((size * 72 / 25.4).toFixed(2)); return Number((length * 72 / 25.4).toPrecision(6));
}
function inputMillimeters(input, original) {
const points = Number(input.value);
return points === displayPoints(original) ? original : points * 25.4 / 72;
} }
async function changeParagraph(wrap = currentTextStyle().wrap) { async function changeParagraph(wrap = currentTextStyle().wrap) {
@@ -1551,14 +1554,12 @@ async function changeParagraph(wrap = currentTextStyle().wrap) {
updateObjectControls(item, true); updateObjectControls(item, true);
return; return;
} }
const points = Number(el.textLineHeight.value); const height = inputMillimeters(el.textLineHeight, item.paragraphHeight || 0);
const height = points === textPoints(item.paragraphHeight || 0) ? item.paragraphHeight || 0 : points * 25.4 / 72;
if (!el.textSpacing.checkValidity()) { if (!el.textSpacing.checkValidity()) {
updateObjectControls(canvasEditor.selected, true); updateObjectControls(canvasEditor.selected, true);
return; return;
} }
const spacingPoints = Number(el.textSpacing.value); const spacing = inputMillimeters(el.textSpacing, item.letterSpacing || 0);
const spacing = spacingPoints === textPoints(item.letterSpacing || 0) ? item.letterSpacing || 0 : spacingPoints * 25.4 / 72;
if (item === state.textDefaults) { if (item === state.textDefaults) {
Object.assign(item, { wrap: Boolean(wrap), align: el.textAlign.value, paragraphHeight: height, letterSpacing: spacing }); Object.assign(item, { wrap: Boolean(wrap), align: el.textAlign.value, paragraphHeight: height, letterSpacing: spacing });
updateObjectControls(canvasEditor.selected, true); updateObjectControls(canvasEditor.selected, true);
@@ -1582,7 +1583,7 @@ async function changeTextStyle(color) {
updateObjectControls(item, true); updateObjectControls(item, true);
return; return;
} }
const size = color || Number(el.textSize.value) === Number(el.textSize.defaultValue) ? item.size : Number(el.textSize.value) * 25.4 / 72; const size = color ? item.size : inputMillimeters(el.textSize, item.size);
const fill = color && el.textColor.value !== item.color ? el.textColor.value : null; const fill = color && el.textColor.value !== item.color ? el.textColor.value : null;
if (item.items) { if (item.items) {
if (color ? !canEditObject(item, "update") : !canEditObject(item, "layoutKnown") || !canEditObject(item, "reflow")) return; if (color ? !canEditObject(item, "update") : !canEditObject(item, "layoutKnown") || !canEditObject(item, "reflow")) return;
@@ -1615,17 +1616,13 @@ function shapeStyle() {
lineWidth: Number(el.shapeWidth.value) * 25.4 / 72 }; lineWidth: Number(el.shapeWidth.value) * 25.4 / 72 };
} }
function strokePoints(width) {
return Number((width * 72 / 25.4).toPrecision(6));
}
async function changeShapeStyle() { async function changeShapeStyle() {
const item = canvasEditor.selected; const item = canvasEditor.selected;
if (!state.editing || document.body.hasAttribute("aria-busy")) { if (!state.editing || document.body.hasAttribute("aria-busy")) {
return; return;
} }
if (!el.shapeWidth.checkValidity() || Number(el.shapeWidth.value) <= 0) { if (!el.shapeWidth.checkValidity() || Number(el.shapeWidth.value) <= 0) {
el.shapeWidth.value = String(item?.type === "PathObject" ? strokePoints(item.lineWidth) : 1); el.shapeWidth.value = String(item?.type === "PathObject" ? displayPoints(item.lineWidth) : 1);
return; return;
} }
if (!el.shapeFill.checked && !el.shapeStroke.checked) { if (!el.shapeFill.checked && !el.shapeStroke.checked) {
@@ -1634,8 +1631,10 @@ async function changeShapeStyle() {
const style = shapeStyle(); const style = shapeStyle();
if (item?.type === "PathObject") { if (item?.type === "PathObject") {
await changeDocument("ofdgoUpdatePathStyle", item, style.fill, style.fillColor, style.stroke, style.strokeColor, await changeDocument("ofdgoUpdatePathStyle", item, style.fill, style.fillColor, style.stroke, style.strokeColor,
Number(el.shapeWidth.value) === strokePoints(item.lineWidth) ? item.lineWidth : style.lineWidth); inputMillimeters(el.shapeWidth, item.lineWidth));
updateObjectControls(canvasEditor.selected, true); updateObjectControls(canvasEditor.selected, true);
} else {
el.shapeWidth.value = String(Number(el.shapeWidth.value));
} }
updateDrawingControls(); updateDrawingControls();
} }
@@ -3682,11 +3681,14 @@ function updatePageListCurrent(force = false) {
if (state.showPages && !el.pageList.hidden) { if (state.showPages && !el.pageList.hidden) {
const panel = el.pageListPanel.getBoundingClientRect(); const panel = el.pageListPanel.getBoundingClientRect();
const item = next.getBoundingClientRect(); const item = next.getBoundingClientRect();
const top = panel.top + Number.parseFloat(getComputedStyle(next).scrollMarginTop); const style = getComputedStyle(el.pageListPanel);
const top = Math.max(panel.top + Number.parseFloat(style.paddingTop),
el.navigationTabs.getBoundingClientRect().bottom + Number.parseFloat(getComputedStyle(el.navigationTabs).marginBottom));
const bottom = panel.bottom - Number.parseFloat(style.paddingBottom);
if (item.top < top) { if (item.top < top) {
el.pageListPanel.scrollTop += item.top - top; el.pageListPanel.scrollTop += item.top - top;
} else if (item.bottom > panel.bottom) { } else if (item.bottom > bottom) {
el.pageListPanel.scrollTop += Math.min(item.top - top, item.bottom - panel.bottom); el.pageListPanel.scrollTop += Math.min(item.top - top, item.bottom - bottom);
} }
} }
} }
@@ -5123,18 +5125,17 @@ function updateObjectControls(item, reset = false) {
el.textSpacing.placeholder = layoutKnown ? "0" : "原文"; el.textSpacing.placeholder = layoutKnown ? "0" : "原文";
el.textWrap.setAttribute("aria-pressed", String(Boolean(text.wrap))); el.textWrap.setAttribute("aria-pressed", String(Boolean(text.wrap)));
if (reset || document.activeElement !== el.textLineHeight) { if (reset || document.activeElement !== el.textLineHeight) {
el.textLineHeight.value = text.paragraphHeight ? String(textPoints(text.paragraphHeight)) : ""; el.textLineHeight.value = text.paragraphHeight ? String(displayPoints(text.paragraphHeight)) : "";
} }
if (reset || document.activeElement !== el.textSpacing) { if (reset || document.activeElement !== el.textSpacing) {
el.textSpacing.value = text.letterSpacing ? String(textPoints(text.letterSpacing)) : ""; el.textSpacing.value = text.letterSpacing ? String(displayPoints(text.letterSpacing)) : "";
} }
updateTextFonts(item); updateTextFonts(item);
if (reset || el.textSize.disabled || document.activeElement !== el.textSize) { if (reset || el.textSize.disabled || document.activeElement !== el.textSize) {
el.textSize.value = text.size === undefined ? "" : document.activeElement === el.textSize ? textPoints(text.size) : Math.round(textPoints(text.size)); el.textSize.value = text.size === undefined ? "" : displayPoints(text.size);
el.textSize.defaultValue = el.textSize.value;
} }
el.textSize.placeholder = text.size === undefined ? "混合" : ""; el.textSize.placeholder = text.size === undefined ? "混合" : "";
el.textSize.title = text.size === undefined ? "字号:混合" : `字号 ${textPoints(text.size)} pt`; el.textSize.title = text.size === undefined ? "字号:混合" : `字号 ${displayPoints(text.size)} pt`;
el.textColor.classList.toggle("mixed-color", Boolean(selection?.items && !text.color)); el.textColor.classList.toggle("mixed-color", Boolean(selection?.items && !text.color));
el.textColor.title = selection?.items && !text.color ? "文字颜色:混合" : "文字颜色"; el.textColor.title = selection?.items && !text.color ? "文字颜色:混合" : "文字颜色";
if (reset || el.textColor.disabled || document.activeElement !== el.textColor) { if (reset || el.textColor.disabled || document.activeElement !== el.textColor) {
@@ -5146,7 +5147,7 @@ function updateObjectControls(item, reset = false) {
el.shapeFillColor.value = item.fillColor; el.shapeFillColor.value = item.fillColor;
el.shapeStrokeColor.value = item.strokeColor; el.shapeStrokeColor.value = item.strokeColor;
if (reset || document.activeElement !== el.shapeWidth) { if (reset || document.activeElement !== el.shapeWidth) {
el.shapeWidth.value = strokePoints(item.lineWidth); el.shapeWidth.value = displayPoints(item.lineWidth);
} }
} }
updateDrawingControls(); updateDrawingControls();