fix: 当前选中组件处于流式布局模式下时,直接拖动其他组件会错误判断成是流式组件

This commit is contained in:
roymondchen 2022-07-25 21:59:01 +08:00 committed by jia000
parent d334b697ae
commit 89f863d873
5 changed files with 48 additions and 35 deletions

View File

@ -160,7 +160,7 @@ StageDragResize实例
销毁实例 销毁实例
### setElementFromPoint ### getElementFromPoint
- **参数:** - **参数:**

View File

@ -41,8 +41,7 @@ import { computed, defineComponent, inject, ref } from 'vue';
import serialize from 'serialize-javascript'; import serialize from 'serialize-javascript';
import type StageCore from '@tmagic/stage'; import type StageCore from '@tmagic/stage';
import { GHOST_EL_ID_PREFIX } from '@tmagic/stage'; import { removeClassNameByClassName } from '@tmagic/utils';
import { addClassName, removeClassNameByClassName } from '@tmagic/utils';
import MIcon from '@editor/components/Icon.vue'; import MIcon from '@editor/components/Icon.vue';
import type { ComponentGroup, ComponentItem, Services, StageOptions } from '@editor/type'; import type { ComponentGroup, ComponentItem, Services, StageOptions } from '@editor/type';
@ -125,19 +124,9 @@ export default defineComponent({
return; return;
} }
if (timeout) return; if (timeout || !stage.value) return;
timeout = globalThis.setTimeout(async () => { timeout = stage.value.getAddContainerHighlightClassNameTimeout(e);
if (!stageOptions || !stage.value) return;
const doc = stage.value.renderer.contentWindow?.document;
const els = stage.value.getElementsFromPoint(e);
for (const el of els) {
if (doc && !el.id.startsWith(GHOST_EL_ID_PREFIX) && (await stageOptions.isContainer(el))) {
addClassName(el, doc, stageOptions?.containerHighlightClassName);
break;
}
}
}, stageOptions?.containerHighlightDuration);
}, },
}; };
}, },

View File

@ -19,6 +19,7 @@
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import type { Id } from '@tmagic/schema'; import type { Id } from '@tmagic/schema';
import { addClassName } from '@tmagic/utils';
import { DEFAULT_ZOOM, GHOST_EL_ID_PREFIX, PAGE_CLASS } from './const'; import { DEFAULT_ZOOM, GHOST_EL_ID_PREFIX, PAGE_CLASS } from './const';
import StageDragResize from './StageDragResize'; import StageDragResize from './StageDragResize';
@ -86,7 +87,7 @@ export default class StageCore extends EventEmitter {
this.mask this.mask
.on('beforeSelect', async (event: MouseEvent) => { .on('beforeSelect', async (event: MouseEvent) => {
this.clearSelectStatus('multiSelect'); this.clearSelectStatus('multiSelect');
const el = await this.setElementFromPoint(event); const el = await this.getElementFromPoint(event);
if (!el) return; if (!el) return;
this.select(el, event); this.select(el, event);
}) })
@ -98,7 +99,7 @@ export default class StageCore extends EventEmitter {
this.emit('changeGuides', data); this.emit('changeGuides', data);
}) })
.on('highlight', async (event: MouseEvent) => { .on('highlight', async (event: MouseEvent) => {
const el = await this.setElementFromPoint(event, 'mousemove'); const el = await this.getElementFromPoint(event, 'mousemove');
if (!el) return; if (!el) return;
await this.highlight(el); await this.highlight(el);
if (this.highlightedDom === this.selectedDom) { if (this.highlightedDom === this.selectedDom) {
@ -111,7 +112,7 @@ export default class StageCore extends EventEmitter {
this.highlightLayer.clearHighlight(); this.highlightLayer.clearHighlight();
}) })
.on('beforeMultiSelect', async (event: MouseEvent) => { .on('beforeMultiSelect', async (event: MouseEvent) => {
const el = await this.setElementFromPoint(event); const el = await this.getElementFromPoint(event);
if (!el) return; if (!el) return;
// 多选不可以选中magic-ui-page // 多选不可以选中magic-ui-page
if (el.className.includes(PAGE_CLASS)) return; if (el.className.includes(PAGE_CLASS)) return;
@ -165,7 +166,7 @@ export default class StageCore extends EventEmitter {
return doc?.elementsFromPoint(x / zoom, y / zoom) as HTMLElement[]; return doc?.elementsFromPoint(x / zoom, y / zoom) as HTMLElement[];
} }
public async setElementFromPoint(event: MouseEvent, type?: String) { public async getElementFromPoint(event: MouseEvent, type?: String) {
const els = this.getElementsFromPoint(event); const els = this.getElementsFromPoint(event);
let stopped = false; let stopped = false;
const stop = () => (stopped = true); const stop = () => (stopped = true);
@ -306,6 +307,27 @@ export default class StageCore extends EventEmitter {
this.dr.clearGuides(); this.dr.clearGuides();
} }
public async addContainerHighlightClassName(event: MouseEvent, exclude: Element[]) {
const els = this.getElementsFromPoint(event);
const { renderer } = this;
const doc = renderer.contentWindow?.document;
if (!doc) return;
for (const el of els) {
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && (await this.isContainer(el)) && !exclude.includes(el)) {
addClassName(el, doc, this.containerHighlightClassName);
break;
}
}
}
public getAddContainerHighlightClassNameTimeout(event: MouseEvent, exclude: Element[] = []) {
return globalThis.setTimeout(() => {
this.addContainerHighlightClassName(event, exclude);
}, this.containerHighlightDuration);
}
/** /**
* *
*/ */

View File

@ -23,7 +23,7 @@ import type { MoveableOptions } from 'moveable';
import Moveable from 'moveable'; import Moveable from 'moveable';
import MoveableHelper from 'moveable-helper'; import MoveableHelper from 'moveable-helper';
import { addClassName, removeClassNameByClassName } from '@tmagic/utils'; import { removeClassNameByClassName } from '@tmagic/utils';
import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, Mode, ZIndex } from './const'; import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, Mode, ZIndex } from './const';
import StageCore from './StageCore'; import StageCore from './StageCore';
@ -299,6 +299,7 @@ export default class StageDragResize extends EventEmitter {
if (this.mode === Mode.SORTABLE) { if (this.mode === Mode.SORTABLE) {
this.ghostEl = this.generateGhostEl(this.target); this.ghostEl = this.generateGhostEl(this.target);
} }
frame.top = this.target.offsetTop; frame.top = this.target.offsetTop;
frame.left = this.target.offsetLeft; frame.left = this.target.offsetLeft;
}) })
@ -310,20 +311,7 @@ export default class StageDragResize extends EventEmitter {
timeout = undefined; timeout = undefined;
} }
timeout = globalThis.setTimeout(async () => { timeout = this.core.getAddContainerHighlightClassNameTimeout(e.inputEvent, [this.target]);
const els = this.core.getElementsFromPoint(e.inputEvent);
for (const el of els) {
if (
doc &&
!el.id.startsWith(GHOST_EL_ID_PREFIX) &&
el !== this.target &&
(await this.core.isContainer(el))
) {
addClassName(el, doc, this.core.containerHighlightClassName);
break;
}
}
}, this.core.containerHighlightDuration);
this.dragStatus = ActionStatus.ING; this.dragStatus = ActionStatus.ING;
@ -483,6 +471,7 @@ export default class StageDragResize extends EventEmitter {
} }
const ghostEl = el.cloneNode(true) as HTMLElement; const ghostEl = el.cloneNode(true) as HTMLElement;
this.setGhostElChildrenId(ghostEl);
const { top, left } = getAbsolutePosition(el, getOffset(el)); const { top, left } = getAbsolutePosition(el, getOffset(el));
ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`; ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
ghostEl.style.zIndex = ZIndex.GHOST_EL; ghostEl.style.zIndex = ZIndex.GHOST_EL;
@ -494,6 +483,18 @@ export default class StageDragResize extends EventEmitter {
return ghostEl; return ghostEl;
} }
private setGhostElChildrenId(el: Element) {
for (const child of el.children) {
if (child.id) {
child.id = `${GHOST_EL_ID_PREFIX}${child.id}`;
}
if (child.children.length) {
this.setGhostElChildrenId(child);
}
}
}
private destroyGhostEl(): void { private destroyGhostEl(): void {
this.ghostEl?.remove(); this.ghostEl?.remove();
this.ghostEl = undefined; this.ghostEl = undefined;

View File

@ -19,7 +19,7 @@
import { MoveableOptions } from 'moveable'; import { MoveableOptions } from 'moveable';
import Core from '@tmagic/core'; import Core from '@tmagic/core';
import type { Id, MApp, MNode } from '@tmagic/schema'; import type { Id, MApp, MContainer, MNode } from '@tmagic/schema';
import { GuidesType } from './const'; import { GuidesType } from './const';
import StageCore from './StageCore'; import StageCore from './StageCore';
@ -99,6 +99,7 @@ export interface SortEventData {
export interface UpdateData { export interface UpdateData {
config: MNode; config: MNode;
parent?: MContainer;
root: MApp; root: MApp;
} }