feat(stage): 支持配置对齐元素

This commit is contained in:
roymondchen 2023-11-28 16:19:00 +08:00
parent eb43deb9f5
commit f8125aa149
6 changed files with 33 additions and 16 deletions

View File

@ -377,6 +377,7 @@ export default class ActionManager extends EventEmitter {
targetEls: this.selectedElList,
targetElIds: this.selectedElList?.map((item) => item.id),
isMulti,
document: this.getRenderDocument(),
};
return options(cfg);
}

View File

@ -19,7 +19,7 @@
import EventEmitter from 'events';
import { merge } from 'lodash-es';
import { MoveableOptions } from 'moveable';
import type { ElementGuidelineValueOption, MoveableOptions, MoveableRefType } from 'moveable';
import { GuidesType, Mode } from './const';
import MoveableActionsAble from './MoveableActionsAble';
@ -88,16 +88,19 @@ export default class MoveableOptionsManager extends EventEmitter {
/**
*
* @param selectedElList
* @param allElList
*/
protected setElementGuidelines(selectedElList: HTMLElement[], allElList: Element[]): void {
protected setElementGuidelines(selectedElList: HTMLElement[]): void {
this.elementGuidelines.forEach((node) => {
node.remove();
});
this.elementGuidelines = [];
// 设置选中元素的周围元素,用于选中元素跟周围元素对齐辅助
const elementGuidelines: Array<ElementGuidelineValueOption | MoveableRefType<Element>> =
this.getCustomizeOptions()?.elementGuidelines || Array.from(selectedElList[0]?.parentElement?.children || []);
if (this.mode === Mode.ABSOLUTE) {
this.container.append(this.createGuidelineElements(selectedElList, allElList));
this.container.append(this.createGuidelineElements(selectedElList, elementGuidelines));
}
}
@ -224,13 +227,29 @@ export default class MoveableOptionsManager extends EventEmitter {
* @param allElList
* @returns frame
*/
private createGuidelineElements(selectedElList: HTMLElement[], allElList: Element[]): DocumentFragment {
private createGuidelineElements(
selectedElList: HTMLElement[],
allElList: Array<ElementGuidelineValueOption | MoveableRefType<Element>>,
): DocumentFragment {
const frame = globalThis.document.createDocumentFragment();
for (const node of allElList) {
const { width, height } = node.getBoundingClientRect();
if (this.isInElementList(node, selectedElList)) continue;
const { left, top } = getOffset(node);
for (const element of allElList) {
let node: MoveableRefType<Element> =
(element as ElementGuidelineValueOption).element || (element as MoveableRefType<Element>);
if (!node || typeof node === 'string') continue;
if (typeof node === 'function') {
node = node();
}
if (this.isInElementList(node as Element, selectedElList)) continue;
const { width, height } = (node as Element).getBoundingClientRect();
if (!width || !height) continue;
const { left, top } = getOffset(node as Element);
const elementGuideline = globalThis.document.createElement('div');
elementGuideline.style.cssText = `position: absolute;width: ${width}px;height: ${height}px;top: ${top}px;left: ${left}px`;
this.elementGuidelines.push(elementGuideline);

View File

@ -131,9 +131,7 @@ export default class StageDragResize extends MoveableOptionsManager {
this.dragResizeHelper.updateShadowEl(el);
this.dragResizeHelper.setMode(this.mode);
// 设置选中元素的周围元素,用于选中元素跟周围元素对齐辅助
const elementGuidelines: Element[] = Array.from(this.target?.parentElement?.children || []);
this.setElementGuidelines([this.target as HTMLElement], elementGuidelines);
this.setElementGuidelines([this.target as HTMLElement]);
return this.getOptions(false, {
target: this.dragResizeHelper.getShadowEl(),

View File

@ -79,9 +79,7 @@ export default class StageMultiDragResize extends MoveableOptionsManager {
this.dragResizeHelper.updateGroup(els);
// 设置周围元素,用于选中元素跟周围元素的对齐辅助
const elementGuidelines: Element[] = Array.from(this.targetList[0].parentElement?.children || []);
this.setElementGuidelines(this.targetList, elementGuidelines);
this.setElementGuidelines(this.targetList);
this.moveableForMulti?.destroy();
this.dragResizeHelper.clear();

View File

@ -101,6 +101,7 @@ export interface CustomizeMoveableOptionsCallbackConfig {
targetEls?: HTMLElement[];
targetElIds?: string[];
isMulti: boolean;
document?: Document;
}
export interface StageRenderConfig {

View File

@ -52,7 +52,7 @@ import { TMagicDialog, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
import { DatasourceTypeOption, editorService, MenuBarData, MoveableOptions, TMagicEditor } from '@tmagic/editor';
import type { MContainer, MNode } from '@tmagic/schema';
import { NodeType } from '@tmagic/schema';
import { CustomizeMoveableOptionsCallbackConfig } from '@tmagic/stage';
import type { CustomizeMoveableOptionsCallbackConfig } from '@tmagic/stage';
import { asyncLoadJs } from '@tmagic/utils';
import DeviceGroup from '../components/DeviceGroup.vue';