@tmagic/stage 1.0.0-rc.1 → 1.0.0-rc.12

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.
@@ -1,23 +1,46 @@
1
+ /** 流式布局下拖动时需要clone一个镜像节点,镜像节点的id前缀 */
1
2
  export declare const GHOST_EL_ID_PREFIX = "ghost_el_";
3
+ /** 拖动的时候需要在蒙层中创建一个占位节点,该节点的id前缀 */
2
4
  export declare const DRAG_EL_ID_PREFIX = "drag_el_";
5
+ /** 高亮时需要在蒙层中创建一个占位节点,该节点的id前缀 */
3
6
  export declare const HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
7
+ /** 默认放到缩小倍数 */
4
8
  export declare const DEFAULT_ZOOM = 1;
9
+ /** 参考线类型 */
5
10
  export declare enum GuidesType {
11
+ /** 水平 */
6
12
  HORIZONTAL = "horizontal",
13
+ /** 垂直 */
7
14
  VERTICAL = "vertical"
8
15
  }
16
+ /** css z-index */
9
17
  export declare enum ZIndex {
18
+ /** 蒙层,用于监听用户操作,需要置于顶层 */
10
19
  MASK = "99999",
11
- SELECTED_EL = "666"
20
+ /** 选中的节点 */
21
+ SELECTED_EL = "666",
22
+ GHOST_EL = "700",
23
+ DRAG_EL = "9"
12
24
  }
25
+ /** 鼠标按键 */
13
26
  export declare enum MouseButton {
27
+ /** 左键 */
14
28
  LEFT = 0,
29
+ /** z中健 */
15
30
  MIDDLE = 1,
31
+ /** 右键 */
16
32
  RIGHT = 2
17
33
  }
34
+ /** 布局方式 */
18
35
  export declare enum Mode {
36
+ /** 绝对定位布局 */
19
37
  ABSOLUTE = "absolute",
38
+ /** 固定定位布局 */
20
39
  FIXED = "fixed",
40
+ /** 流式布局 */
21
41
  SORTABLE = "sortable"
22
42
  }
43
+ /** 选中节点的class name */
23
44
  export declare const SELECTED_CLASS = "tmagic-stage-selected-area";
45
+ export declare const H_GUIDE_LINE_STORAGE_KEY = "$MagicStageHorizontalGuidelinesData";
46
+ export declare const V_GUIDE_LINE_STORAGE_KEY = "$MagicStageVerticalGuidelinesData";
@@ -1,4 +1,5 @@
1
- import { MoveableOptions } from 'react-moveable/declaration/types';
1
+ import { MoveableOptions } from 'moveable';
2
+ import Core from '@tmagic/core';
2
3
  import { Id, MApp, MNode } from '@tmagic/schema';
3
4
  import { GuidesType } from './const';
4
5
  import StageCore from './StageCore';
@@ -15,6 +16,8 @@ export declare type StageCoreConfig = {
15
16
  /** runtime 的HTML地址,可以是一个HTTP地址,如果和编辑器不同域,需要设置跨域,也可以是一个相对或绝对路径 */
16
17
  runtimeUrl?: string;
17
18
  render?: (renderer: StageCore) => Promise<HTMLElement> | HTMLElement;
19
+ autoScrollIntoView?: boolean;
20
+ updateDragEl?: (el: HTMLDivElement, target: HTMLElement) => void;
18
21
  };
19
22
  export interface StageRenderConfig {
20
23
  core: StageCore;
@@ -42,10 +45,14 @@ export interface UpdateEventData {
42
45
  el: HTMLElement;
43
46
  ghostEl: HTMLElement;
44
47
  style: {
45
- width: number;
46
- height: number;
48
+ width?: number;
49
+ height?: number;
47
50
  left?: number;
48
51
  top?: number;
52
+ transform?: {
53
+ rotate?: string;
54
+ scale?: string;
55
+ };
49
56
  };
50
57
  }
51
58
  export interface SortEventData {
@@ -62,9 +69,10 @@ export interface RemoveData {
62
69
  root: MApp;
63
70
  }
64
71
  export interface Runtime {
72
+ getApp?: () => Core;
65
73
  beforeSelect?: (el: HTMLElement) => Promise<boolean> | boolean;
66
74
  getSnapElements?: (el?: HTMLElement) => HTMLElement[];
67
- updateRootConfig: (config: MApp) => void;
75
+ updateRootConfig?: (config: MApp) => void;
68
76
  updatePageId?: (id: Id) => void;
69
77
  select?: (id: Id) => Promise<HTMLElement> | HTMLElement;
70
78
  add?: (data: UpdateData) => void;
@@ -88,4 +96,5 @@ export interface TargetCalibrateConfig {
88
96
  parent: HTMLElement;
89
97
  mask: StageMask;
90
98
  dr: StageDragResize;
99
+ core: StageCore;
91
100
  }
@@ -1,4 +1,4 @@
1
- import { Mode } from './const';
1
+ import { GuidesType, Mode } from './const';
2
2
  import type { Offset } from './types';
3
3
  export declare const getOffset: (el: HTMLElement) => Offset;
4
4
  export declare const getAbsolutePosition: (el: HTMLElement, { top, left }: Offset) => {
@@ -19,4 +19,5 @@ export declare const createDiv: ({ className, cssText }: {
19
19
  cssText: string;
20
20
  }) => HTMLDivElement;
21
21
  export declare const removeSelectedClassName: (doc: Document) => void;
22
- export declare const addSelectedClassName: (el: Element) => void;
22
+ export declare const addSelectedClassName: (el: Element, doc: Document) => void;
23
+ export declare const getGuideLineFromCache: (type: GuidesType) => number[];
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.0-rc.1",
2
+ "version": "1.0.0-rc.12",
3
3
  "name": "@tmagic/stage",
4
4
  "sideEffects": [
5
5
  "dist/*"
@@ -27,8 +27,9 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@scena/guides": "^0.17.0",
30
- "@tmagic/schema": "^1.0.0-rc.1",
31
- "@tmagic/utils": "^1.0.0-rc.1",
30
+ "@tmagic/core": "1.0.0-rc.12",
31
+ "@tmagic/schema": "1.0.0-rc.12",
32
+ "@tmagic/utils": "1.0.0-rc.12",
32
33
  "events": "^3.3.0",
33
34
  "lodash-es": "^4.17.21",
34
35
  "moveable": "^0.29.4",
@@ -42,6 +43,5 @@
42
43
  "typescript": "^4.3.4",
43
44
  "vite": "^2.3.7",
44
45
  "vite-plugin-dts": "^0.9.6"
45
- },
46
- "gitHead": "3b647794d087888bfec9772f54356fa48c0b6d90"
46
+ }
47
47
  }
package/src/Rule.ts CHANGED
@@ -2,13 +2,14 @@ import EventEmitter from 'events';
2
2
 
3
3
  import Guides, { GuidesEvents } from '@scena/guides';
4
4
 
5
- import { GuidesType } from './const';
5
+ import { GuidesType, H_GUIDE_LINE_STORAGE_KEY, V_GUIDE_LINE_STORAGE_KEY } from './const';
6
+ import { getGuideLineFromCache } from './util';
6
7
 
7
8
  export default class Rule extends EventEmitter {
8
9
  public hGuides: Guides;
9
10
  public vGuides: Guides;
10
- public horizontalGuidelines: number[] = [];
11
- public verticalGuidelines: number[] = [];
11
+ public horizontalGuidelines: number[] = getGuideLineFromCache(GuidesType.HORIZONTAL);
12
+ public verticalGuidelines: number[] = getGuideLineFromCache(GuidesType.VERTICAL);
12
13
 
13
14
  private container: HTMLDivElement;
14
15
  private containerResizeObserver: ResizeObserver;
@@ -17,8 +18,8 @@ export default class Rule extends EventEmitter {
17
18
  super();
18
19
 
19
20
  this.container = container;
20
- this.hGuides = this.createGuides(GuidesType.HORIZONTAL);
21
- this.vGuides = this.createGuides(GuidesType.VERTICAL);
21
+ this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
22
+ this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
22
23
 
23
24
  this.hGuides.on('changeGuides', this.hGuidesChangeGuidesHandler);
24
25
  this.vGuides.on('changeGuides', this.vGuidesChangeGuidesHandler);
@@ -68,6 +69,9 @@ export default class Rule extends EventEmitter {
68
69
  type: GuidesType.HORIZONTAL,
69
70
  guides: [],
70
71
  });
72
+
73
+ globalThis.localStorage.setItem(V_GUIDE_LINE_STORAGE_KEY, '[]');
74
+ globalThis.localStorage.setItem(H_GUIDE_LINE_STORAGE_KEY, '[]');
71
75
  }
72
76
 
73
77
  /**
@@ -138,6 +142,8 @@ export default class Rule extends EventEmitter {
138
142
  type: GuidesType.HORIZONTAL,
139
143
  guides: this.horizontalGuidelines,
140
144
  });
145
+
146
+ globalThis.localStorage.setItem(H_GUIDE_LINE_STORAGE_KEY, JSON.stringify(e.guides));
141
147
  };
142
148
 
143
149
  private vGuidesChangeGuidesHandler = (e: GuidesEvents['changeGuides']) => {
@@ -146,5 +152,7 @@ export default class Rule extends EventEmitter {
146
152
  type: GuidesType.VERTICAL,
147
153
  guides: this.verticalGuidelines,
148
154
  });
155
+
156
+ globalThis.localStorage.setItem(V_GUIDE_LINE_STORAGE_KEY, JSON.stringify(e.guides));
149
157
  };
150
158
  }
package/src/StageCore.ts CHANGED
@@ -155,12 +155,17 @@ export default class StageCore extends EventEmitter {
155
155
 
156
156
  this.mask.setLayout(el);
157
157
  this.dr.select(el, event);
158
+
159
+ if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
160
+ this.mask.intersectionObserver?.observe(el);
161
+ }
162
+
158
163
  this.selectedDom = el;
159
164
 
160
165
  if (this.renderer.contentWindow) {
161
166
  removeSelectedClassName(this.renderer.contentWindow.document);
162
167
  if (this.selectedDom) {
163
- addSelectedClassName(this.selectedDom);
168
+ addSelectedClassName(this.selectedDom, this.renderer.contentWindow.document);
164
169
  }
165
170
  }
166
171
  }
@@ -225,11 +230,11 @@ export default class StageCore extends EventEmitter {
225
230
  * 挂载Dom节点
226
231
  * @param el 将stage挂载到该Dom节点上
227
232
  */
228
- public mount(el: HTMLDivElement): void {
233
+ public async mount(el: HTMLDivElement) {
229
234
  this.container = el;
230
235
  const { mask, renderer } = this;
231
236
 
232
- renderer.mount(el);
237
+ await renderer.mount(el);
233
238
  mask.mount(el);
234
239
 
235
240
  this.emit('mounted');
@@ -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 { DRAG_EL_ID_PREFIX, 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
- import type { Offset, Runtime, SortEventData, StageDragResizeConfig } from './types';
29
- import { getAbsolutePosition, getMode, getOffset } from './util';
28
+ import type { SortEventData, StageDragResizeConfig } from './types';
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,27 @@ 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
- public dragEl: HTMLElement;
50
+ /** 目标节点在蒙层中的占位节点 */
51
+ public dragEl: HTMLDivElement;
52
+ /** Moveable拖拽类实例 */
45
53
  public moveable?: Moveable;
46
- public horizontalGuidelines: number[] = [];
47
- public verticalGuidelines: number[] = [];
54
+ /** 水平参考线 */
55
+ public horizontalGuidelines: number[] = getGuideLineFromCache(GuidesType.HORIZONTAL);
56
+ /** 垂直参考线 */
57
+ public verticalGuidelines: number[] = getGuideLineFromCache(GuidesType.VERTICAL);
58
+ /** 对齐元素集合 */
48
59
  public elementGuidelines: HTMLElement[] = [];
60
+ /** 布局方式:流式布局、绝对定位、固定定位 */
49
61
  public mode: Mode = Mode.ABSOLUTE;
50
62
 
51
63
  private moveableOptions: MoveableOptions = {};
64
+ /** 拖动状态 */
52
65
  private dragStatus: ActionStatus = ActionStatus.END;
66
+ /** 流式布局下,目标节点的镜像节点 */
53
67
  private ghostEl: HTMLElement | undefined;
54
68
  private moveableHelper?: MoveableHelper;
55
69
 
@@ -73,10 +87,9 @@ export default class StageDragResize extends EventEmitter {
73
87
  const oldTarget = this.target;
74
88
  this.target = el;
75
89
 
76
- this.init(el);
77
-
78
90
  // 从不能拖动到能拖动的节点之间切换,要重新创建moveable,不然dragStart不生效
79
91
  if (!this.moveable || this.target !== oldTarget) {
92
+ this.init(el);
80
93
  this.moveableHelper = MoveableHelper.create({
81
94
  useBeforeRender: true,
82
95
  useRender: false,
@@ -98,7 +111,7 @@ export default class StageDragResize extends EventEmitter {
98
111
  */
99
112
  public updateMoveable(el = this.target): void {
100
113
  if (!this.moveable) throw new Error('未初始化moveable');
101
- if (!el) throw new Error('为选中任何节点');
114
+ if (!el) throw new Error('未选中任何节点');
102
115
 
103
116
  this.target = el;
104
117
 
@@ -157,6 +170,29 @@ export default class StageDragResize extends EventEmitter {
157
170
  });
158
171
  }
159
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
+
160
196
  private initMoveable() {
161
197
  this.moveable?.destroy();
162
198
 
@@ -166,49 +202,47 @@ export default class StageDragResize extends EventEmitter {
166
202
 
167
203
  this.bindResizeEvent();
168
204
  this.bindDragEvent();
205
+ this.bindRotateEvent();
206
+ this.bindScaleEvent();
169
207
  }
170
208
 
171
209
  private bindResizeEvent(): void {
172
- if (!this.moveable) throw new Error('moveable 为初始化');
210
+ if (!this.moveable) throw new Error('moveable 未初始化');
173
211
 
174
212
  const frame = {
175
- translate: [0, 0],
213
+ left: 0,
214
+ top: 0,
176
215
  };
177
216
 
178
217
  this.moveable
179
218
  .on('resizeStart', (e) => {
180
- if (e.dragStart) {
181
- const rect = this.moveable!.getRect();
182
- const offset = getAbsolutePosition(e.target as HTMLElement, rect);
183
- e.dragStart.set([offset.left, offset.top]);
184
- }
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;
185
226
  })
186
- .on('resize', ({ width, height, drag }) => {
227
+ .on('resize', (e) => {
228
+ const { width, height, drag } = e;
187
229
  if (!this.moveable || !this.target || !this.dragEl) return;
188
230
 
189
231
  const { beforeTranslate } = drag;
190
- frame.translate = beforeTranslate;
191
232
  this.dragStatus = ActionStatus.ING;
192
233
 
193
- this.target.style.width = `${width}px`;
194
- this.target.style.height = `${height}px`;
195
- this.dragEl.style.width = `${width}px`;
196
- this.dragEl.style.height = `${height}px`;
234
+ this.moveableHelper?.onResize(e);
197
235
 
198
236
  // 流式布局
199
237
  if (this.mode === Mode.SORTABLE) {
200
- this.dragEl.style.top = `${beforeTranslate[1]}px`;
201
- this.target.style.top = `0px`;
202
- return;
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`;
203
242
  }
204
243
 
205
- this.dragEl.style.left = `${beforeTranslate[0]}px`;
206
- this.dragEl.style.top = `${beforeTranslate[1]}px`;
207
-
208
- const offset = getAbsolutePosition(this.target, { left: beforeTranslate[0], top: beforeTranslate[1] });
209
-
210
- this.target.style.left = `${offset.left}px`;
211
- this.target.style.top = `${offset.top}px`;
244
+ this.target.style.width = `${width}px`;
245
+ this.target.style.height = `${height}px`;
212
246
  })
213
247
  .on('resizeEnd', () => {
214
248
  this.dragStatus = ActionStatus.END;
@@ -217,9 +251,12 @@ export default class StageDragResize extends EventEmitter {
217
251
  }
218
252
 
219
253
  private bindDragEvent(): void {
220
- if (!this.moveable) throw new Error('moveable 为初始化');
254
+ if (!this.moveable) throw new Error('moveable 未初始化');
221
255
 
222
- let offset: Offset | null = null;
256
+ const frame = {
257
+ left: 0,
258
+ top: 0,
259
+ };
223
260
 
224
261
  this.moveable
225
262
  .on('dragStart', (e) => {
@@ -232,29 +269,25 @@ export default class StageDragResize extends EventEmitter {
232
269
  if (this.mode === Mode.SORTABLE) {
233
270
  this.ghostEl = this.generateGhostEl(this.target);
234
271
  }
272
+
273
+ frame.top = this.target.offsetTop;
274
+ frame.left = this.target.offsetLeft;
235
275
  })
236
276
  .on('drag', (e) => {
237
277
  if (!this.target || !this.dragEl) return;
238
278
 
239
- if (!offset) {
240
- offset = getAbsolutePosition(this.target, { left: 0, top: 0 });
241
- }
242
-
243
279
  this.dragStatus = ActionStatus.ING;
244
280
 
245
- const { left, top } = e;
246
-
247
281
  // 流式布局
248
282
  if (this.ghostEl) {
249
- this.dragEl.style.top = `${top}px`;
250
- this.ghostEl.style.top = `${top + offset.top}px`;
283
+ this.ghostEl.style.top = `${frame.top + e.beforeTranslate[1]}px`;
251
284
  return;
252
285
  }
253
286
 
254
287
  this.moveableHelper?.onDrag(e);
255
288
 
256
- this.target.style.left = `${left + offset.left}px`;
257
- this.target.style.top = `${top + offset.top}px`;
289
+ this.target.style.left = `${frame.left + e.beforeTranslate[0]}px`;
290
+ this.target.style.top = `${frame.top + e.beforeTranslate[1]}px`;
258
291
  })
259
292
  .on('dragEnd', () => {
260
293
  // 点击不拖动时会触发dragStart和dragEnd,但是不会有drag事件
@@ -267,24 +300,64 @@ export default class StageDragResize extends EventEmitter {
267
300
  this.update();
268
301
  }
269
302
  }
270
- offset = null;
271
303
 
272
304
  this.dragStatus = ActionStatus.END;
273
305
  this.destroyGhostEl();
274
306
  });
275
307
  }
276
308
 
277
- private getSnapElements(runtime: Runtime, el?: HTMLElement): HTMLElement[] {
278
- const { renderer, mask } = this.core;
279
- const getSnapElements =
280
- runtime?.getSnapElements ||
281
- (() => {
282
- const doc = renderer.contentWindow?.document;
283
- return doc ? Array.from(doc.querySelectorAll('[id]')) : [];
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
+ });
284
360
  });
285
- return getSnapElements(el).filter(
286
- (element) => element !== this.target && !this.target?.contains(element) && element !== mask.page,
287
- );
288
361
  }
289
362
 
290
363
  private sort(): void {
@@ -307,14 +380,15 @@ export default class StageDragResize extends EventEmitter {
307
380
  }
308
381
 
309
382
  private update(isResize = false): void {
310
- const rect = this.moveable!.getRect();
383
+ if (!this.target) return;
384
+
311
385
  const offset =
312
- this.mode === Mode.SORTABLE ? { left: 0, top: 0 } : getAbsolutePosition(this.target as HTMLElement, rect);
386
+ this.mode === Mode.SORTABLE ? { left: 0, top: 0 } : { left: this.target.offsetLeft, top: this.target.offsetTop };
313
387
 
314
388
  const left = this.calcValueByFontsize(offset.left);
315
389
  const top = this.calcValueByFontsize(offset.top);
316
- const width = this.calcValueByFontsize(rect.width);
317
- const height = this.calcValueByFontsize(rect.height);
390
+ const width = this.calcValueByFontsize(this.target.clientWidth);
391
+ const height = this.calcValueByFontsize(this.target.clientHeight);
318
392
 
319
393
  this.emit('update', {
320
394
  el: this.target,
@@ -330,7 +404,7 @@ export default class StageDragResize extends EventEmitter {
330
404
  const ghostEl = el.cloneNode(true) as HTMLElement;
331
405
  const { top, left } = getAbsolutePosition(el, getOffset(el));
332
406
  ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
333
- ghostEl.style.zIndex = '5';
407
+ ghostEl.style.zIndex = ZIndex.GHOST_EL;
334
408
  ghostEl.style.opacity = '.5';
335
409
  ghostEl.style.position = 'absolute';
336
410
  ghostEl.style.left = `${left}px`;
@@ -345,19 +419,24 @@ export default class StageDragResize extends EventEmitter {
345
419
  }
346
420
 
347
421
  private updateDragEl(el: HTMLElement) {
348
- const { width, height } = el.getBoundingClientRect();
349
422
  const offset = getOffset(el);
423
+ const { transform } = getComputedStyle(el);
350
424
 
351
425
  this.dragEl.style.cssText = `
352
426
  position: absolute;
427
+ transform: ${transform};
353
428
  left: ${offset.left}px;
354
429
  top: ${offset.top}px;
355
- width: ${width}px;
356
- height: ${height}px;
357
- z-index: 9;
430
+ width: ${el.clientWidth}px;
431
+ height: ${el.clientHeight}px;
432
+ z-index: ${ZIndex.DRAG_EL};
358
433
  `;
359
434
 
360
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
+ }
361
440
  }
362
441
 
363
442
  private destroyDragEl(): void {
@@ -376,6 +455,14 @@ export default class StageDragResize extends EventEmitter {
376
455
  moveableOptions = moveableOptions(this.core);
377
456
  }
378
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
+
379
466
  return {
380
467
  origin: false,
381
468
  rootContainer: this.core.container,
@@ -383,6 +470,8 @@ export default class StageDragResize extends EventEmitter {
383
470
  dragArea: false,
384
471
  draggable: true,
385
472
  resizable: true,
473
+ scalable: false,
474
+ rotatable: false,
386
475
  snappable: isAbsolute || isFixed,
387
476
  snapGap: isAbsolute || isFixed,
388
477
  snapThreshold: 5,
@@ -41,6 +41,7 @@ export default class StageHighlight extends EventEmitter {
41
41
  parent: this.core.mask.content,
42
42
  mask: this.core.mask,
43
43
  dr: this.core.dr,
44
+ core: this.core,
44
45
  });
45
46
  }
46
47