mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 01:27:26 +08:00
This commit is contained in:
1 parent
9bb6c9141a
commit
9c3a04b7eb
3 files changed
+76
-2
No files matched your search
+27
-2
@@ -110,6 +110,7 @@ function createDocumentState() {
|
||||
styleOriginal: null,
|
||||
objectClipboardToken: null,
|
||||
styleClipboard: null,
|
||||
objectDistribution: null,
|
||||
outlineExpanded: new Map(),
|
||||
textFonts: [],
|
||||
textFontID: null,
|
||||
@@ -1260,7 +1261,7 @@ el.objectAlign.addEventListener("change", () => {
|
||||
el.objectDistribute.addEventListener("change", () => {
|
||||
const axis = el.objectDistribute.value;
|
||||
el.objectDistribute.value = "";
|
||||
if (axis && canvasEditor.items().length >= 3) {
|
||||
if (axis && !el.objectDistribute.disabled && state.objectDistribution?.axes?.includes(axis)) {
|
||||
return changeDocument("ofdgoDistributeObjects", canvasEditor.selected, axis);
|
||||
}
|
||||
});
|
||||
@@ -12746,6 +12747,30 @@ function updateEditorTools() {
|
||||
updateObjectControls(canvasEditor.selected);
|
||||
}
|
||||
|
||||
function updateObjectDistribution(item, disabled) {
|
||||
const tab = documentTab(), state = tab.state;
|
||||
const ids = item?.items?.slice().sort((a, b) => a.order - b.order).map(member => member.id) || [];
|
||||
if (disabled || ids.length < 3) state.objectDistribution = null;
|
||||
else {
|
||||
const { openSeq, wasmSeq } = state, revision = state.editorInfo?.revision;
|
||||
const key = JSON.stringify([openSeq, wasmSeq, revision, item.index, ids]);
|
||||
if (state.objectDistribution?.key !== key) {
|
||||
const request = state.objectDistribution = { key, axes: [] };
|
||||
const current = () => !tab.closed && state.objectDistribution === request && state.openSeq === openSeq && state.wasmSeq === wasmSeq && state.editorInfo?.revision === revision;
|
||||
callTabWASM(tab, "ofdgoDistributionAxes", item.index, ids).then(axes => {
|
||||
if (!current()) return;
|
||||
request.axes = axes;
|
||||
if (isForegroundDocument(tab)) updateObjectControls(canvasEditor.selected);
|
||||
}).catch(error => {
|
||||
if (current() && isForegroundDocument(tab)) showError(error, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
const axes = state.objectDistribution?.axes || [];
|
||||
el.objectDistribute.disabled = disabled || !axes.length;
|
||||
for (const option of el.objectDistribute.options) if (option.value) option.disabled = !axes.includes(option.value);
|
||||
}
|
||||
|
||||
function updateObjectControls(item, reset = false) {
|
||||
const members = item?.items || (item ? [item] : []);
|
||||
const disabled = !item || Boolean(item.draft) || !state.ready || state.exporting;
|
||||
@@ -12763,7 +12788,7 @@ function updateObjectControls(item, reset = false) {
|
||||
el.cropImageButton.setAttribute("data-pressed", String(cropping));
|
||||
el.resetCropButton.textContent = cropping ? "取消" : "还原";
|
||||
el.resetCropButton.disabled = canEditObject(item, "resetCrop") ? disabled : el.cropImageButton.disabled || !cropping && (item.scoped ? !item.cropped : !item.imageBounds || ["x", "y", "width", "height"].every(key => Math.abs(item[key] - item.imageBounds[key]) < 1e-9));
|
||||
el.objectDistribute.disabled = el.objectAlign.disabled || !item.items || item.items.length < 3;
|
||||
updateObjectDistribution(item, el.objectAlign.disabled);
|
||||
el.editObjectButton.disabled = disabled || (item.items ? !item.items.every(member => member.type === "TextObject" && !member.richText)
|
||||
: !canEditObject(item, "children") && (item.type === "PathObject"
|
||||
|| !(item.type === "TextObject" && canEditObject(item, "rewriteText")) && !canEditObject(item, item.type === "TextObject" ? "textContent" : item.type === "ImageObject" ? "replaceImage" : "update")));
|
||||
|
||||
@@ -5703,6 +5703,20 @@ func (e *businessEngine) orderObjects(args []platformValue) (any, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// distributionAxes 获取画布选区可用的等间距分布方向
|
||||
// 入参: args 页面索引和画布对象标识数组
|
||||
// 返回: any 可用方向, error 路径或度量错误
|
||||
func (e *businessEngine) distributionAxes(args []platformValue) (any, error) {
|
||||
if e.currentEditor == nil {
|
||||
return nil, fmt.Errorf("no document is being edited")
|
||||
}
|
||||
paths, err := e.editorTargetPaths(e.stringsFromJS(args[1]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e.currentEditor.DistributionAxes(args[0].Int(), paths)
|
||||
}
|
||||
|
||||
// distributeObjects 按指定轴等距分布选区
|
||||
// 入参: args 页面索引、对象标识数组和分布轴
|
||||
// 返回: any 文档信息, error 错误信息
|
||||
@@ -8159,6 +8173,7 @@ func (e *businessEngine) businessCommands() map[string]func([]platformValue) (an
|
||||
"ofdgoImportObjects": e.importObjects,
|
||||
"ofdgoOrderObjects": e.orderObjects,
|
||||
"ofdgoDistributeObjects": e.distributeObjects,
|
||||
"ofdgoDistributionAxes": e.distributionAxes,
|
||||
"ofdgoRotateObjects": e.rotateObjects,
|
||||
"ofdgoFlipObjects": e.flipObjects,
|
||||
"ofdgoCropImage": e.cropImage,
|
||||
|
||||
@@ -808,6 +808,40 @@ func (e *Editor) ResizeTargets(page int, paths []ObjectPath, box Box) error {
|
||||
return e.TransformTargets(page, paths, Matrix{a: sx, d: sy, e: box.X - bounds.X*sx, f: box.Y - bounds.Y*sy})
|
||||
}
|
||||
|
||||
// DistributionAxes 获取选区可保持位置顺序的等间距分布方向,不修改文档或历史
|
||||
// 入参: page 页面索引, paths 按绘制顺序排列的完整路径
|
||||
// 返回: []string 可用的horizontal和vertical方向, error 路径或度量错误
|
||||
func (e *Editor) DistributionAxes(page int, paths []ObjectPath) ([]string, error) {
|
||||
objects, annotations, groups, err := editorTargetGroups(paths)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var boxes []Box
|
||||
var positions []editorObjectPosition
|
||||
if len(groups) == 0 {
|
||||
boxes, positions, _, err = e.selectionGeometry(page, objects, annotations)
|
||||
} else {
|
||||
boxes, _, _, err = e.targetGeometry(page, paths)
|
||||
positions = make([]editorObjectPosition, len(paths))
|
||||
for i := range positions {
|
||||
positions[i].index = i
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
axes := []string{}
|
||||
if len(boxes) < 3 {
|
||||
return axes, nil
|
||||
}
|
||||
for _, axis := range []string{"horizontal", "vertical"} {
|
||||
if _, err := editorDistribution(boxes, positions, axis); err == nil {
|
||||
axes = append(axes, axis)
|
||||
}
|
||||
}
|
||||
return axes, nil
|
||||
}
|
||||
|
||||
// ArrangeTargets 对齐或等距分布跨容器选区,单选对齐页面
|
||||
// 入参: page 页面索引, paths 按绘制顺序排列的完整路径, distribute 是否分布, direction 对齐方向或分布轴
|
||||
// 返回: error 路径、方向或编辑错误
|
||||
|
||||
Reference in new issue
Block a user