@tmagic/stage 1.1.0-beta.6 → 1.1.0-beta.9
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/dist/tmagic-stage.mjs +107 -39
- package/dist/tmagic-stage.mjs.map +1 -1
- package/dist/tmagic-stage.umd.js +112 -42
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/package.json +4 -4
- package/src/StageCore.ts +20 -8
- package/src/StageDragResize.ts +49 -29
- package/src/StageMask.ts +7 -2
- package/src/StageMultiDragResize.ts +44 -15
- package/src/types.ts +32 -14
- package/types/StageCore.d.ts +2 -1
- package/types/StageDragResize.d.ts +2 -0
- package/types/StageMultiDragResize.d.ts +4 -2
- package/types/types.d.ts +30 -14
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.1.0-beta.
|
|
2
|
+
"version": "1.1.0-beta.9",
|
|
3
3
|
"name": "@tmagic/stage",
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"dist/*"
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@scena/guides": "^0.17.0",
|
|
32
|
-
"@tmagic/core": "1.1.0-beta.
|
|
33
|
-
"@tmagic/schema": "1.1.0-beta.
|
|
34
|
-
"@tmagic/utils": "1.1.0-beta.
|
|
32
|
+
"@tmagic/core": "1.1.0-beta.9",
|
|
33
|
+
"@tmagic/schema": "1.1.0-beta.9",
|
|
34
|
+
"@tmagic/utils": "1.1.0-beta.9",
|
|
35
35
|
"events": "^3.3.0",
|
|
36
36
|
"keycon": "^1.1.2",
|
|
37
37
|
"lodash-es": "^4.17.21",
|
package/src/StageCore.ts
CHANGED
|
@@ -21,7 +21,7 @@ import { EventEmitter } from 'events';
|
|
|
21
21
|
import type { Id } from '@tmagic/schema';
|
|
22
22
|
import { addClassName } from '@tmagic/utils';
|
|
23
23
|
|
|
24
|
-
import { DEFAULT_ZOOM, GHOST_EL_ID_PREFIX, PAGE_CLASS } from './const';
|
|
24
|
+
import { CONTAINER_HIGHLIGHT_CLASS, DEFAULT_ZOOM, GHOST_EL_ID_PREFIX, PAGE_CLASS } from './const';
|
|
25
25
|
import StageDragResize from './StageDragResize';
|
|
26
26
|
import StageHighlight from './StageHighlight';
|
|
27
27
|
import StageMask from './StageMask';
|
|
@@ -29,12 +29,14 @@ import StageMultiDragResize from './StageMultiDragResize';
|
|
|
29
29
|
import StageRender from './StageRender';
|
|
30
30
|
import {
|
|
31
31
|
CanSelect,
|
|
32
|
+
ContainerHighlightType,
|
|
32
33
|
GuidesEventData,
|
|
33
34
|
IsContainer,
|
|
34
35
|
RemoveData,
|
|
35
36
|
Runtime,
|
|
36
37
|
SortEventData,
|
|
37
38
|
StageCoreConfig,
|
|
39
|
+
StageDragStatus,
|
|
38
40
|
UpdateData,
|
|
39
41
|
UpdateEventData,
|
|
40
42
|
} from './types';
|
|
@@ -56,6 +58,7 @@ export default class StageCore extends EventEmitter {
|
|
|
56
58
|
public zoom = DEFAULT_ZOOM;
|
|
57
59
|
public containerHighlightClassName: string;
|
|
58
60
|
public containerHighlightDuration: number;
|
|
61
|
+
public containerHighlightType?: ContainerHighlightType;
|
|
59
62
|
public isContainer: IsContainer;
|
|
60
63
|
|
|
61
64
|
private canSelect: CanSelect;
|
|
@@ -68,8 +71,9 @@ export default class StageCore extends EventEmitter {
|
|
|
68
71
|
this.setZoom(config.zoom);
|
|
69
72
|
this.canSelect = config.canSelect || ((el: HTMLElement) => !!el.id);
|
|
70
73
|
this.isContainer = config.isContainer;
|
|
71
|
-
this.containerHighlightClassName = config.containerHighlightClassName;
|
|
72
|
-
this.containerHighlightDuration = config.containerHighlightDuration;
|
|
74
|
+
this.containerHighlightClassName = config.containerHighlightClassName || CONTAINER_HIGHLIGHT_CLASS;
|
|
75
|
+
this.containerHighlightDuration = config.containerHighlightDuration || 800;
|
|
76
|
+
this.containerHighlightType = config.containerHighlightType;
|
|
73
77
|
|
|
74
78
|
this.renderer = new StageRender({ core: this });
|
|
75
79
|
this.mask = new StageMask({ core: this });
|
|
@@ -101,6 +105,8 @@ export default class StageCore extends EventEmitter {
|
|
|
101
105
|
.on('highlight', async (event: MouseEvent) => {
|
|
102
106
|
const el = await this.getElementFromPoint(event);
|
|
103
107
|
if (!el) return;
|
|
108
|
+
// 如果多选组件处于拖拽状态时不进行组件高亮
|
|
109
|
+
if (this.multiDr.dragStatus === StageDragStatus.ING) return;
|
|
104
110
|
await this.highlight(el);
|
|
105
111
|
if (this.highlightedDom === this.selectedDom) {
|
|
106
112
|
this.highlightLayer.clearHighlight();
|
|
@@ -139,9 +145,15 @@ export default class StageCore extends EventEmitter {
|
|
|
139
145
|
setTimeout(() => this.emit('sort', data));
|
|
140
146
|
});
|
|
141
147
|
|
|
142
|
-
this.multiDr
|
|
143
|
-
|
|
144
|
-
|
|
148
|
+
this.multiDr
|
|
149
|
+
.on('update', (data: UpdateEventData) => {
|
|
150
|
+
setTimeout(() => this.emit('update', data));
|
|
151
|
+
})
|
|
152
|
+
.on('select', async (id: Id) => {
|
|
153
|
+
const el = await this.getTargetElement(id);
|
|
154
|
+
this.select(el); // 选中
|
|
155
|
+
setTimeout(() => this.emit('select', el)); // set node
|
|
156
|
+
});
|
|
145
157
|
}
|
|
146
158
|
|
|
147
159
|
public getElementsFromPoint(event: MouseEvent) {
|
|
@@ -180,7 +192,7 @@ export default class StageCore extends EventEmitter {
|
|
|
180
192
|
if (!canSelectByProp) return false;
|
|
181
193
|
// 多选规则
|
|
182
194
|
if (this.mask.isMultiSelectStatus) {
|
|
183
|
-
return this.multiDr.canSelect(el);
|
|
195
|
+
return this.multiDr.canSelect(el, stop);
|
|
184
196
|
}
|
|
185
197
|
return true;
|
|
186
198
|
}
|
|
@@ -337,7 +349,7 @@ export default class StageCore extends EventEmitter {
|
|
|
337
349
|
}
|
|
338
350
|
}
|
|
339
351
|
|
|
340
|
-
public getAddContainerHighlightClassNameTimeout(event: MouseEvent, exclude: Element[] = []) {
|
|
352
|
+
public getAddContainerHighlightClassNameTimeout(event: MouseEvent, exclude: Element[] = []): NodeJS.Timeout {
|
|
341
353
|
return globalThis.setTimeout(() => {
|
|
342
354
|
this.addContainerHighlightClassName(event, exclude);
|
|
343
355
|
}, this.containerHighlightDuration);
|
package/src/StageDragResize.ts
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
/* eslint-disable no-param-reassign */
|
|
20
20
|
import { EventEmitter } from 'events';
|
|
21
21
|
|
|
22
|
+
import KeyController from 'keycon';
|
|
22
23
|
import type { MoveableOptions } from 'moveable';
|
|
23
24
|
import Moveable from 'moveable';
|
|
24
25
|
import MoveableHelper from 'moveable-helper';
|
|
@@ -29,18 +30,9 @@ import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, Mode, ZIndex } from
|
|
|
29
30
|
import StageCore from './StageCore';
|
|
30
31
|
import StageMask from './StageMask';
|
|
31
32
|
import type { StageDragResizeConfig } from './types';
|
|
33
|
+
import { ContainerHighlightType, StageDragStatus } from './types';
|
|
32
34
|
import { calcValueByFontsize, down, getAbsolutePosition, getMode, getOffset, getTargetElStyle, up } from './util';
|
|
33
35
|
|
|
34
|
-
/** 拖动状态 */
|
|
35
|
-
enum ActionStatus {
|
|
36
|
-
/** 开始拖动 */
|
|
37
|
-
START = 'start',
|
|
38
|
-
/** 拖动中 */
|
|
39
|
-
ING = 'ing',
|
|
40
|
-
/** 拖动结束 */
|
|
41
|
-
END = 'end',
|
|
42
|
-
}
|
|
43
|
-
|
|
44
36
|
/**
|
|
45
37
|
* 选中框
|
|
46
38
|
*/
|
|
@@ -66,10 +58,11 @@ export default class StageDragResize extends EventEmitter {
|
|
|
66
58
|
|
|
67
59
|
private moveableOptions: MoveableOptions = {};
|
|
68
60
|
/** 拖动状态 */
|
|
69
|
-
private dragStatus:
|
|
61
|
+
private dragStatus: StageDragStatus = StageDragStatus.END;
|
|
70
62
|
/** 流式布局下,目标节点的镜像节点 */
|
|
71
63
|
private ghostEl: HTMLElement | undefined;
|
|
72
64
|
private moveableHelper?: MoveableHelper;
|
|
65
|
+
private isContainerHighlight: Boolean = false;
|
|
73
66
|
|
|
74
67
|
constructor(config: StageDragResizeConfig) {
|
|
75
68
|
super();
|
|
@@ -77,6 +70,20 @@ export default class StageDragResize extends EventEmitter {
|
|
|
77
70
|
this.core = config.core;
|
|
78
71
|
this.container = config.container;
|
|
79
72
|
this.mask = config.mask;
|
|
73
|
+
|
|
74
|
+
KeyController.global.keydown('alt', (e) => {
|
|
75
|
+
e.inputEvent.preventDefault();
|
|
76
|
+
this.isContainerHighlight = true;
|
|
77
|
+
});
|
|
78
|
+
KeyController.global.keyup('alt', (e) => {
|
|
79
|
+
e.inputEvent.preventDefault();
|
|
80
|
+
|
|
81
|
+
const doc = this.core.renderer.contentWindow?.document;
|
|
82
|
+
if (doc && this.canContainerHighlight()) {
|
|
83
|
+
removeClassNameByClassName(doc, this.core.containerHighlightClassName);
|
|
84
|
+
}
|
|
85
|
+
this.isContainerHighlight = false;
|
|
86
|
+
});
|
|
80
87
|
}
|
|
81
88
|
|
|
82
89
|
/**
|
|
@@ -165,7 +172,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
165
172
|
this.moveable?.destroy();
|
|
166
173
|
this.destroyGhostEl();
|
|
167
174
|
this.destroyDragEl();
|
|
168
|
-
this.dragStatus =
|
|
175
|
+
this.dragStatus = StageDragStatus.END;
|
|
169
176
|
this.removeAllListeners();
|
|
170
177
|
}
|
|
171
178
|
|
|
@@ -243,7 +250,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
243
250
|
.on('resizeStart', (e) => {
|
|
244
251
|
if (!this.target) return;
|
|
245
252
|
|
|
246
|
-
this.dragStatus =
|
|
253
|
+
this.dragStatus = StageDragStatus.START;
|
|
247
254
|
this.moveableHelper?.onResizeStart(e);
|
|
248
255
|
|
|
249
256
|
frame.top = this.target.offsetTop;
|
|
@@ -254,7 +261,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
254
261
|
if (!this.moveable || !this.target || !this.dragEl) return;
|
|
255
262
|
|
|
256
263
|
const { beforeTranslate } = drag;
|
|
257
|
-
this.dragStatus =
|
|
264
|
+
this.dragStatus = StageDragStatus.ING;
|
|
258
265
|
|
|
259
266
|
this.moveableHelper?.onResize(e);
|
|
260
267
|
|
|
@@ -270,7 +277,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
270
277
|
this.target.style.height = `${height}px`;
|
|
271
278
|
})
|
|
272
279
|
.on('resizeEnd', () => {
|
|
273
|
-
this.dragStatus =
|
|
280
|
+
this.dragStatus = StageDragStatus.END;
|
|
274
281
|
this.update(true);
|
|
275
282
|
});
|
|
276
283
|
}
|
|
@@ -292,7 +299,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
292
299
|
.on('dragStart', (e) => {
|
|
293
300
|
if (!this.target) throw new Error('未选中组件');
|
|
294
301
|
|
|
295
|
-
this.dragStatus =
|
|
302
|
+
this.dragStatus = StageDragStatus.START;
|
|
296
303
|
|
|
297
304
|
this.moveableHelper?.onDragStart(e);
|
|
298
305
|
|
|
@@ -311,9 +318,11 @@ export default class StageDragResize extends EventEmitter {
|
|
|
311
318
|
timeout = undefined;
|
|
312
319
|
}
|
|
313
320
|
|
|
314
|
-
|
|
321
|
+
if (this.canContainerHighlight()) {
|
|
322
|
+
timeout = this.core.getAddContainerHighlightClassNameTimeout(e.inputEvent, [this.target]);
|
|
323
|
+
}
|
|
315
324
|
|
|
316
|
-
this.dragStatus =
|
|
325
|
+
this.dragStatus = StageDragStatus.ING;
|
|
317
326
|
|
|
318
327
|
// 流式布局
|
|
319
328
|
if (this.ghostEl) {
|
|
@@ -334,12 +343,12 @@ export default class StageDragResize extends EventEmitter {
|
|
|
334
343
|
|
|
335
344
|
let parentEl: HTMLElement | null = null;
|
|
336
345
|
|
|
337
|
-
if (doc) {
|
|
346
|
+
if (doc && this.canContainerHighlight()) {
|
|
338
347
|
parentEl = removeClassNameByClassName(doc, this.core.containerHighlightClassName);
|
|
339
348
|
}
|
|
340
349
|
|
|
341
350
|
// 点击不拖动时会触发dragStart和dragEnd,但是不会有drag事件
|
|
342
|
-
if (this.dragStatus ===
|
|
351
|
+
if (this.dragStatus === StageDragStatus.ING) {
|
|
343
352
|
if (parentEl) {
|
|
344
353
|
this.update(false, parentEl);
|
|
345
354
|
} else {
|
|
@@ -353,7 +362,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
353
362
|
}
|
|
354
363
|
}
|
|
355
364
|
|
|
356
|
-
this.dragStatus =
|
|
365
|
+
this.dragStatus = StageDragStatus.END;
|
|
357
366
|
this.destroyGhostEl();
|
|
358
367
|
});
|
|
359
368
|
}
|
|
@@ -363,18 +372,18 @@ export default class StageDragResize extends EventEmitter {
|
|
|
363
372
|
|
|
364
373
|
this.moveable
|
|
365
374
|
.on('rotateStart', (e) => {
|
|
366
|
-
this.dragStatus =
|
|
375
|
+
this.dragStatus = StageDragStatus.START;
|
|
367
376
|
this.moveableHelper?.onRotateStart(e);
|
|
368
377
|
})
|
|
369
378
|
.on('rotate', (e) => {
|
|
370
379
|
if (!this.target || !this.dragEl) return;
|
|
371
|
-
this.dragStatus =
|
|
380
|
+
this.dragStatus = StageDragStatus.ING;
|
|
372
381
|
this.moveableHelper?.onRotate(e);
|
|
373
382
|
const frame = this.moveableHelper?.getFrame(e.target);
|
|
374
383
|
this.target.style.transform = frame?.toCSSObject().transform || '';
|
|
375
384
|
})
|
|
376
385
|
.on('rotateEnd', (e) => {
|
|
377
|
-
this.dragStatus =
|
|
386
|
+
this.dragStatus = StageDragStatus.END;
|
|
378
387
|
const frame = this.moveableHelper?.getFrame(e.target);
|
|
379
388
|
this.emit('update', {
|
|
380
389
|
el: this.target,
|
|
@@ -390,18 +399,18 @@ export default class StageDragResize extends EventEmitter {
|
|
|
390
399
|
|
|
391
400
|
this.moveable
|
|
392
401
|
.on('scaleStart', (e) => {
|
|
393
|
-
this.dragStatus =
|
|
402
|
+
this.dragStatus = StageDragStatus.START;
|
|
394
403
|
this.moveableHelper?.onScaleStart(e);
|
|
395
404
|
})
|
|
396
405
|
.on('scale', (e) => {
|
|
397
406
|
if (!this.target || !this.dragEl) return;
|
|
398
|
-
this.dragStatus =
|
|
407
|
+
this.dragStatus = StageDragStatus.ING;
|
|
399
408
|
this.moveableHelper?.onScale(e);
|
|
400
409
|
const frame = this.moveableHelper?.getFrame(e.target);
|
|
401
410
|
this.target.style.transform = frame?.toCSSObject().transform || '';
|
|
402
411
|
})
|
|
403
412
|
.on('scaleEnd', (e) => {
|
|
404
|
-
this.dragStatus =
|
|
413
|
+
this.dragStatus = StageDragStatus.END;
|
|
405
414
|
const frame = this.moveableHelper?.getFrame(e.target);
|
|
406
415
|
this.emit('update', {
|
|
407
416
|
el: this.target,
|
|
@@ -459,9 +468,13 @@ export default class StageDragResize extends EventEmitter {
|
|
|
459
468
|
}
|
|
460
469
|
|
|
461
470
|
this.emit('update', {
|
|
462
|
-
|
|
471
|
+
data: [
|
|
472
|
+
{
|
|
473
|
+
el: this.target,
|
|
474
|
+
style: isResize ? { left, top, width, height } : { left, top },
|
|
475
|
+
},
|
|
476
|
+
],
|
|
463
477
|
parentEl,
|
|
464
|
-
style: isResize ? { left, top, width, height } : { left, top },
|
|
465
478
|
});
|
|
466
479
|
}
|
|
467
480
|
|
|
@@ -566,4 +579,11 @@ export default class StageDragResize extends EventEmitter {
|
|
|
566
579
|
...moveableOptions,
|
|
567
580
|
};
|
|
568
581
|
}
|
|
582
|
+
|
|
583
|
+
private canContainerHighlight() {
|
|
584
|
+
return (
|
|
585
|
+
this.core.containerHighlightType === ContainerHighlightType.DEFAULT ||
|
|
586
|
+
(this.core.containerHighlightType === ContainerHighlightType.ALT && this.isContainerHighlight)
|
|
587
|
+
);
|
|
588
|
+
}
|
|
569
589
|
}
|
package/src/StageMask.ts
CHANGED
|
@@ -108,11 +108,16 @@ export default class StageMask extends Rule {
|
|
|
108
108
|
this.content.addEventListener('wheel', this.mouseWheelHandler);
|
|
109
109
|
this.content.addEventListener('mousemove', this.highlightHandler);
|
|
110
110
|
this.content.addEventListener('mouseleave', this.mouseLeaveHandler);
|
|
111
|
-
|
|
111
|
+
|
|
112
|
+
const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
|
|
113
|
+
|
|
114
|
+
const ctrl = isMac ? 'meta' : 'ctrl';
|
|
115
|
+
|
|
116
|
+
KeyController.global.keydown(ctrl, (e) => {
|
|
112
117
|
e.inputEvent.preventDefault();
|
|
113
118
|
this.isMultiSelectStatus = true;
|
|
114
119
|
});
|
|
115
|
-
KeyController.global.keyup(
|
|
120
|
+
KeyController.global.keyup(ctrl, (e) => {
|
|
116
121
|
e.inputEvent.preventDefault();
|
|
117
122
|
this.isMultiSelectStatus = false;
|
|
118
123
|
});
|
|
@@ -25,8 +25,9 @@ import MoveableHelper from 'moveable-helper';
|
|
|
25
25
|
import { DRAG_EL_ID_PREFIX, PAGE_CLASS } from './const';
|
|
26
26
|
import StageCore from './StageCore';
|
|
27
27
|
import StageMask from './StageMask';
|
|
28
|
-
import { StageDragResizeConfig } from './types';
|
|
28
|
+
import { StageDragResizeConfig, StageDragStatus } from './types';
|
|
29
29
|
import { calcValueByFontsize, getMode, getTargetElStyle } from './util';
|
|
30
|
+
|
|
30
31
|
export default class StageMultiDragResize extends EventEmitter {
|
|
31
32
|
public core: StageCore;
|
|
32
33
|
public mask: StageMask;
|
|
@@ -38,6 +39,8 @@ export default class StageMultiDragResize extends EventEmitter {
|
|
|
38
39
|
public dragElList: HTMLDivElement[] = [];
|
|
39
40
|
/** Moveable多选拖拽类实例 */
|
|
40
41
|
public moveableForMulti?: Moveable;
|
|
42
|
+
/** 拖动状态 */
|
|
43
|
+
public dragStatus: StageDragStatus = StageDragStatus.END;
|
|
41
44
|
private multiMoveableHelper?: MoveableHelper;
|
|
42
45
|
|
|
43
46
|
constructor(config: StageDragResizeConfig) {
|
|
@@ -99,6 +102,7 @@ export default class StageMultiDragResize extends EventEmitter {
|
|
|
99
102
|
id: matchEventTarget.id,
|
|
100
103
|
});
|
|
101
104
|
});
|
|
105
|
+
this.dragStatus = StageDragStatus.START;
|
|
102
106
|
})
|
|
103
107
|
.on('dragGroup', (params) => {
|
|
104
108
|
const { events } = params;
|
|
@@ -121,22 +125,35 @@ export default class StageMultiDragResize extends EventEmitter {
|
|
|
121
125
|
}
|
|
122
126
|
});
|
|
123
127
|
this.multiMoveableHelper?.onDragGroup(params);
|
|
128
|
+
this.dragStatus = StageDragStatus.ING;
|
|
124
129
|
})
|
|
125
130
|
.on('dragGroupEnd', () => {
|
|
126
131
|
this.update();
|
|
132
|
+
this.dragStatus = StageDragStatus.END;
|
|
133
|
+
})
|
|
134
|
+
.on('clickGroup', (params) => {
|
|
135
|
+
const { inputTarget, targets } = params;
|
|
136
|
+
// 如果此时mask不处于多选状态下,且有多个元素被选中,同时点击的元素在选中元素中的其中一项,代表多选态切换为该元素的单选态
|
|
137
|
+
if (!this.mask.isMultiSelectStatus && targets.length > 1 && targets.includes(inputTarget)) {
|
|
138
|
+
this.emit('select', inputTarget.id.replace(DRAG_EL_ID_PREFIX, ''));
|
|
139
|
+
}
|
|
127
140
|
});
|
|
128
141
|
}
|
|
129
142
|
|
|
130
|
-
public canSelect(el: HTMLElement): Boolean {
|
|
131
|
-
//
|
|
143
|
+
public canSelect(el: HTMLElement, stop: () => boolean): Boolean {
|
|
144
|
+
// 多选状态下不可以选中magic-ui-page,并停止继续向上层选中
|
|
132
145
|
if (el.className.includes(PAGE_CLASS)) {
|
|
133
146
|
this.core.highlightedDom = undefined;
|
|
134
147
|
this.core.highlightLayer.clearHighlight();
|
|
148
|
+
stop();
|
|
135
149
|
return false;
|
|
136
150
|
}
|
|
137
151
|
const currentTargetMode = getMode(el);
|
|
138
152
|
let selectedDomMode = '';
|
|
139
|
-
|
|
153
|
+
if (this.core.selectedDom?.className.includes(PAGE_CLASS)) {
|
|
154
|
+
// 先单击选中了页面(magic-ui-page),再按住多选键多选时,任一元素均可选中
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
140
157
|
if (this.targetList.length === 0 && this.core.selectedDom) {
|
|
141
158
|
// 单选后添加到多选的情况
|
|
142
159
|
selectedDomMode = getMode(this.core.selectedDom);
|
|
@@ -188,16 +205,19 @@ export default class StageMultiDragResize extends EventEmitter {
|
|
|
188
205
|
const doc = contentWindow?.document;
|
|
189
206
|
if (!doc) return;
|
|
190
207
|
|
|
191
|
-
this.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
208
|
+
this.emit('update', {
|
|
209
|
+
data: this.targetList.map((targetItem) => {
|
|
210
|
+
const offset = { left: targetItem.offsetLeft, top: targetItem.offsetTop };
|
|
211
|
+
const left = calcValueByFontsize(doc, offset.left);
|
|
212
|
+
const top = calcValueByFontsize(doc, offset.top);
|
|
213
|
+
const width = calcValueByFontsize(doc, targetItem.clientWidth);
|
|
214
|
+
const height = calcValueByFontsize(doc, targetItem.clientHeight);
|
|
215
|
+
return {
|
|
216
|
+
el: targetItem,
|
|
217
|
+
style: isResize ? { left, top, width, height } : { left, top },
|
|
218
|
+
};
|
|
219
|
+
}),
|
|
220
|
+
parentEl: null,
|
|
201
221
|
});
|
|
202
222
|
}
|
|
203
223
|
|
|
@@ -217,13 +237,22 @@ export default class StageMultiDragResize extends EventEmitter {
|
|
|
217
237
|
defaultGroupRotate: 0,
|
|
218
238
|
defaultGroupOrigin: '50% 50%',
|
|
219
239
|
draggable: true,
|
|
220
|
-
resizable:
|
|
240
|
+
resizable: false,
|
|
221
241
|
throttleDrag: 0,
|
|
222
242
|
startDragRotate: 0,
|
|
223
243
|
throttleDragRotate: 0,
|
|
224
244
|
zoom: 1,
|
|
225
245
|
origin: true,
|
|
226
246
|
padding: { left: 0, top: 0, right: 0, bottom: 0 },
|
|
247
|
+
snappable: true,
|
|
248
|
+
bounds: {
|
|
249
|
+
top: 0,
|
|
250
|
+
// 设置0的话无法移动到left为0,所以只能设置为-1
|
|
251
|
+
left: -1,
|
|
252
|
+
right: this.container.clientWidth - 1,
|
|
253
|
+
bottom: this.container.clientHeight,
|
|
254
|
+
...(multiMoveableOptions.bounds || {}),
|
|
255
|
+
},
|
|
227
256
|
...options,
|
|
228
257
|
...multiMoveableOptions,
|
|
229
258
|
};
|
package/src/types.ts
CHANGED
|
@@ -29,6 +29,11 @@ import StageMask from './StageMask';
|
|
|
29
29
|
export type CanSelect = (el: HTMLElement, event: MouseEvent, stop: () => boolean) => boolean | Promise<boolean>;
|
|
30
30
|
export type IsContainer = (el: HTMLElement) => boolean | Promise<boolean>;
|
|
31
31
|
|
|
32
|
+
export enum ContainerHighlightType {
|
|
33
|
+
DEFAULT = 'default',
|
|
34
|
+
ALT = 'alt',
|
|
35
|
+
}
|
|
36
|
+
|
|
32
37
|
export type StageCoreConfig = {
|
|
33
38
|
/** 需要对齐的dom节点的CSS选择器字符串 */
|
|
34
39
|
snapElementQuerySelector?: string;
|
|
@@ -36,8 +41,9 @@ export type StageCoreConfig = {
|
|
|
36
41
|
zoom?: number;
|
|
37
42
|
canSelect?: CanSelect;
|
|
38
43
|
isContainer: IsContainer;
|
|
39
|
-
containerHighlightClassName
|
|
40
|
-
containerHighlightDuration
|
|
44
|
+
containerHighlightClassName?: string;
|
|
45
|
+
containerHighlightDuration?: number;
|
|
46
|
+
containerHighlightType?: ContainerHighlightType;
|
|
41
47
|
moveableOptions?: ((core?: StageCore) => MoveableOptions) | MoveableOptions;
|
|
42
48
|
multiMoveableOptions?: ((core?: StageCore) => MoveableOptions) | MoveableOptions;
|
|
43
49
|
/** runtime 的HTML地址,可以是一个HTTP地址,如果和编辑器不同域,需要设置跨域,也可以是一个相对或绝对路径 */
|
|
@@ -61,6 +67,16 @@ export interface StageDragResizeConfig {
|
|
|
61
67
|
mask: StageMask;
|
|
62
68
|
}
|
|
63
69
|
|
|
70
|
+
/** 拖动状态 */
|
|
71
|
+
export enum StageDragStatus {
|
|
72
|
+
/** 开始拖动 */
|
|
73
|
+
START = 'start',
|
|
74
|
+
/** 拖动中 */
|
|
75
|
+
ING = 'ing',
|
|
76
|
+
/** 拖动结束 */
|
|
77
|
+
END = 'end',
|
|
78
|
+
}
|
|
79
|
+
|
|
64
80
|
export type Rect = {
|
|
65
81
|
width: number;
|
|
66
82
|
height: number;
|
|
@@ -77,19 +93,21 @@ export interface GuidesEventData {
|
|
|
77
93
|
}
|
|
78
94
|
|
|
79
95
|
export interface UpdateEventData {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
96
|
+
data: {
|
|
97
|
+
el: HTMLElement;
|
|
98
|
+
style: {
|
|
99
|
+
width?: number;
|
|
100
|
+
height?: number;
|
|
101
|
+
left?: number;
|
|
102
|
+
top?: number;
|
|
103
|
+
transform?: {
|
|
104
|
+
rotate?: string;
|
|
105
|
+
scale?: string;
|
|
106
|
+
};
|
|
91
107
|
};
|
|
92
|
-
|
|
108
|
+
ghostEl?: HTMLElement;
|
|
109
|
+
}[];
|
|
110
|
+
parentEl: HTMLElement | null;
|
|
93
111
|
}
|
|
94
112
|
|
|
95
113
|
export interface SortEventData {
|
package/types/StageCore.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import StageHighlight from './StageHighlight';
|
|
|
7
7
|
import StageMask from './StageMask';
|
|
8
8
|
import StageMultiDragResize from './StageMultiDragResize';
|
|
9
9
|
import StageRender from './StageRender';
|
|
10
|
-
import { IsContainer, RemoveData, SortEventData, StageCoreConfig, UpdateData } from './types';
|
|
10
|
+
import { ContainerHighlightType, IsContainer, RemoveData, SortEventData, StageCoreConfig, UpdateData } from './types';
|
|
11
11
|
export default class StageCore extends EventEmitter {
|
|
12
12
|
container?: HTMLDivElement;
|
|
13
13
|
selectedDom: HTMLElement | undefined;
|
|
@@ -22,6 +22,7 @@ export default class StageCore extends EventEmitter {
|
|
|
22
22
|
zoom: number;
|
|
23
23
|
containerHighlightClassName: string;
|
|
24
24
|
containerHighlightDuration: number;
|
|
25
|
+
containerHighlightType?: ContainerHighlightType;
|
|
25
26
|
isContainer: IsContainer;
|
|
26
27
|
private canSelect;
|
|
27
28
|
constructor(config: StageCoreConfig);
|
|
@@ -33,6 +33,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
33
33
|
/** 流式布局下,目标节点的镜像节点 */
|
|
34
34
|
private ghostEl;
|
|
35
35
|
private moveableHelper?;
|
|
36
|
+
private isContainerHighlight;
|
|
36
37
|
constructor(config: StageDragResizeConfig);
|
|
37
38
|
/**
|
|
38
39
|
* 将选中框渲染并覆盖到选中的组件Dom节点上方
|
|
@@ -67,4 +68,5 @@ export default class StageDragResize extends EventEmitter {
|
|
|
67
68
|
private setGhostElChildrenId;
|
|
68
69
|
private destroyGhostEl;
|
|
69
70
|
private getOptions;
|
|
71
|
+
private canContainerHighlight;
|
|
70
72
|
}
|
|
@@ -3,7 +3,7 @@ import { EventEmitter } from 'events';
|
|
|
3
3
|
import Moveable from 'moveable';
|
|
4
4
|
import StageCore from './StageCore';
|
|
5
5
|
import StageMask from './StageMask';
|
|
6
|
-
import { StageDragResizeConfig } from './types';
|
|
6
|
+
import { StageDragResizeConfig, StageDragStatus } from './types';
|
|
7
7
|
export default class StageMultiDragResize extends EventEmitter {
|
|
8
8
|
core: StageCore;
|
|
9
9
|
mask: StageMask;
|
|
@@ -15,6 +15,8 @@ export default class StageMultiDragResize extends EventEmitter {
|
|
|
15
15
|
dragElList: HTMLDivElement[];
|
|
16
16
|
/** Moveable多选拖拽类实例 */
|
|
17
17
|
moveableForMulti?: Moveable;
|
|
18
|
+
/** 拖动状态 */
|
|
19
|
+
dragStatus: StageDragStatus;
|
|
18
20
|
private multiMoveableHelper?;
|
|
19
21
|
constructor(config: StageDragResizeConfig);
|
|
20
22
|
/**
|
|
@@ -22,7 +24,7 @@ export default class StageMultiDragResize extends EventEmitter {
|
|
|
22
24
|
* @param els
|
|
23
25
|
*/
|
|
24
26
|
multiSelect(els: HTMLElement[]): void;
|
|
25
|
-
canSelect(el: HTMLElement): Boolean;
|
|
27
|
+
canSelect(el: HTMLElement, stop: () => boolean): Boolean;
|
|
26
28
|
/**
|
|
27
29
|
* 清除多选状态
|
|
28
30
|
*/
|
package/types/types.d.ts
CHANGED
|
@@ -7,6 +7,10 @@ import StageDragResize from './StageDragResize';
|
|
|
7
7
|
import StageMask from './StageMask';
|
|
8
8
|
export declare type CanSelect = (el: HTMLElement, event: MouseEvent, stop: () => boolean) => boolean | Promise<boolean>;
|
|
9
9
|
export declare type IsContainer = (el: HTMLElement) => boolean | Promise<boolean>;
|
|
10
|
+
export declare enum ContainerHighlightType {
|
|
11
|
+
DEFAULT = "default",
|
|
12
|
+
ALT = "alt"
|
|
13
|
+
}
|
|
10
14
|
export declare type StageCoreConfig = {
|
|
11
15
|
/** 需要对齐的dom节点的CSS选择器字符串 */
|
|
12
16
|
snapElementQuerySelector?: string;
|
|
@@ -14,8 +18,9 @@ export declare type StageCoreConfig = {
|
|
|
14
18
|
zoom?: number;
|
|
15
19
|
canSelect?: CanSelect;
|
|
16
20
|
isContainer: IsContainer;
|
|
17
|
-
containerHighlightClassName
|
|
18
|
-
containerHighlightDuration
|
|
21
|
+
containerHighlightClassName?: string;
|
|
22
|
+
containerHighlightDuration?: number;
|
|
23
|
+
containerHighlightType?: ContainerHighlightType;
|
|
19
24
|
moveableOptions?: ((core?: StageCore) => MoveableOptions) | MoveableOptions;
|
|
20
25
|
multiMoveableOptions?: ((core?: StageCore) => MoveableOptions) | MoveableOptions;
|
|
21
26
|
/** runtime 的HTML地址,可以是一个HTTP地址,如果和编辑器不同域,需要设置跨域,也可以是一个相对或绝对路径 */
|
|
@@ -35,6 +40,15 @@ export interface StageDragResizeConfig {
|
|
|
35
40
|
container: HTMLElement;
|
|
36
41
|
mask: StageMask;
|
|
37
42
|
}
|
|
43
|
+
/** 拖动状态 */
|
|
44
|
+
export declare enum StageDragStatus {
|
|
45
|
+
/** 开始拖动 */
|
|
46
|
+
START = "start",
|
|
47
|
+
/** 拖动中 */
|
|
48
|
+
ING = "ing",
|
|
49
|
+
/** 拖动结束 */
|
|
50
|
+
END = "end"
|
|
51
|
+
}
|
|
38
52
|
export declare type Rect = {
|
|
39
53
|
width: number;
|
|
40
54
|
height: number;
|
|
@@ -48,19 +62,21 @@ export interface GuidesEventData {
|
|
|
48
62
|
guides: number[];
|
|
49
63
|
}
|
|
50
64
|
export interface UpdateEventData {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
data: {
|
|
66
|
+
el: HTMLElement;
|
|
67
|
+
style: {
|
|
68
|
+
width?: number;
|
|
69
|
+
height?: number;
|
|
70
|
+
left?: number;
|
|
71
|
+
top?: number;
|
|
72
|
+
transform?: {
|
|
73
|
+
rotate?: string;
|
|
74
|
+
scale?: string;
|
|
75
|
+
};
|
|
62
76
|
};
|
|
63
|
-
|
|
77
|
+
ghostEl?: HTMLElement;
|
|
78
|
+
}[];
|
|
79
|
+
parentEl: HTMLElement | null;
|
|
64
80
|
}
|
|
65
81
|
export interface SortEventData {
|
|
66
82
|
src: Id;
|