@tmagic/stage 1.0.0-beta.9 → 1.0.0-rc.11
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 +1 -0
- package/dist/tmagic-stage.es.js +516 -297
- package/dist/tmagic-stage.es.js.map +1 -1
- package/dist/tmagic-stage.umd.js +517 -299
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/dist/types/src/StageCore.d.ts +4 -4
- package/dist/types/src/StageDragResize.d.ts +21 -7
- package/dist/types/src/StageHighlight.d.ts +2 -0
- package/dist/types/src/StageMask.d.ts +18 -0
- package/dist/types/src/TargetCalibrate.d.ts +20 -0
- package/dist/types/src/const.d.ts +26 -1
- package/dist/types/src/types.d.ts +22 -6
- package/dist/types/src/util.d.ts +3 -2
- package/package.json +12 -8
- package/src/Rule.ts +13 -5
- package/src/StageCore.ts +43 -23
- package/src/StageDragResize.ts +214 -98
- package/src/StageHighlight.ts +16 -1
- package/src/StageMask.ts +93 -27
- package/src/StageRender.ts +4 -16
- package/src/TargetCalibrate.ts +119 -0
- package/src/const.ts +28 -2
- package/src/types.ts +23 -6
- package/src/util.ts +40 -29
- package/LICENSE +0 -5432
- package/tsconfig.json +0 -9
- package/vite.config.ts +0 -27
package/src/StageDragResize.ts
CHANGED
|
@@ -23,14 +23,18 @@ import type { MoveableOptions } from 'moveable';
|
|
|
23
23
|
import Moveable from 'moveable';
|
|
24
24
|
import MoveableHelper from 'moveable-helper';
|
|
25
25
|
|
|
26
|
-
import { GHOST_EL_ID_PREFIX, GuidesType, Mode } from './const';
|
|
26
|
+
import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, Mode, ZIndex } from './const';
|
|
27
27
|
import StageCore from './StageCore';
|
|
28
28
|
import type { SortEventData, StageDragResizeConfig } from './types';
|
|
29
|
-
import { getAbsolutePosition, getMode, getOffset } from './util';
|
|
29
|
+
import { getAbsolutePosition, getGuideLineFromCache, getMode, getOffset } from './util';
|
|
30
30
|
|
|
31
|
+
/** 拖动状态 */
|
|
31
32
|
enum ActionStatus {
|
|
33
|
+
/** 开始拖动 */
|
|
32
34
|
START = 'start',
|
|
35
|
+
/** 拖动中 */
|
|
33
36
|
ING = 'ing',
|
|
37
|
+
/** 拖动结束 */
|
|
34
38
|
END = 'end',
|
|
35
39
|
}
|
|
36
40
|
|
|
@@ -39,17 +43,28 @@ enum ActionStatus {
|
|
|
39
43
|
*/
|
|
40
44
|
export default class StageDragResize extends EventEmitter {
|
|
41
45
|
public core: StageCore;
|
|
46
|
+
/** 画布容器 */
|
|
42
47
|
public container: HTMLElement;
|
|
48
|
+
/** 目标节点 */
|
|
43
49
|
public target?: HTMLElement;
|
|
44
|
-
|
|
50
|
+
/** 目标节点在蒙层中的占位节点 */
|
|
51
|
+
public dragEl: HTMLDivElement;
|
|
52
|
+
/** Moveable拖拽类实例 */
|
|
45
53
|
public moveable?: Moveable;
|
|
46
|
-
|
|
47
|
-
public
|
|
54
|
+
/** 水平参考线 */
|
|
55
|
+
public horizontalGuidelines: number[] = getGuideLineFromCache(GuidesType.HORIZONTAL);
|
|
56
|
+
/** 垂直参考线 */
|
|
57
|
+
public verticalGuidelines: number[] = getGuideLineFromCache(GuidesType.VERTICAL);
|
|
58
|
+
/** 对齐元素集合 */
|
|
59
|
+
public elementGuidelines: HTMLElement[] = [];
|
|
60
|
+
/** 布局方式:流式布局、绝对定位、固定定位 */
|
|
61
|
+
public mode: Mode = Mode.ABSOLUTE;
|
|
48
62
|
|
|
49
63
|
private moveableOptions: MoveableOptions = {};
|
|
64
|
+
/** 拖动状态 */
|
|
50
65
|
private dragStatus: ActionStatus = ActionStatus.END;
|
|
66
|
+
/** 流式布局下,目标节点的镜像节点 */
|
|
51
67
|
private ghostEl: HTMLElement | undefined;
|
|
52
|
-
private mode: Mode = Mode.ABSOLUTE;
|
|
53
68
|
private moveableHelper?: MoveableHelper;
|
|
54
69
|
|
|
55
70
|
constructor(config: StageDragResizeConfig) {
|
|
@@ -57,6 +72,9 @@ export default class StageDragResize extends EventEmitter {
|
|
|
57
72
|
|
|
58
73
|
this.core = config.core;
|
|
59
74
|
this.container = config.container;
|
|
75
|
+
|
|
76
|
+
this.dragEl = globalThis.document.createElement('div');
|
|
77
|
+
this.container.append(this.dragEl);
|
|
60
78
|
}
|
|
61
79
|
|
|
62
80
|
/**
|
|
@@ -65,29 +83,23 @@ export default class StageDragResize extends EventEmitter {
|
|
|
65
83
|
* @param el 选中组件的Dom节点元素
|
|
66
84
|
* @param event 鼠标事件
|
|
67
85
|
*/
|
|
68
|
-
public
|
|
86
|
+
public select(el: HTMLElement, event?: MouseEvent): void {
|
|
87
|
+
const oldTarget = this.target;
|
|
69
88
|
this.target = el;
|
|
70
|
-
// 如果有滚动条会导致resize时获取到width,height不准确
|
|
71
|
-
if (/(auto|scroll)/.test(this.target.style.overflow)) {
|
|
72
|
-
this.target.style.overflow = 'hidden';
|
|
73
|
-
}
|
|
74
|
-
this.mode = getMode(el);
|
|
75
|
-
this.destroyDragEl();
|
|
76
|
-
this.destroyGhostEl();
|
|
77
89
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
useRender: false,
|
|
87
|
-
createAuto: true,
|
|
88
|
-
});
|
|
90
|
+
// 从不能拖动到能拖动的节点之间切换,要重新创建moveable,不然dragStart不生效
|
|
91
|
+
if (!this.moveable || this.target !== oldTarget) {
|
|
92
|
+
this.init(el);
|
|
93
|
+
this.moveableHelper = MoveableHelper.create({
|
|
94
|
+
useBeforeRender: true,
|
|
95
|
+
useRender: false,
|
|
96
|
+
createAuto: true,
|
|
97
|
+
});
|
|
89
98
|
|
|
90
|
-
|
|
99
|
+
this.initMoveable();
|
|
100
|
+
} else {
|
|
101
|
+
this.updateMoveable();
|
|
102
|
+
}
|
|
91
103
|
|
|
92
104
|
if (event) {
|
|
93
105
|
this.moveable?.dragStart(event);
|
|
@@ -97,11 +109,15 @@ export default class StageDragResize extends EventEmitter {
|
|
|
97
109
|
/**
|
|
98
110
|
* 初始化选中框并渲染出来
|
|
99
111
|
*/
|
|
100
|
-
public
|
|
112
|
+
public updateMoveable(el = this.target): void {
|
|
101
113
|
if (!this.moveable) throw new Error('未初始化moveable');
|
|
114
|
+
if (!el) throw new Error('为选中任何节点');
|
|
115
|
+
|
|
116
|
+
this.target = el;
|
|
102
117
|
|
|
103
|
-
|
|
104
|
-
|
|
118
|
+
this.init(el);
|
|
119
|
+
|
|
120
|
+
Object.entries(this.moveableOptions).forEach(([key, value]) => {
|
|
105
121
|
(this.moveable as any)[key] = value;
|
|
106
122
|
});
|
|
107
123
|
this.moveable.updateTarget();
|
|
@@ -110,17 +126,21 @@ export default class StageDragResize extends EventEmitter {
|
|
|
110
126
|
public setGuidelines(type: GuidesType, guidelines: number[]): void {
|
|
111
127
|
if (type === GuidesType.HORIZONTAL) {
|
|
112
128
|
this.horizontalGuidelines = guidelines;
|
|
129
|
+
this.moveableOptions.horizontalGuidelines = guidelines;
|
|
113
130
|
} else if (type === GuidesType.VERTICAL) {
|
|
114
131
|
this.verticalGuidelines = guidelines;
|
|
132
|
+
this.moveableOptions.verticalGuidelines = guidelines;
|
|
115
133
|
}
|
|
116
134
|
|
|
117
|
-
this.
|
|
135
|
+
this.updateMoveable();
|
|
118
136
|
}
|
|
119
137
|
|
|
120
138
|
public clearGuides() {
|
|
121
|
-
this.verticalGuidelines = [];
|
|
122
139
|
this.horizontalGuidelines = [];
|
|
123
|
-
this.
|
|
140
|
+
this.verticalGuidelines = [];
|
|
141
|
+
this.moveableOptions.horizontalGuidelines = [];
|
|
142
|
+
this.moveableOptions.verticalGuidelines = [];
|
|
143
|
+
this.updateMoveable();
|
|
124
144
|
}
|
|
125
145
|
|
|
126
146
|
/**
|
|
@@ -134,6 +154,45 @@ export default class StageDragResize extends EventEmitter {
|
|
|
134
154
|
this.removeAllListeners();
|
|
135
155
|
}
|
|
136
156
|
|
|
157
|
+
private init(el: HTMLElement): void {
|
|
158
|
+
// 如果有滚动条会导致resize时获取到width,height不准确
|
|
159
|
+
if (/(auto|scroll)/.test(el.style.overflow)) {
|
|
160
|
+
el.style.overflow = 'hidden';
|
|
161
|
+
}
|
|
162
|
+
this.mode = getMode(el);
|
|
163
|
+
|
|
164
|
+
this.destroyGhostEl();
|
|
165
|
+
|
|
166
|
+
this.updateDragEl(el);
|
|
167
|
+
|
|
168
|
+
this.moveableOptions = this.getOptions({
|
|
169
|
+
target: this.dragEl,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private setElementGuidelines(nodes: HTMLElement[]) {
|
|
174
|
+
this.elementGuidelines.forEach((node) => {
|
|
175
|
+
node.remove();
|
|
176
|
+
});
|
|
177
|
+
this.elementGuidelines = [];
|
|
178
|
+
|
|
179
|
+
if (this.mode === Mode.ABSOLUTE) {
|
|
180
|
+
const frame = document.createDocumentFragment();
|
|
181
|
+
|
|
182
|
+
for (const node of nodes) {
|
|
183
|
+
const { width, height } = node.getBoundingClientRect();
|
|
184
|
+
if (node === this.target) continue;
|
|
185
|
+
const { left, top } = getOffset(node as HTMLElement);
|
|
186
|
+
const elementGuideline = document.createElement('div');
|
|
187
|
+
elementGuideline.style.cssText = `position: absolute;width: ${width}px;height: ${height}px;top: ${top}px;left: ${left}px`;
|
|
188
|
+
this.elementGuidelines.push(elementGuideline);
|
|
189
|
+
frame.append(elementGuideline);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
this.container.append(frame);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
137
196
|
private initMoveable() {
|
|
138
197
|
this.moveable?.destroy();
|
|
139
198
|
|
|
@@ -143,49 +202,47 @@ export default class StageDragResize extends EventEmitter {
|
|
|
143
202
|
|
|
144
203
|
this.bindResizeEvent();
|
|
145
204
|
this.bindDragEvent();
|
|
205
|
+
this.bindRotateEvent();
|
|
206
|
+
this.bindScaleEvent();
|
|
146
207
|
}
|
|
147
208
|
|
|
148
209
|
private bindResizeEvent(): void {
|
|
149
210
|
if (!this.moveable) throw new Error('moveable 为初始化');
|
|
150
211
|
|
|
151
212
|
const frame = {
|
|
152
|
-
|
|
213
|
+
left: 0,
|
|
214
|
+
top: 0,
|
|
153
215
|
};
|
|
154
216
|
|
|
155
217
|
this.moveable
|
|
156
218
|
.on('resizeStart', (e) => {
|
|
157
|
-
if (
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
219
|
+
if (!this.target) return;
|
|
220
|
+
|
|
221
|
+
this.dragStatus = ActionStatus.START;
|
|
222
|
+
this.moveableHelper?.onResizeStart(e);
|
|
223
|
+
|
|
224
|
+
frame.top = this.target.offsetTop;
|
|
225
|
+
frame.left = this.target.offsetLeft;
|
|
162
226
|
})
|
|
163
|
-
.on('resize', (
|
|
227
|
+
.on('resize', (e) => {
|
|
228
|
+
const { width, height, drag } = e;
|
|
164
229
|
if (!this.moveable || !this.target || !this.dragEl) return;
|
|
165
230
|
|
|
166
231
|
const { beforeTranslate } = drag;
|
|
167
|
-
frame.translate = beforeTranslate;
|
|
168
232
|
this.dragStatus = ActionStatus.ING;
|
|
169
233
|
|
|
170
|
-
this.
|
|
171
|
-
this.target.style.height = `${height}px`;
|
|
172
|
-
this.dragEl.style.width = `${width}px`;
|
|
173
|
-
this.dragEl.style.height = `${height}px`;
|
|
234
|
+
this.moveableHelper?.onResize(e);
|
|
174
235
|
|
|
175
236
|
// 流式布局
|
|
176
237
|
if (this.mode === Mode.SORTABLE) {
|
|
177
|
-
this.
|
|
178
|
-
|
|
179
|
-
|
|
238
|
+
this.target.style.top = '0px';
|
|
239
|
+
} else {
|
|
240
|
+
this.target.style.left = `${frame.left + beforeTranslate[0]}px`;
|
|
241
|
+
this.target.style.top = `${frame.top + beforeTranslate[1]}px`;
|
|
180
242
|
}
|
|
181
243
|
|
|
182
|
-
this.
|
|
183
|
-
this.
|
|
184
|
-
|
|
185
|
-
const offset = getAbsolutePosition(this.target, { left: beforeTranslate[0], top: beforeTranslate[1] });
|
|
186
|
-
|
|
187
|
-
this.target.style.left = `${offset.left}px`;
|
|
188
|
-
this.target.style.top = `${offset.top}px`;
|
|
244
|
+
this.target.style.width = `${width}px`;
|
|
245
|
+
this.target.style.height = `${height}px`;
|
|
189
246
|
})
|
|
190
247
|
.on('resizeEnd', () => {
|
|
191
248
|
this.dragStatus = ActionStatus.END;
|
|
@@ -196,7 +253,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
196
253
|
private bindDragEvent(): void {
|
|
197
254
|
if (!this.moveable) throw new Error('moveable 为初始化');
|
|
198
255
|
|
|
199
|
-
|
|
256
|
+
const frame = {
|
|
200
257
|
left: 0,
|
|
201
258
|
top: 0,
|
|
202
259
|
};
|
|
@@ -209,29 +266,28 @@ export default class StageDragResize extends EventEmitter {
|
|
|
209
266
|
|
|
210
267
|
this.moveableHelper?.onDragStart(e);
|
|
211
268
|
|
|
212
|
-
offset = getAbsolutePosition(this.target, { left: 0, top: 0 });
|
|
213
|
-
|
|
214
269
|
if (this.mode === Mode.SORTABLE) {
|
|
215
270
|
this.ghostEl = this.generateGhostEl(this.target);
|
|
216
271
|
}
|
|
272
|
+
|
|
273
|
+
frame.top = this.target.offsetTop;
|
|
274
|
+
frame.left = this.target.offsetLeft;
|
|
217
275
|
})
|
|
218
276
|
.on('drag', (e) => {
|
|
219
277
|
if (!this.target || !this.dragEl) return;
|
|
220
|
-
this.dragStatus = ActionStatus.ING;
|
|
221
278
|
|
|
222
|
-
|
|
279
|
+
this.dragStatus = ActionStatus.ING;
|
|
223
280
|
|
|
224
281
|
// 流式布局
|
|
225
282
|
if (this.ghostEl) {
|
|
226
|
-
this.
|
|
227
|
-
this.ghostEl.style.top = `${top + offset.top}px`;
|
|
283
|
+
this.ghostEl.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
228
284
|
return;
|
|
229
285
|
}
|
|
230
286
|
|
|
231
287
|
this.moveableHelper?.onDrag(e);
|
|
232
288
|
|
|
233
|
-
this.target.style.left = `${left +
|
|
234
|
-
this.target.style.top = `${top +
|
|
289
|
+
this.target.style.left = `${frame.left + e.beforeTranslate[0]}px`;
|
|
290
|
+
this.target.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
235
291
|
})
|
|
236
292
|
.on('dragEnd', () => {
|
|
237
293
|
// 点击不拖动时会触发dragStart和dragEnd,但是不会有drag事件
|
|
@@ -250,19 +306,58 @@ export default class StageDragResize extends EventEmitter {
|
|
|
250
306
|
});
|
|
251
307
|
}
|
|
252
308
|
|
|
253
|
-
private
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
(() => {
|
|
258
|
-
|
|
259
|
-
|
|
309
|
+
private bindRotateEvent(): void {
|
|
310
|
+
if (!this.moveable) throw new Error('moveable 为初始化');
|
|
311
|
+
|
|
312
|
+
this.moveable
|
|
313
|
+
.on('rotateStart', (e) => {
|
|
314
|
+
this.dragStatus = ActionStatus.START;
|
|
315
|
+
this.moveableHelper?.onRotateStart(e);
|
|
316
|
+
})
|
|
317
|
+
.on('rotate', (e) => {
|
|
318
|
+
if (!this.target || !this.dragEl) return;
|
|
319
|
+
this.dragStatus = ActionStatus.ING;
|
|
320
|
+
this.moveableHelper?.onRotate(e);
|
|
321
|
+
const frame = this.moveableHelper?.getFrame(e.target);
|
|
322
|
+
this.target.style.transform = frame?.toCSSObject().transform || '';
|
|
323
|
+
})
|
|
324
|
+
.on('rotateEnd', (e) => {
|
|
325
|
+
this.dragStatus = ActionStatus.END;
|
|
326
|
+
const frame = this.moveableHelper?.getFrame(e.target);
|
|
327
|
+
this.emit('update', {
|
|
328
|
+
el: this.target,
|
|
329
|
+
style: {
|
|
330
|
+
transform: frame?.get('transform'),
|
|
331
|
+
},
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
private bindScaleEvent(): void {
|
|
337
|
+
if (!this.moveable) throw new Error('moveable 为初始化');
|
|
338
|
+
|
|
339
|
+
this.moveable
|
|
340
|
+
.on('scaleStart', (e) => {
|
|
341
|
+
this.dragStatus = ActionStatus.START;
|
|
342
|
+
this.moveableHelper?.onScaleStart(e);
|
|
343
|
+
})
|
|
344
|
+
.on('scale', (e) => {
|
|
345
|
+
if (!this.target || !this.dragEl) return;
|
|
346
|
+
this.dragStatus = ActionStatus.ING;
|
|
347
|
+
this.moveableHelper?.onScale(e);
|
|
348
|
+
const frame = this.moveableHelper?.getFrame(e.target);
|
|
349
|
+
this.target.style.transform = frame?.toCSSObject().transform || '';
|
|
350
|
+
})
|
|
351
|
+
.on('scaleEnd', (e) => {
|
|
352
|
+
this.dragStatus = ActionStatus.END;
|
|
353
|
+
const frame = this.moveableHelper?.getFrame(e.target);
|
|
354
|
+
this.emit('update', {
|
|
355
|
+
el: this.target,
|
|
356
|
+
style: {
|
|
357
|
+
transform: frame?.get('transform'),
|
|
358
|
+
},
|
|
359
|
+
});
|
|
260
360
|
});
|
|
261
|
-
return (
|
|
262
|
-
getSnapElements(el)
|
|
263
|
-
// 排除掉当前组件本身
|
|
264
|
-
.filter((element) => element !== this.target && !this.target?.contains(element))
|
|
265
|
-
);
|
|
266
361
|
}
|
|
267
362
|
|
|
268
363
|
private sort(): void {
|
|
@@ -285,14 +380,15 @@ export default class StageDragResize extends EventEmitter {
|
|
|
285
380
|
}
|
|
286
381
|
|
|
287
382
|
private update(isResize = false): void {
|
|
288
|
-
|
|
383
|
+
if (!this.target) return;
|
|
384
|
+
|
|
289
385
|
const offset =
|
|
290
|
-
this.mode === Mode.SORTABLE ? { left: 0, top: 0 } :
|
|
386
|
+
this.mode === Mode.SORTABLE ? { left: 0, top: 0 } : { left: this.target.offsetLeft, top: this.target.offsetTop };
|
|
291
387
|
|
|
292
388
|
const left = this.calcValueByFontsize(offset.left);
|
|
293
389
|
const top = this.calcValueByFontsize(offset.top);
|
|
294
|
-
const width = this.calcValueByFontsize(
|
|
295
|
-
const height = this.calcValueByFontsize(
|
|
390
|
+
const width = this.calcValueByFontsize(this.target.clientWidth);
|
|
391
|
+
const height = this.calcValueByFontsize(this.target.clientHeight);
|
|
296
392
|
|
|
297
393
|
this.emit('update', {
|
|
298
394
|
el: this.target,
|
|
@@ -307,8 +403,8 @@ export default class StageDragResize extends EventEmitter {
|
|
|
307
403
|
|
|
308
404
|
const ghostEl = el.cloneNode(true) as HTMLElement;
|
|
309
405
|
const { top, left } = getAbsolutePosition(el, getOffset(el));
|
|
310
|
-
ghostEl.id = `${GHOST_EL_ID_PREFIX}${
|
|
311
|
-
ghostEl.style.zIndex =
|
|
406
|
+
ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
|
|
407
|
+
ghostEl.style.zIndex = ZIndex.GHOST_EL;
|
|
312
408
|
ghostEl.style.opacity = '.5';
|
|
313
409
|
ghostEl.style.position = 'absolute';
|
|
314
410
|
ghostEl.style.left = `${left}px`;
|
|
@@ -322,34 +418,36 @@ export default class StageDragResize extends EventEmitter {
|
|
|
322
418
|
this.ghostEl = undefined;
|
|
323
419
|
}
|
|
324
420
|
|
|
325
|
-
private
|
|
326
|
-
if (this.dragEl) {
|
|
327
|
-
this.destroyDragEl();
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
const { width, height } = el.getBoundingClientRect();
|
|
421
|
+
private updateDragEl(el: HTMLElement) {
|
|
331
422
|
const offset = getOffset(el);
|
|
332
|
-
const
|
|
333
|
-
|
|
423
|
+
const { transform } = getComputedStyle(el);
|
|
424
|
+
|
|
425
|
+
this.dragEl.style.cssText = `
|
|
334
426
|
position: absolute;
|
|
427
|
+
transform: ${transform};
|
|
335
428
|
left: ${offset.left}px;
|
|
336
429
|
top: ${offset.top}px;
|
|
337
|
-
width: ${
|
|
338
|
-
height: ${
|
|
430
|
+
width: ${el.clientWidth}px;
|
|
431
|
+
height: ${el.clientHeight}px;
|
|
432
|
+
z-index: ${ZIndex.DRAG_EL};
|
|
339
433
|
`;
|
|
340
|
-
|
|
341
|
-
|
|
434
|
+
|
|
435
|
+
this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
|
|
436
|
+
|
|
437
|
+
if (typeof this.core.config.updateDragEl === 'function') {
|
|
438
|
+
this.core.config.updateDragEl(this.dragEl, el);
|
|
439
|
+
}
|
|
342
440
|
}
|
|
343
441
|
|
|
344
442
|
private destroyDragEl(): void {
|
|
345
443
|
this.dragEl?.remove();
|
|
346
|
-
this.dragEl = undefined;
|
|
347
444
|
}
|
|
348
445
|
|
|
349
|
-
private
|
|
446
|
+
private getOptions(options: MoveableOptions = {}): MoveableOptions {
|
|
350
447
|
if (!this.target) return {};
|
|
351
448
|
|
|
352
449
|
const isAbsolute = this.mode === Mode.ABSOLUTE;
|
|
450
|
+
const isFixed = this.mode === Mode.FIXED;
|
|
353
451
|
|
|
354
452
|
let { moveableOptions = {} } = this.core.config;
|
|
355
453
|
|
|
@@ -357,15 +455,25 @@ export default class StageDragResize extends EventEmitter {
|
|
|
357
455
|
moveableOptions = moveableOptions(this.core);
|
|
358
456
|
}
|
|
359
457
|
|
|
458
|
+
const elementGuidelines: any = moveableOptions.elementGuidelines || this.target.parentElement?.children || [];
|
|
459
|
+
|
|
460
|
+
this.setElementGuidelines(elementGuidelines);
|
|
461
|
+
|
|
462
|
+
if (moveableOptions.elementGuidelines) {
|
|
463
|
+
delete moveableOptions.elementGuidelines;
|
|
464
|
+
}
|
|
465
|
+
|
|
360
466
|
return {
|
|
361
|
-
origin:
|
|
467
|
+
origin: false,
|
|
362
468
|
rootContainer: this.core.container,
|
|
363
469
|
zoom: 1,
|
|
364
470
|
dragArea: false,
|
|
365
471
|
draggable: true,
|
|
366
472
|
resizable: true,
|
|
367
|
-
|
|
368
|
-
|
|
473
|
+
scalable: false,
|
|
474
|
+
rotatable: false,
|
|
475
|
+
snappable: isAbsolute || isFixed,
|
|
476
|
+
snapGap: isAbsolute || isFixed,
|
|
369
477
|
snapThreshold: 5,
|
|
370
478
|
snapDigit: 0,
|
|
371
479
|
throttleDrag: 0,
|
|
@@ -378,8 +486,16 @@ export default class StageDragResize extends EventEmitter {
|
|
|
378
486
|
center: isAbsolute,
|
|
379
487
|
middle: isAbsolute,
|
|
380
488
|
},
|
|
489
|
+
elementSnapDirections: {
|
|
490
|
+
top: isAbsolute,
|
|
491
|
+
right: isAbsolute,
|
|
492
|
+
bottom: isAbsolute,
|
|
493
|
+
left: isAbsolute,
|
|
494
|
+
},
|
|
495
|
+
isDisplayInnerSnapDigit: true,
|
|
381
496
|
horizontalGuidelines: this.horizontalGuidelines,
|
|
382
497
|
verticalGuidelines: this.verticalGuidelines,
|
|
498
|
+
elementGuidelines: this.elementGuidelines,
|
|
383
499
|
|
|
384
500
|
bounds: {
|
|
385
501
|
top: 0,
|
package/src/StageHighlight.ts
CHANGED
|
@@ -21,19 +21,28 @@ import { EventEmitter } from 'events';
|
|
|
21
21
|
|
|
22
22
|
import Moveable from 'moveable';
|
|
23
23
|
|
|
24
|
+
import { HIGHLIGHT_EL_ID_PREFIX } from './const';
|
|
24
25
|
import StageCore from './StageCore';
|
|
26
|
+
import TargetCalibrate from './TargetCalibrate';
|
|
25
27
|
import type { StageHighlightConfig } from './types';
|
|
26
28
|
export default class StageHighlight extends EventEmitter {
|
|
27
29
|
public core: StageCore;
|
|
28
30
|
public container: HTMLElement;
|
|
29
31
|
public target?: HTMLElement;
|
|
30
32
|
public moveable?: Moveable;
|
|
33
|
+
public calibrationTarget: TargetCalibrate;
|
|
31
34
|
|
|
32
35
|
constructor(config: StageHighlightConfig) {
|
|
33
36
|
super();
|
|
34
37
|
|
|
35
38
|
this.core = config.core;
|
|
36
39
|
this.container = config.container;
|
|
40
|
+
this.calibrationTarget = new TargetCalibrate({
|
|
41
|
+
parent: this.core.mask.content,
|
|
42
|
+
mask: this.core.mask,
|
|
43
|
+
dr: this.core.dr,
|
|
44
|
+
core: this.core,
|
|
45
|
+
});
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
/**
|
|
@@ -44,8 +53,12 @@ export default class StageHighlight extends EventEmitter {
|
|
|
44
53
|
if (!el || el === this.target) return;
|
|
45
54
|
this.target = el;
|
|
46
55
|
this.moveable?.destroy();
|
|
56
|
+
|
|
47
57
|
this.moveable = new Moveable(this.container, {
|
|
48
|
-
target: this.
|
|
58
|
+
target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
|
|
59
|
+
origin: false,
|
|
60
|
+
rootContainer: this.core.container,
|
|
61
|
+
zoom: 1,
|
|
49
62
|
});
|
|
50
63
|
}
|
|
51
64
|
|
|
@@ -54,6 +67,7 @@ export default class StageHighlight extends EventEmitter {
|
|
|
54
67
|
*/
|
|
55
68
|
public clearHighlight(): void {
|
|
56
69
|
if (!this.moveable) return;
|
|
70
|
+
this.target = undefined;
|
|
57
71
|
this.moveable.target = null;
|
|
58
72
|
this.moveable.updateTarget();
|
|
59
73
|
}
|
|
@@ -63,5 +77,6 @@ export default class StageHighlight extends EventEmitter {
|
|
|
63
77
|
*/
|
|
64
78
|
public destroy(): void {
|
|
65
79
|
this.moveable?.destroy();
|
|
80
|
+
this.calibrationTarget.destroy();
|
|
66
81
|
}
|
|
67
82
|
}
|