@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.
@@ -17,103 +17,62 @@
17
17
  */
18
18
 
19
19
  /* eslint-disable no-param-reassign */
20
- import { EventEmitter } from 'events';
20
+ import Moveable, { MoveableOptions } from 'moveable';
21
21
 
22
- import KeyController from 'keycon';
23
- import type { MoveableOptions } from 'moveable';
24
- import Moveable from 'moveable';
25
- import MoveableHelper from 'moveable-helper';
26
-
27
- import { removeClassNameByClassName } from '@tmagic/utils';
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 EventEmitter {
41
- public core: StageCore;
42
- public mask: StageMask;
43
- /** 画布容器 */
44
- public container: HTMLElement;
33
+ export default class StageDragResize extends MoveableOptionsManager {
45
34
  /** 目标节点 */
46
- public target?: HTMLElement;
47
- /** 目标节点在蒙层中的占位节点 */
48
- public dragEl?: HTMLDivElement;
35
+ private target?: HTMLElement;
49
36
  /** Moveable拖拽类实例 */
50
- public moveable?: Moveable;
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 ghostEl: HTMLElement | undefined;
65
- private moveableHelper?: MoveableHelper;
66
- private isContainerHighlight: Boolean = false;
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.core = config.core;
72
- this.container = config.container;
73
- this.mask = config.mask;
48
+ this.getRenderDocument = config.getRenderDocument;
49
+ this.markContainerEnd = config.markContainerEnd;
50
+ this.delayedMarkContainer = config.delayedMarkContainer;
74
51
 
75
- KeyController.global.keydown('alt', (e) => {
76
- e.inputEvent.preventDefault();
77
- this.isContainerHighlight = true;
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
- const doc = this.core.renderer.contentWindow?.document;
83
- if (doc && this.canContainerHighlight()) {
84
- removeClassNameByClassName(doc, this.core.containerHighlightClassName);
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
- * 当选中的节点是不是absolute时,会创建一个新的节点出来作为拖拽目标
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 !== oldTarget) {
107
- this.init(el);
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) throw new Error('未初始化moveable');
87
+ if (!this.moveable) return;
129
88
  if (!el) throw new Error('未选中任何节点');
130
89
 
131
- this.target = el;
132
-
133
- this.init(el);
90
+ const options: MoveableOptions = this.init(el);
134
91
 
135
- Object.entries(this.moveableOptions).forEach(([key, value]) => {
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.destroyDragEl();
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.destroyGhostEl();
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): void {
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.destroyGhostEl();
194
-
195
- if (!this.dragEl) {
196
- return;
197
- }
121
+ this.target = el;
122
+ this.mode = getMode(el);
198
123
 
199
- this.dragEl.style.cssText = getTargetElStyle(el);
200
- this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
124
+ this.dragResizeHelper.updateShadowEl(el);
125
+ this.dragResizeHelper.setMode(this.mode);
201
126
 
202
- if (typeof this.core.config.updateDragEl === 'function') {
203
- this.core.config.updateDragEl(this.dragEl, el);
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
- private setElementGuidelines(nodes: HTMLElement[]) {
211
- this.elementGuidelines.forEach((node) => {
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 createGuidelineElements(nodes: HTMLElement[]) {
222
- const frame = globalThis.document.createDocumentFragment();
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
- ...this.moveableOptions,
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.moveableHelper?.onResizeStart(e);
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
- const { width, height, drag } = e;
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.moveableHelper?.onDragStart(e);
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.dragEl) return;
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
- let parentEl: HTMLElement | null = null;
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.moveableHelper?.onRotateStart(e);
234
+ this.dragResizeHelper.onRotateStart(e);
387
235
  })
388
236
  .on('rotate', (e) => {
389
- if (!this.target || !this.dragEl) return;
237
+ if (!this.target || !this.dragResizeHelper.getShadowEl()) return;
390
238
  this.dragStatus = StageDragStatus.ING;
391
- this.moveableHelper?.onRotate(e);
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.moveableHelper?.getFrame(e.target);
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.moveableHelper?.onScaleStart(e);
263
+ this.dragResizeHelper.onScaleStart(e);
418
264
  })
419
265
  .on('scale', (e) => {
420
- if (!this.target || !this.dragEl) return;
266
+ if (!this.target || !this.dragResizeHelper.getShadowEl()) return;
421
267
  this.dragStatus = StageDragStatus.ING;
422
- this.moveableHelper?.onScale(e);
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.moveableHelper?.getFrame(e.target);
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.ghostEl) throw new Error('未知错误');
444
- const { top } = this.ghostEl.getBoundingClientRect();
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 { contentWindow } = this.core.renderer;
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
- if (parentEl && this.mode === Mode.ABSOLUTE && this.dragEl) {
478
- const [translateX, translateY] = this.moveableHelper?.getFrame(this.dragEl).properties.transform.translate.value;
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, this.dragEl.offsetLeft) +
332
+ calcValueByFontsize(doc, targetShadowElOffsetLeft) +
482
333
  parseFloat(translateX) -
483
334
  calcValueByFontsize(doc, parentLeft);
484
335
  top =
485
- calcValueByFontsize(doc, this.dragEl.offsetTop) + parseFloat(translateY) - calcValueByFontsize(doc, parentTop);
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
  }
@@ -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 StageCore from './StageCore';
25
- import TargetCalibrate from './TargetCalibrate';
26
- import type { StageHighlightConfig } from './types';
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 calibrationTarget: TargetCalibrate;
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.calibrationTarget = new TargetCalibrate({
40
- parent: this.core.mask.content,
41
- mask: this.core.mask,
42
- dr: this.core.dr,
43
- core: this.core,
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.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
58
+ target: this.targetShadow.update(el),
58
59
  origin: false,
59
- rootContainer: this.core.container,
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.calibrationTarget.destroy();
80
+ this.targetShadow.destroy();
80
81
  }
81
82
  }