mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-06-14 17:06:03 +08:00
多选优化及问题修复 (#196)
* feat(stage): 支持绝对定位,固定定位,组内元素按住shift键进行多选拖拽能力 * feat(stage): 使用moveable.helper接管moveable target的更新,针对弹窗场景引入业务方方法进行校准 * feat(stage): 将多选逻辑封装到StageMultiDragResize * fix(stage): 修复多选target元素无法映射到drag虚拟元素的问题 * feat(stage): 多选拖拽完成后将更新的位置信息暴露给上层业务方 * fix(stage): 删除多余的成员变量 Co-authored-by: parisma <parisma@tencent.com>
This commit is contained in:
parent
fe520bf600
commit
3ccabfbe44
@ -141,6 +141,10 @@ export default class StageCore extends EventEmitter {
|
||||
.on('sort', (data: UpdateEventData) => {
|
||||
setTimeout(() => this.emit('sort', data));
|
||||
});
|
||||
|
||||
this.multiDr.on('update', (data: UpdateEventData) => {
|
||||
setTimeout(() => this.emit('update', data));
|
||||
});
|
||||
}
|
||||
|
||||
public getElementsFromPoint(event: MouseEvent) {
|
||||
|
@ -53,14 +53,8 @@ export default class StageDragResize extends EventEmitter {
|
||||
public target?: HTMLElement;
|
||||
/** 目标节点在蒙层中的占位节点 */
|
||||
public dragEl?: HTMLDivElement;
|
||||
/** 多选:目标节点组 */
|
||||
public targetList: HTMLElement[] = [];
|
||||
/** 多选:目标节点在蒙层中的占位节点组 */
|
||||
public dragElList: HTMLDivElement[] = [];
|
||||
/** Moveable拖拽类实例 */
|
||||
public moveable?: Moveable;
|
||||
/** Moveable多选拖拽类实例 */
|
||||
public moveableForMulti?: Moveable;
|
||||
/** 水平参考线 */
|
||||
public horizontalGuidelines: number[] = [];
|
||||
/** 垂直参考线 */
|
||||
|
@ -25,7 +25,7 @@ import { DRAG_EL_ID_PREFIX } from './const';
|
||||
import StageCore from './StageCore';
|
||||
import StageMask from './StageMask';
|
||||
import { StageDragResizeConfig } from './types';
|
||||
import { getTargetElStyle } from './util';
|
||||
import { calcValueByFontsize, getTargetElStyle } from './util';
|
||||
export default class StageMultiDragResize extends EventEmitter {
|
||||
public core: StageCore;
|
||||
public mask: StageMask;
|
||||
@ -88,7 +88,7 @@ export default class StageMultiDragResize extends EventEmitter {
|
||||
useRender: false,
|
||||
createAuto: true,
|
||||
});
|
||||
const frames: { left: number; top: number; dragLeft: number; dragTop: number; id: string }[] = [];
|
||||
const frames: { left: number; top: number; id: string }[] = [];
|
||||
this.moveableForMulti
|
||||
.on('dragGroupStart', (params) => {
|
||||
const { events } = params;
|
||||
@ -96,15 +96,13 @@ export default class StageMultiDragResize extends EventEmitter {
|
||||
// 记录拖动前快照
|
||||
events.forEach((ev) => {
|
||||
// 实际目标元素
|
||||
const matchEventTarget = this.targetList.find((targetItem) => targetItem.id === ev.target.id.split('_')[2]);
|
||||
// 蒙层虚拟元素(对于在组内的元素拖动时的相对位置不同,因此需要分别记录)
|
||||
const dragEventTarget = ev.target as HTMLDivElement;
|
||||
if (!matchEventTarget || !dragEventTarget) return;
|
||||
const matchEventTarget = this.targetList.find(
|
||||
(targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ''),
|
||||
);
|
||||
if (!matchEventTarget) return;
|
||||
frames.push({
|
||||
left: matchEventTarget.offsetLeft,
|
||||
top: matchEventTarget.offsetTop,
|
||||
dragLeft: dragEventTarget.offsetLeft,
|
||||
dragTop: dragEventTarget.offsetTop,
|
||||
id: matchEventTarget.id,
|
||||
});
|
||||
});
|
||||
@ -113,9 +111,13 @@ export default class StageMultiDragResize extends EventEmitter {
|
||||
const { events } = params;
|
||||
// 拖动过程更新
|
||||
events.forEach((ev) => {
|
||||
const frameSnapShot = frames.find((frameItem) => frameItem.id === ev.target.id.split('_')[2]);
|
||||
const frameSnapShot = frames.find(
|
||||
(frameItem) => frameItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ''),
|
||||
);
|
||||
if (!frameSnapShot) return;
|
||||
const targeEl = this.targetList.find((targetItem) => targetItem.id === ev.target.id.split('_')[2]);
|
||||
const targeEl = this.targetList.find(
|
||||
(targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ''),
|
||||
);
|
||||
if (!targeEl) return;
|
||||
// 元素与其所属组同时加入多选列表时,只更新父元素
|
||||
const isParentIncluded = this.targetList.find((targetItem) => targetItem.id === targeEl.parentElement?.id);
|
||||
@ -126,6 +128,9 @@ export default class StageMultiDragResize extends EventEmitter {
|
||||
}
|
||||
});
|
||||
this.multiMoveableHelper?.onDragGroup(params);
|
||||
})
|
||||
.on('dragGroupEnd', () => {
|
||||
this.update();
|
||||
});
|
||||
}
|
||||
|
||||
@ -153,4 +158,28 @@ export default class StageMultiDragResize extends EventEmitter {
|
||||
public destroyDragElList(): void {
|
||||
this.dragElList.forEach((dragElItem) => dragElItem?.remove());
|
||||
}
|
||||
|
||||
/**
|
||||
* 拖拽完成后将更新的位置信息暴露给上层业务方,业务方可以接收事件进行保存
|
||||
* @param isResize 是否进行大小缩放
|
||||
*/
|
||||
private update(isResize = false): void {
|
||||
if (this.targetList.length === 0) return;
|
||||
|
||||
const { contentWindow } = this.core.renderer;
|
||||
const doc = contentWindow?.document;
|
||||
if (!doc) return;
|
||||
|
||||
this.targetList.forEach((targetItem) => {
|
||||
const offset = { left: targetItem.offsetLeft, top: targetItem.offsetTop };
|
||||
const left = calcValueByFontsize(doc, offset.left);
|
||||
const top = calcValueByFontsize(doc, offset.top);
|
||||
const width = calcValueByFontsize(doc, targetItem.clientWidth);
|
||||
const height = calcValueByFontsize(doc, targetItem.clientHeight);
|
||||
this.emit('update', {
|
||||
el: targetItem,
|
||||
style: isResize ? { left, top, width, height } : { left, top },
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user