@tmagic/stage 1.2.0-beta.18 → 1.2.0-beta.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -1
- package/dist/tmagic-stage.mjs +1389 -1060
- package/dist/tmagic-stage.mjs.map +1 -1
- package/dist/tmagic-stage.umd.js +1387 -1058
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/package.json +4 -4
- package/src/ActionManager.ts +534 -0
- package/src/DragResizeHelper.ts +338 -0
- package/src/MoveableOptionsManager.ts +249 -0
- package/src/MoveableSelectParentAble.ts +3 -5
- package/src/Rule.ts +4 -4
- package/src/StageCore.ts +202 -275
- package/src/StageDragResize.ts +83 -347
- package/src/StageHighlight.ts +17 -16
- package/src/StageMask.ts +19 -102
- package/src/StageMultiDragResize.ts +97 -198
- package/src/StageRender.ts +85 -10
- package/src/TargetShadow.ts +120 -0
- package/src/const.ts +1 -1
- package/src/types.ts +95 -18
- package/src/util.ts +18 -11
- package/types/ActionManager.d.ts +141 -0
- package/types/DragResizeHelper.d.ts +70 -0
- package/types/MoveableOptionsManager.d.ts +86 -0
- package/types/MoveableSelectParentAble.d.ts +1 -2
- package/types/StageCore.d.ts +58 -41
- package/types/StageDragResize.d.ts +11 -40
- package/types/StageHighlight.d.ts +3 -4
- package/types/StageMask.d.ts +0 -21
- package/types/StageMultiDragResize.d.ts +8 -24
- package/types/StageRender.d.ts +23 -4
- package/types/TargetShadow.d.ts +22 -0
- package/types/const.d.ts +1 -1
- package/types/types.d.ts +83 -17
- package/types/util.d.ts +8 -8
- package/src/TargetCalibrate.ts +0 -119
- package/types/TargetCalibrate.d.ts +0 -20
package/src/StageDragResize.ts
CHANGED
|
@@ -17,103 +17,62 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
/* eslint-disable no-param-reassign */
|
|
20
|
-
import {
|
|
20
|
+
import Moveable, { MoveableOptions } from 'moveable';
|
|
21
21
|
|
|
22
|
-
import
|
|
23
|
-
import
|
|
24
|
-
import
|
|
25
|
-
import
|
|
26
|
-
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, Mode, ZIndex } from './const';
|
|
30
|
-
import selectParentAbles from './MoveableSelectParentAble';
|
|
31
|
-
import StageCore from './StageCore';
|
|
32
|
-
import StageMask from './StageMask';
|
|
33
|
-
import type { StageDragResizeConfig } from './types';
|
|
34
|
-
import { ContainerHighlightType, StageDragStatus } from './types';
|
|
35
|
-
import { calcValueByFontsize, down, getAbsolutePosition, getMode, getOffset, getTargetElStyle, up } from './util';
|
|
22
|
+
import { Mode } from './const';
|
|
23
|
+
import DragResizeHelper from './DragResizeHelper';
|
|
24
|
+
import MoveableOptionsManager from './MoveableOptionsManager';
|
|
25
|
+
import type { DelayedMarkContainer, GetRenderDocument, MarkContainerEnd, StageDragResizeConfig } from './types';
|
|
26
|
+
import { StageDragStatus } from './types';
|
|
27
|
+
import { calcValueByFontsize, down, getMode, getOffset, up } from './util';
|
|
36
28
|
|
|
37
29
|
/**
|
|
38
|
-
*
|
|
30
|
+
* 管理单选操作,响应选中操作,初始化moveableOption参数并初始化moveable,处理moveable回调事件对组件进行更新
|
|
31
|
+
* @extends MoveableOptionsManager
|
|
39
32
|
*/
|
|
40
|
-
export default class StageDragResize extends
|
|
41
|
-
public core: StageCore;
|
|
42
|
-
public mask: StageMask;
|
|
43
|
-
/** 画布容器 */
|
|
44
|
-
public container: HTMLElement;
|
|
33
|
+
export default class StageDragResize extends MoveableOptionsManager {
|
|
45
34
|
/** 目标节点 */
|
|
46
|
-
|
|
47
|
-
/** 目标节点在蒙层中的占位节点 */
|
|
48
|
-
public dragEl?: HTMLDivElement;
|
|
35
|
+
private target?: HTMLElement;
|
|
49
36
|
/** Moveable拖拽类实例 */
|
|
50
|
-
|
|
51
|
-
/** 水平参考线 */
|
|
52
|
-
public horizontalGuidelines: number[] = [];
|
|
53
|
-
/** 垂直参考线 */
|
|
54
|
-
public verticalGuidelines: number[] = [];
|
|
55
|
-
/** 对齐元素集合 */
|
|
56
|
-
public elementGuidelines: HTMLElement[] = [];
|
|
57
|
-
/** 布局方式:流式布局、绝对定位、固定定位 */
|
|
58
|
-
public mode: Mode = Mode.ABSOLUTE;
|
|
59
|
-
|
|
60
|
-
private moveableOptions: MoveableOptions = {};
|
|
37
|
+
private moveable?: Moveable;
|
|
61
38
|
/** 拖动状态 */
|
|
62
39
|
private dragStatus: StageDragStatus = StageDragStatus.END;
|
|
63
|
-
|
|
64
|
-
private
|
|
65
|
-
private
|
|
66
|
-
private
|
|
40
|
+
private dragResizeHelper: DragResizeHelper;
|
|
41
|
+
private getRenderDocument: GetRenderDocument;
|
|
42
|
+
private markContainerEnd: MarkContainerEnd;
|
|
43
|
+
private delayedMarkContainer: DelayedMarkContainer;
|
|
67
44
|
|
|
68
45
|
constructor(config: StageDragResizeConfig) {
|
|
69
|
-
super();
|
|
46
|
+
super(config);
|
|
70
47
|
|
|
71
|
-
this.
|
|
72
|
-
this.
|
|
73
|
-
this.
|
|
48
|
+
this.getRenderDocument = config.getRenderDocument;
|
|
49
|
+
this.markContainerEnd = config.markContainerEnd;
|
|
50
|
+
this.delayedMarkContainer = config.delayedMarkContainer;
|
|
74
51
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
52
|
+
this.dragResizeHelper = new DragResizeHelper({
|
|
53
|
+
container: config.container,
|
|
54
|
+
updateDragEl: config.updateDragEl,
|
|
78
55
|
});
|
|
79
|
-
KeyController.global.keyup('alt', (e) => {
|
|
80
|
-
e.inputEvent.preventDefault();
|
|
81
56
|
|
|
82
|
-
|
|
83
|
-
if (
|
|
84
|
-
|
|
57
|
+
this.on('update-moveable', () => {
|
|
58
|
+
if (this.moveable) {
|
|
59
|
+
this.updateMoveable();
|
|
85
60
|
}
|
|
86
|
-
this.isContainerHighlight = false;
|
|
87
61
|
});
|
|
88
62
|
}
|
|
89
63
|
|
|
90
64
|
/**
|
|
91
65
|
* 将选中框渲染并覆盖到选中的组件Dom节点上方
|
|
92
|
-
*
|
|
66
|
+
* 当选中的节点不是absolute时,会创建一个新的节点出来作为拖拽目标
|
|
93
67
|
* @param el 选中组件的Dom节点元素
|
|
94
68
|
* @param event 鼠标事件
|
|
95
69
|
*/
|
|
96
70
|
public select(el: HTMLElement, event?: MouseEvent): void {
|
|
97
|
-
const oldTarget = this.target;
|
|
98
|
-
this.target = el;
|
|
99
|
-
|
|
100
|
-
if (!this.dragEl) {
|
|
101
|
-
this.dragEl = globalThis.document.createElement('div');
|
|
102
|
-
this.container.append(this.dragEl);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
71
|
// 从不能拖动到能拖动的节点之间切换,要重新创建moveable,不然dragStart不生效
|
|
106
|
-
if (!this.moveable || this.target
|
|
107
|
-
this.
|
|
108
|
-
this.moveableHelper = MoveableHelper.create({
|
|
109
|
-
useBeforeRender: true,
|
|
110
|
-
useRender: false,
|
|
111
|
-
createAuto: true,
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
this.initMoveable();
|
|
72
|
+
if (!this.moveable || el !== this.target) {
|
|
73
|
+
this.initMoveable(el);
|
|
115
74
|
} else {
|
|
116
|
-
this.updateMoveable();
|
|
75
|
+
this.updateMoveable(el);
|
|
117
76
|
}
|
|
118
77
|
|
|
119
78
|
if (event) {
|
|
@@ -125,120 +84,63 @@ export default class StageDragResize extends EventEmitter {
|
|
|
125
84
|
* 初始化选中框并渲染出来
|
|
126
85
|
*/
|
|
127
86
|
public updateMoveable(el = this.target): void {
|
|
128
|
-
if (!this.moveable)
|
|
87
|
+
if (!this.moveable) return;
|
|
129
88
|
if (!el) throw new Error('未选中任何节点');
|
|
130
89
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
this.init(el);
|
|
90
|
+
const options: MoveableOptions = this.init(el);
|
|
134
91
|
|
|
135
|
-
Object.entries(
|
|
92
|
+
Object.entries(options).forEach(([key, value]) => {
|
|
136
93
|
(this.moveable as any)[key] = value;
|
|
137
94
|
});
|
|
138
95
|
this.moveable.updateTarget();
|
|
139
96
|
}
|
|
140
97
|
|
|
141
|
-
public setGuidelines(type: GuidesType, guidelines: number[]): void {
|
|
142
|
-
if (type === GuidesType.HORIZONTAL) {
|
|
143
|
-
this.horizontalGuidelines = guidelines;
|
|
144
|
-
this.moveableOptions.horizontalGuidelines = guidelines;
|
|
145
|
-
} else if (type === GuidesType.VERTICAL) {
|
|
146
|
-
this.verticalGuidelines = guidelines;
|
|
147
|
-
this.moveableOptions.verticalGuidelines = guidelines;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (this.moveable) {
|
|
151
|
-
this.updateMoveable();
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
public clearGuides() {
|
|
156
|
-
this.horizontalGuidelines = [];
|
|
157
|
-
this.verticalGuidelines = [];
|
|
158
|
-
this.moveableOptions.horizontalGuidelines = [];
|
|
159
|
-
this.moveableOptions.verticalGuidelines = [];
|
|
160
|
-
this.updateMoveable();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
98
|
public clearSelectStatus(): void {
|
|
164
99
|
if (!this.moveable) return;
|
|
165
|
-
this.
|
|
166
|
-
this.dragEl = undefined;
|
|
100
|
+
this.dragResizeHelper.destroyShadowEl();
|
|
167
101
|
this.moveable.target = null;
|
|
168
102
|
this.moveable.updateTarget();
|
|
169
103
|
}
|
|
170
104
|
|
|
171
|
-
public destroyDragEl(): void {
|
|
172
|
-
this.dragEl?.remove();
|
|
173
|
-
}
|
|
174
|
-
|
|
175
105
|
/**
|
|
176
106
|
* 销毁实例
|
|
177
107
|
*/
|
|
178
108
|
public destroy(): void {
|
|
179
109
|
this.moveable?.destroy();
|
|
180
|
-
this.
|
|
181
|
-
this.destroyDragEl();
|
|
110
|
+
this.dragResizeHelper.destroy();
|
|
182
111
|
this.dragStatus = StageDragStatus.END;
|
|
183
112
|
this.removeAllListeners();
|
|
184
113
|
}
|
|
185
114
|
|
|
186
|
-
private init(el: HTMLElement):
|
|
115
|
+
private init(el: HTMLElement): MoveableOptions {
|
|
187
116
|
// 如果有滚动条会导致resize时获取到width,height不准确
|
|
188
117
|
if (/(auto|scroll)/.test(el.style.overflow)) {
|
|
189
118
|
el.style.overflow = 'hidden';
|
|
190
119
|
}
|
|
191
|
-
this.mode = getMode(el);
|
|
192
120
|
|
|
193
|
-
this.
|
|
194
|
-
|
|
195
|
-
if (!this.dragEl) {
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
121
|
+
this.target = el;
|
|
122
|
+
this.mode = getMode(el);
|
|
198
123
|
|
|
199
|
-
this.
|
|
200
|
-
this.
|
|
124
|
+
this.dragResizeHelper.updateShadowEl(el);
|
|
125
|
+
this.dragResizeHelper.setMode(this.mode);
|
|
201
126
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
this.moveableOptions = this.getOptions({
|
|
206
|
-
target: this.dragEl,
|
|
207
|
-
});
|
|
208
|
-
}
|
|
127
|
+
// 设置选中元素的周围元素,用于选中元素跟周围元素对齐辅助
|
|
128
|
+
const elementGuidelines: HTMLElement[] = Array.prototype.slice.call(this.target?.parentElement?.children) || [];
|
|
129
|
+
this.setElementGuidelines([this.target as HTMLElement], elementGuidelines);
|
|
209
130
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
node.remove();
|
|
131
|
+
return this.getOptions(false, {
|
|
132
|
+
target: this.dragResizeHelper.getShadowEl(),
|
|
213
133
|
});
|
|
214
|
-
this.elementGuidelines = [];
|
|
215
|
-
|
|
216
|
-
if (this.mode === Mode.ABSOLUTE) {
|
|
217
|
-
this.container.append(this.createGuidelineElements(nodes));
|
|
218
|
-
}
|
|
219
134
|
}
|
|
220
135
|
|
|
221
|
-
private
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
for (const node of nodes) {
|
|
225
|
-
const { width, height } = node.getBoundingClientRect();
|
|
226
|
-
if (node === this.target) continue;
|
|
227
|
-
const { left, top } = getOffset(node as HTMLElement);
|
|
228
|
-
const elementGuideline = globalThis.document.createElement('div');
|
|
229
|
-
elementGuideline.style.cssText = `position: absolute;width: ${width}px;height: ${height}px;top: ${top}px;left: ${left}px`;
|
|
230
|
-
this.elementGuidelines.push(elementGuideline);
|
|
231
|
-
frame.append(elementGuideline);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return frame;
|
|
235
|
-
}
|
|
136
|
+
private initMoveable(el: HTMLElement) {
|
|
137
|
+
const options: MoveableOptions = this.init(el);
|
|
138
|
+
this.dragResizeHelper.clear();
|
|
236
139
|
|
|
237
|
-
private initMoveable() {
|
|
238
140
|
this.moveable?.destroy();
|
|
239
141
|
|
|
240
142
|
this.moveable = new Moveable(this.container, {
|
|
241
|
-
...
|
|
143
|
+
...options,
|
|
242
144
|
});
|
|
243
145
|
|
|
244
146
|
this.bindResizeEvent();
|
|
@@ -250,41 +152,19 @@ export default class StageDragResize extends EventEmitter {
|
|
|
250
152
|
private bindResizeEvent(): void {
|
|
251
153
|
if (!this.moveable) throw new Error('moveable 未初始化');
|
|
252
154
|
|
|
253
|
-
const frame = {
|
|
254
|
-
left: 0,
|
|
255
|
-
top: 0,
|
|
256
|
-
};
|
|
257
|
-
|
|
258
155
|
this.moveable
|
|
259
156
|
.on('resizeStart', (e) => {
|
|
260
157
|
if (!this.target) return;
|
|
261
158
|
|
|
262
159
|
this.dragStatus = StageDragStatus.START;
|
|
263
|
-
this.
|
|
264
|
-
|
|
265
|
-
frame.top = this.target.offsetTop;
|
|
266
|
-
frame.left = this.target.offsetLeft;
|
|
160
|
+
this.dragResizeHelper.onResizeStart(e);
|
|
267
161
|
})
|
|
268
162
|
.on('resize', (e) => {
|
|
269
|
-
|
|
270
|
-
if (!this.moveable || !this.target || !this.dragEl) return;
|
|
163
|
+
if (!this.moveable || !this.target || !this.dragResizeHelper.getShadowEl()) return;
|
|
271
164
|
|
|
272
|
-
const { beforeTranslate } = drag;
|
|
273
165
|
this.dragStatus = StageDragStatus.ING;
|
|
274
166
|
|
|
275
|
-
|
|
276
|
-
if (this.mode === Mode.SORTABLE) {
|
|
277
|
-
this.target.style.top = '0px';
|
|
278
|
-
this.dragEl.style.width = `${width}px`;
|
|
279
|
-
this.dragEl.style.height = `${height}px`;
|
|
280
|
-
} else {
|
|
281
|
-
this.moveableHelper?.onResize(e);
|
|
282
|
-
this.target.style.left = `${frame.left + beforeTranslate[0]}px`;
|
|
283
|
-
this.target.style.top = `${frame.top + beforeTranslate[1]}px`;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
this.target.style.width = `${width}px`;
|
|
287
|
-
this.target.style.height = `${height}px`;
|
|
167
|
+
this.dragResizeHelper.onResize(e);
|
|
288
168
|
})
|
|
289
169
|
.on('resizeEnd', () => {
|
|
290
170
|
this.dragStatus = StageDragStatus.END;
|
|
@@ -295,55 +175,28 @@ export default class StageDragResize extends EventEmitter {
|
|
|
295
175
|
private bindDragEvent(): void {
|
|
296
176
|
if (!this.moveable) throw new Error('moveable 未初始化');
|
|
297
177
|
|
|
298
|
-
const frame = {
|
|
299
|
-
left: 0,
|
|
300
|
-
top: 0,
|
|
301
|
-
};
|
|
302
|
-
|
|
303
178
|
let timeout: NodeJS.Timeout | undefined;
|
|
304
179
|
|
|
305
|
-
const { contentWindow } = this.core.renderer;
|
|
306
|
-
const doc = contentWindow?.document;
|
|
307
|
-
|
|
308
180
|
this.moveable
|
|
309
181
|
.on('dragStart', (e) => {
|
|
310
182
|
if (!this.target) throw new Error('未选中组件');
|
|
311
183
|
|
|
312
184
|
this.dragStatus = StageDragStatus.START;
|
|
313
185
|
|
|
314
|
-
this.
|
|
315
|
-
|
|
316
|
-
if (this.mode === Mode.SORTABLE) {
|
|
317
|
-
this.ghostEl = this.generateGhostEl(this.target);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
frame.top = this.target.offsetTop;
|
|
321
|
-
frame.left = this.target.offsetLeft;
|
|
186
|
+
this.dragResizeHelper.onDragStart(e);
|
|
322
187
|
})
|
|
323
188
|
.on('drag', (e) => {
|
|
324
|
-
if (!this.target || !this.
|
|
189
|
+
if (!this.target || !this.dragResizeHelper.getShadowEl()) return;
|
|
325
190
|
|
|
326
191
|
if (timeout) {
|
|
327
192
|
globalThis.clearTimeout(timeout);
|
|
328
193
|
timeout = undefined;
|
|
329
194
|
}
|
|
330
|
-
|
|
331
|
-
if (this.canContainerHighlight()) {
|
|
332
|
-
timeout = this.core.getAddContainerHighlightClassNameTimeout(e.inputEvent, [this.target]);
|
|
333
|
-
}
|
|
195
|
+
timeout = this.delayedMarkContainer(e.inputEvent, [this.target]);
|
|
334
196
|
|
|
335
197
|
this.dragStatus = StageDragStatus.ING;
|
|
336
198
|
|
|
337
|
-
|
|
338
|
-
if (this.ghostEl) {
|
|
339
|
-
this.ghostEl.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
this.moveableHelper?.onDrag(e);
|
|
344
|
-
|
|
345
|
-
this.target.style.left = `${frame.left + e.beforeTranslate[0]}px`;
|
|
346
|
-
this.target.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
199
|
+
this.dragResizeHelper.onDrag(e);
|
|
347
200
|
})
|
|
348
201
|
.on('dragEnd', () => {
|
|
349
202
|
if (timeout) {
|
|
@@ -351,12 +204,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
351
204
|
timeout = undefined;
|
|
352
205
|
}
|
|
353
206
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if (doc && this.canContainerHighlight()) {
|
|
357
|
-
parentEl = removeClassNameByClassName(doc, this.core.containerHighlightClassName);
|
|
358
|
-
}
|
|
359
|
-
|
|
207
|
+
const parentEl = this.markContainerEnd();
|
|
360
208
|
// 点击不拖动时会触发dragStart和dragEnd,但是不会有drag事件
|
|
361
209
|
if (this.dragStatus === StageDragStatus.ING) {
|
|
362
210
|
if (parentEl) {
|
|
@@ -373,7 +221,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
373
221
|
}
|
|
374
222
|
|
|
375
223
|
this.dragStatus = StageDragStatus.END;
|
|
376
|
-
this.destroyGhostEl();
|
|
224
|
+
this.dragResizeHelper.destroyGhostEl();
|
|
377
225
|
});
|
|
378
226
|
}
|
|
379
227
|
|
|
@@ -383,18 +231,16 @@ export default class StageDragResize extends EventEmitter {
|
|
|
383
231
|
this.moveable
|
|
384
232
|
.on('rotateStart', (e) => {
|
|
385
233
|
this.dragStatus = StageDragStatus.START;
|
|
386
|
-
this.
|
|
234
|
+
this.dragResizeHelper.onRotateStart(e);
|
|
387
235
|
})
|
|
388
236
|
.on('rotate', (e) => {
|
|
389
|
-
if (!this.target || !this.
|
|
237
|
+
if (!this.target || !this.dragResizeHelper.getShadowEl()) return;
|
|
390
238
|
this.dragStatus = StageDragStatus.ING;
|
|
391
|
-
this.
|
|
392
|
-
const frame = this.moveableHelper?.getFrame(e.target);
|
|
393
|
-
this.target.style.transform = frame?.toCSSObject().transform || '';
|
|
239
|
+
this.dragResizeHelper.onRotate(e);
|
|
394
240
|
})
|
|
395
241
|
.on('rotateEnd', (e) => {
|
|
396
242
|
this.dragStatus = StageDragStatus.END;
|
|
397
|
-
const frame = this.
|
|
243
|
+
const frame = this.dragResizeHelper?.getFrame(e.target);
|
|
398
244
|
this.emit('update', {
|
|
399
245
|
data: [
|
|
400
246
|
{
|
|
@@ -414,18 +260,16 @@ export default class StageDragResize extends EventEmitter {
|
|
|
414
260
|
this.moveable
|
|
415
261
|
.on('scaleStart', (e) => {
|
|
416
262
|
this.dragStatus = StageDragStatus.START;
|
|
417
|
-
this.
|
|
263
|
+
this.dragResizeHelper.onScaleStart(e);
|
|
418
264
|
})
|
|
419
265
|
.on('scale', (e) => {
|
|
420
|
-
if (!this.target || !this.
|
|
266
|
+
if (!this.target || !this.dragResizeHelper.getShadowEl()) return;
|
|
421
267
|
this.dragStatus = StageDragStatus.ING;
|
|
422
|
-
this.
|
|
423
|
-
const frame = this.moveableHelper?.getFrame(e.target);
|
|
424
|
-
this.target.style.transform = frame?.toCSSObject().transform || '';
|
|
268
|
+
this.dragResizeHelper.onScale(e);
|
|
425
269
|
})
|
|
426
270
|
.on('scaleEnd', (e) => {
|
|
427
271
|
this.dragStatus = StageDragStatus.END;
|
|
428
|
-
const frame = this.
|
|
272
|
+
const frame = this.dragResizeHelper.getFrame(e.target);
|
|
429
273
|
this.emit('update', {
|
|
430
274
|
data: [
|
|
431
275
|
{
|
|
@@ -440,8 +284,8 @@ export default class StageDragResize extends EventEmitter {
|
|
|
440
284
|
}
|
|
441
285
|
|
|
442
286
|
private sort(): void {
|
|
443
|
-
if (!this.target || !this.
|
|
444
|
-
const { top } = this.
|
|
287
|
+
if (!this.target || !this.dragResizeHelper.getGhostEl()) throw new Error('未知错误');
|
|
288
|
+
const { top } = this.dragResizeHelper.getGhostEl()!.getBoundingClientRect();
|
|
445
289
|
const { top: oriTop } = this.target.getBoundingClientRect();
|
|
446
290
|
const deltaTop = top - oriTop;
|
|
447
291
|
if (Math.abs(deltaTop) >= this.target.clientHeight / 2) {
|
|
@@ -461,8 +305,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
461
305
|
private update(isResize = false, parentEl: HTMLElement | null = null): void {
|
|
462
306
|
if (!this.target) return;
|
|
463
307
|
|
|
464
|
-
const
|
|
465
|
-
const doc = contentWindow?.document;
|
|
308
|
+
const doc = this.getRenderDocument();
|
|
466
309
|
|
|
467
310
|
if (!doc) return;
|
|
468
311
|
|
|
@@ -474,15 +317,25 @@ export default class StageDragResize extends EventEmitter {
|
|
|
474
317
|
const width = calcValueByFontsize(doc, this.target.clientWidth);
|
|
475
318
|
const height = calcValueByFontsize(doc, this.target.clientHeight);
|
|
476
319
|
|
|
477
|
-
|
|
478
|
-
|
|
320
|
+
const shadowEl = this.dragResizeHelper.getShadowEl();
|
|
321
|
+
if (parentEl && this.mode === Mode.ABSOLUTE && shadowEl) {
|
|
322
|
+
const targetShadowHtmlEl = shadowEl as HTMLElement;
|
|
323
|
+
const targetShadowElOffsetLeft = targetShadowHtmlEl.offsetLeft || 0;
|
|
324
|
+
const targetShadowElOffsetTop = targetShadowHtmlEl.offsetTop || 0;
|
|
325
|
+
|
|
326
|
+
const frame = this.dragResizeHelper.getFrame(shadowEl);
|
|
327
|
+
|
|
328
|
+
const [translateX, translateY] = frame?.properties.transform.translate.value;
|
|
479
329
|
const { left: parentLeft, top: parentTop } = getOffset(parentEl);
|
|
330
|
+
|
|
480
331
|
left =
|
|
481
|
-
calcValueByFontsize(doc,
|
|
332
|
+
calcValueByFontsize(doc, targetShadowElOffsetLeft) +
|
|
482
333
|
parseFloat(translateX) -
|
|
483
334
|
calcValueByFontsize(doc, parentLeft);
|
|
484
335
|
top =
|
|
485
|
-
calcValueByFontsize(doc,
|
|
336
|
+
calcValueByFontsize(doc, targetShadowElOffsetTop) +
|
|
337
|
+
parseFloat(translateY) -
|
|
338
|
+
calcValueByFontsize(doc, parentTop);
|
|
486
339
|
}
|
|
487
340
|
|
|
488
341
|
this.emit('update', {
|
|
@@ -495,121 +348,4 @@ export default class StageDragResize extends EventEmitter {
|
|
|
495
348
|
parentEl,
|
|
496
349
|
});
|
|
497
350
|
}
|
|
498
|
-
|
|
499
|
-
private generateGhostEl(el: HTMLElement): HTMLElement {
|
|
500
|
-
if (this.ghostEl) {
|
|
501
|
-
this.destroyGhostEl();
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
const ghostEl = el.cloneNode(true) as HTMLElement;
|
|
505
|
-
this.setGhostElChildrenId(ghostEl);
|
|
506
|
-
const { top, left } = getAbsolutePosition(el, getOffset(el));
|
|
507
|
-
ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
|
|
508
|
-
ghostEl.style.zIndex = ZIndex.GHOST_EL;
|
|
509
|
-
ghostEl.style.opacity = '.5';
|
|
510
|
-
ghostEl.style.position = 'absolute';
|
|
511
|
-
ghostEl.style.left = `${left}px`;
|
|
512
|
-
ghostEl.style.top = `${top}px`;
|
|
513
|
-
el.after(ghostEl);
|
|
514
|
-
return ghostEl;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
private setGhostElChildrenId(el: Element) {
|
|
518
|
-
for (const child of Array.from(el.children)) {
|
|
519
|
-
if (child.id) {
|
|
520
|
-
child.id = `${GHOST_EL_ID_PREFIX}${child.id}`;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
if (child.children.length) {
|
|
524
|
-
this.setGhostElChildrenId(child);
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
private destroyGhostEl(): void {
|
|
530
|
-
this.ghostEl?.remove();
|
|
531
|
-
this.ghostEl = undefined;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
private getOptions(options: MoveableOptions = {}): MoveableOptions {
|
|
535
|
-
if (!this.target) return {};
|
|
536
|
-
|
|
537
|
-
const isAbsolute = this.mode === Mode.ABSOLUTE;
|
|
538
|
-
const isFixed = this.mode === Mode.FIXED;
|
|
539
|
-
const isSortable = this.mode === Mode.SORTABLE;
|
|
540
|
-
|
|
541
|
-
let { moveableOptions = {} } = this.core.config;
|
|
542
|
-
|
|
543
|
-
if (typeof moveableOptions === 'function') {
|
|
544
|
-
moveableOptions = moveableOptions(this.core);
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
const elementGuidelines: any = moveableOptions.elementGuidelines || this.target.parentElement?.children || [];
|
|
548
|
-
|
|
549
|
-
this.setElementGuidelines(elementGuidelines);
|
|
550
|
-
|
|
551
|
-
if (moveableOptions.elementGuidelines) {
|
|
552
|
-
delete moveableOptions.elementGuidelines;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
return {
|
|
556
|
-
origin: false,
|
|
557
|
-
rootContainer: this.core.container,
|
|
558
|
-
zoom: 1,
|
|
559
|
-
dragArea: false,
|
|
560
|
-
draggable: true,
|
|
561
|
-
resizable: true,
|
|
562
|
-
scalable: false,
|
|
563
|
-
rotatable: false,
|
|
564
|
-
snappable: true,
|
|
565
|
-
snapGap: isAbsolute || isFixed,
|
|
566
|
-
snapThreshold: 5,
|
|
567
|
-
snapDigit: 0,
|
|
568
|
-
throttleDrag: 0,
|
|
569
|
-
isDisplaySnapDigit: isAbsolute,
|
|
570
|
-
snapDirections: {
|
|
571
|
-
top: isAbsolute,
|
|
572
|
-
right: isAbsolute,
|
|
573
|
-
bottom: isAbsolute,
|
|
574
|
-
left: isAbsolute,
|
|
575
|
-
center: isAbsolute,
|
|
576
|
-
middle: isAbsolute,
|
|
577
|
-
},
|
|
578
|
-
elementSnapDirections: {
|
|
579
|
-
top: isAbsolute,
|
|
580
|
-
right: isAbsolute,
|
|
581
|
-
bottom: isAbsolute,
|
|
582
|
-
left: isAbsolute,
|
|
583
|
-
},
|
|
584
|
-
isDisplayInnerSnapDigit: true,
|
|
585
|
-
horizontalGuidelines: this.horizontalGuidelines,
|
|
586
|
-
verticalGuidelines: this.verticalGuidelines,
|
|
587
|
-
elementGuidelines: this.elementGuidelines,
|
|
588
|
-
|
|
589
|
-
bounds: {
|
|
590
|
-
top: 0,
|
|
591
|
-
// 设置0的话无法移动到left为0,所以只能设置为-1
|
|
592
|
-
left: -1,
|
|
593
|
-
right: this.container.clientWidth - 1,
|
|
594
|
-
bottom: isSortable ? undefined : this.container.clientHeight,
|
|
595
|
-
...(moveableOptions.bounds || {}),
|
|
596
|
-
},
|
|
597
|
-
|
|
598
|
-
props: {
|
|
599
|
-
selectParent: true,
|
|
600
|
-
},
|
|
601
|
-
|
|
602
|
-
ables: [selectParentAbles(this)],
|
|
603
|
-
|
|
604
|
-
...options,
|
|
605
|
-
...moveableOptions,
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
private canContainerHighlight() {
|
|
610
|
-
return (
|
|
611
|
-
this.core.containerHighlightType === ContainerHighlightType.DEFAULT ||
|
|
612
|
-
(this.core.containerHighlightType === ContainerHighlightType.ALT && this.isContainerHighlight)
|
|
613
|
-
);
|
|
614
|
-
}
|
|
615
351
|
}
|
package/src/StageHighlight.ts
CHANGED
|
@@ -20,27 +20,28 @@ import { EventEmitter } from 'events';
|
|
|
20
20
|
|
|
21
21
|
import Moveable from 'moveable';
|
|
22
22
|
|
|
23
|
-
import { HIGHLIGHT_EL_ID_PREFIX } from './const';
|
|
24
|
-
import
|
|
25
|
-
import
|
|
26
|
-
|
|
23
|
+
import { HIGHLIGHT_EL_ID_PREFIX, ZIndex } from './const';
|
|
24
|
+
import TargetShadow from './TargetShadow';
|
|
25
|
+
import type { GetRootContainer, StageHighlightConfig } from './types';
|
|
26
|
+
|
|
27
27
|
export default class StageHighlight extends EventEmitter {
|
|
28
|
-
public core: StageCore;
|
|
29
28
|
public container: HTMLElement;
|
|
30
29
|
public target?: HTMLElement;
|
|
31
30
|
public moveable?: Moveable;
|
|
32
|
-
public
|
|
31
|
+
public targetShadow: TargetShadow;
|
|
32
|
+
private getRootContainer: GetRootContainer;
|
|
33
33
|
|
|
34
34
|
constructor(config: StageHighlightConfig) {
|
|
35
35
|
super();
|
|
36
36
|
|
|
37
|
-
this.core = config.core;
|
|
38
37
|
this.container = config.container;
|
|
39
|
-
this.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
this.getRootContainer = config.getRootContainer;
|
|
39
|
+
|
|
40
|
+
this.targetShadow = new TargetShadow({
|
|
41
|
+
container: config.container,
|
|
42
|
+
updateDragEl: config.updateDragEl,
|
|
43
|
+
zIndex: ZIndex.HIGHLIGHT_EL,
|
|
44
|
+
idPrefix: HIGHLIGHT_EL_ID_PREFIX,
|
|
44
45
|
});
|
|
45
46
|
}
|
|
46
47
|
|
|
@@ -54,9 +55,9 @@ export default class StageHighlight extends EventEmitter {
|
|
|
54
55
|
this.moveable?.destroy();
|
|
55
56
|
|
|
56
57
|
this.moveable = new Moveable(this.container, {
|
|
57
|
-
target: this.
|
|
58
|
+
target: this.targetShadow.update(el),
|
|
58
59
|
origin: false,
|
|
59
|
-
rootContainer: this.
|
|
60
|
+
rootContainer: this.getRootContainer(),
|
|
60
61
|
zoom: 2,
|
|
61
62
|
});
|
|
62
63
|
}
|
|
@@ -65,7 +66,7 @@ export default class StageHighlight extends EventEmitter {
|
|
|
65
66
|
* 清空高亮
|
|
66
67
|
*/
|
|
67
68
|
public clearHighlight(): void {
|
|
68
|
-
if (!this.moveable) return;
|
|
69
|
+
if (!this.moveable || !this.target) return;
|
|
69
70
|
this.target = undefined;
|
|
70
71
|
this.moveable.target = null;
|
|
71
72
|
this.moveable.updateTarget();
|
|
@@ -76,6 +77,6 @@ export default class StageHighlight extends EventEmitter {
|
|
|
76
77
|
*/
|
|
77
78
|
public destroy(): void {
|
|
78
79
|
this.moveable?.destroy();
|
|
79
|
-
this.
|
|
80
|
+
this.targetShadow.destroy();
|
|
80
81
|
}
|
|
81
82
|
}
|