@tmagic/stage 1.0.0-beta.9 → 1.0.0-rc.3
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 +404 -241
- package/dist/tmagic-stage.es.js.map +1 -1
- package/dist/tmagic-stage.umd.js +405 -243
- 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 +8 -6
- 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 +18 -0
- package/dist/types/src/const.d.ts +2 -0
- package/dist/types/src/types.d.ts +10 -2
- package/dist/types/src/util.d.ts +1 -1
- package/package.json +11 -7
- package/src/StageCore.ts +43 -23
- package/src/StageDragResize.ts +84 -57
- package/src/StageHighlight.ts +15 -1
- package/src/StageMask.ts +91 -26
- package/src/TargetCalibrate.ts +135 -0
- package/src/const.ts +4 -0
- package/src/types.ts +11 -3
- package/src/util.ts +17 -1
- package/tsconfig.json +0 -9
- package/vite.config.ts +0 -27
package/package.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.0.0-
|
|
2
|
+
"version": "1.0.0-rc.3",
|
|
3
3
|
"name": "@tmagic/stage",
|
|
4
|
-
"sideEffects":
|
|
4
|
+
"sideEffects": [
|
|
5
|
+
"dist/*"
|
|
6
|
+
],
|
|
5
7
|
"main": "dist/tmagic-stage.umd.js",
|
|
6
8
|
"module": "dist/tmagic-stage.es.js",
|
|
7
9
|
"types": "dist/types/src/index.d.ts",
|
|
@@ -9,8 +11,10 @@
|
|
|
9
11
|
".": {
|
|
10
12
|
"import": "./dist/tmagic-stage.es.js",
|
|
11
13
|
"require": "./dist/tmagic-stage.umd.js"
|
|
12
|
-
}
|
|
14
|
+
},
|
|
15
|
+
"./*": "./*"
|
|
13
16
|
},
|
|
17
|
+
"license": "Apache-2.0",
|
|
14
18
|
"scripts": {
|
|
15
19
|
"build": "vite build"
|
|
16
20
|
},
|
|
@@ -23,11 +27,11 @@
|
|
|
23
27
|
},
|
|
24
28
|
"dependencies": {
|
|
25
29
|
"@scena/guides": "^0.17.0",
|
|
26
|
-
"@tmagic/schema": "^1.0.0-
|
|
27
|
-
"@tmagic/utils": "^1.0.0-
|
|
30
|
+
"@tmagic/schema": "^1.0.0-rc.3",
|
|
31
|
+
"@tmagic/utils": "^1.0.0-rc.3",
|
|
28
32
|
"events": "^3.3.0",
|
|
29
33
|
"lodash-es": "^4.17.21",
|
|
30
|
-
"moveable": "^0.
|
|
34
|
+
"moveable": "^0.29.4",
|
|
31
35
|
"moveable-helper": "^0.4.0"
|
|
32
36
|
},
|
|
33
37
|
"devDependencies": {
|
|
@@ -39,5 +43,5 @@
|
|
|
39
43
|
"vite": "^2.3.7",
|
|
40
44
|
"vite-plugin-dts": "^0.9.6"
|
|
41
45
|
},
|
|
42
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "d9f6ca25a0a6efba35d183e643a306e164b74af7"
|
|
43
47
|
}
|
package/src/StageCore.ts
CHANGED
|
@@ -61,10 +61,14 @@ export default class StageCore extends EventEmitter {
|
|
|
61
61
|
this.renderer = new StageRender({ core: this });
|
|
62
62
|
this.mask = new StageMask({ core: this });
|
|
63
63
|
this.dr = new StageDragResize({ core: this, container: this.mask.content });
|
|
64
|
-
this.highlightLayer = new StageHighlight({ core: this, container: this.mask.
|
|
64
|
+
this.highlightLayer = new StageHighlight({ core: this, container: this.mask.wrapper });
|
|
65
65
|
|
|
66
|
-
this.renderer.on('runtime-ready', (runtime: Runtime) =>
|
|
67
|
-
|
|
66
|
+
this.renderer.on('runtime-ready', (runtime: Runtime) => {
|
|
67
|
+
this.emit('runtime-ready', runtime);
|
|
68
|
+
});
|
|
69
|
+
this.renderer.on('page-el-update', (el: HTMLElement) => {
|
|
70
|
+
this.mask?.observe(el);
|
|
71
|
+
});
|
|
68
72
|
|
|
69
73
|
this.mask
|
|
70
74
|
.on('beforeSelect', (event: MouseEvent) => {
|
|
@@ -79,6 +83,10 @@ export default class StageCore extends EventEmitter {
|
|
|
79
83
|
})
|
|
80
84
|
.on('highlight', async (event: MouseEvent) => {
|
|
81
85
|
await this.setElementFromPoint(event);
|
|
86
|
+
if (this.highlightedDom === this.selectedDom) {
|
|
87
|
+
this.highlightLayer.clearHighlight();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
82
90
|
this.highlightLayer.highlight(this.highlightedDom as HTMLElement);
|
|
83
91
|
this.emit('highlight', this.highlightedDom);
|
|
84
92
|
})
|
|
@@ -116,7 +124,7 @@ export default class StageCore extends EventEmitter {
|
|
|
116
124
|
let stopped = false;
|
|
117
125
|
const stop = () => (stopped = true);
|
|
118
126
|
for (const el of els) {
|
|
119
|
-
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && (await this.canSelect(el, stop))) {
|
|
127
|
+
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && (await this.canSelect(el, event, stop))) {
|
|
120
128
|
if (stopped) break;
|
|
121
129
|
if (event.type === 'mousemove') {
|
|
122
130
|
this.highlight(el);
|
|
@@ -139,18 +147,25 @@ export default class StageCore extends EventEmitter {
|
|
|
139
147
|
|
|
140
148
|
const runtime = await this.renderer.getRuntime();
|
|
141
149
|
|
|
150
|
+
await runtime?.select?.(el.id);
|
|
151
|
+
|
|
142
152
|
if (runtime?.beforeSelect) {
|
|
143
153
|
await runtime.beforeSelect(el);
|
|
144
154
|
}
|
|
145
155
|
|
|
146
156
|
this.mask.setLayout(el);
|
|
147
|
-
this.dr
|
|
157
|
+
this.dr.select(el, event);
|
|
158
|
+
|
|
159
|
+
if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
|
|
160
|
+
this.mask.intersectionObserver?.observe(el);
|
|
161
|
+
}
|
|
162
|
+
|
|
148
163
|
this.selectedDom = el;
|
|
149
164
|
|
|
150
165
|
if (this.renderer.contentWindow) {
|
|
151
166
|
removeSelectedClassName(this.renderer.contentWindow.document);
|
|
152
167
|
if (this.selectedDom) {
|
|
153
|
-
addSelectedClassName(this.selectedDom);
|
|
168
|
+
addSelectedClassName(this.selectedDom, this.renderer.contentWindow.document);
|
|
154
169
|
}
|
|
155
170
|
}
|
|
156
171
|
}
|
|
@@ -159,18 +174,20 @@ export default class StageCore extends EventEmitter {
|
|
|
159
174
|
* 更新选中的节点
|
|
160
175
|
* @param data 更新的数据
|
|
161
176
|
*/
|
|
162
|
-
public update(data: UpdateData): void {
|
|
177
|
+
public update(data: UpdateData): Promise<void> {
|
|
163
178
|
const { config } = data;
|
|
164
179
|
|
|
165
|
-
this.renderer?.getRuntime().then((runtime) => {
|
|
180
|
+
return this.renderer?.getRuntime().then((runtime) => {
|
|
166
181
|
runtime?.update?.(data);
|
|
167
182
|
// 更新配置后,需要等组件渲染更新
|
|
168
183
|
setTimeout(() => {
|
|
169
184
|
const el = this.renderer.contentWindow?.document.getElementById(`${config.id}`);
|
|
170
|
-
|
|
185
|
+
// 有可能dom已经重新渲染,不再是原来的dom了,所以这里判断id,而不是判断el === this.selectedDom
|
|
186
|
+
if (el && el.id === this.selectedDom?.id) {
|
|
187
|
+
this.selectedDom = el;
|
|
171
188
|
// 更新了组件的布局,需要重新设置mask是否可以滚动
|
|
172
189
|
this.mask.setLayout(el);
|
|
173
|
-
this.dr
|
|
190
|
+
this.dr.updateMoveable(el);
|
|
174
191
|
}
|
|
175
192
|
}, 0);
|
|
176
193
|
});
|
|
@@ -181,22 +198,28 @@ export default class StageCore extends EventEmitter {
|
|
|
181
198
|
* @param el 页面Dom节点
|
|
182
199
|
*/
|
|
183
200
|
public async highlight(idOrEl: HTMLElement | Id): Promise<void> {
|
|
184
|
-
|
|
201
|
+
let el;
|
|
202
|
+
try {
|
|
203
|
+
el = await this.getTargetElement(idOrEl);
|
|
204
|
+
} catch (error) {
|
|
205
|
+
this.highlightLayer.clearHighlight();
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
185
208
|
if (el === this.highlightedDom) return;
|
|
186
209
|
this.highlightLayer.highlight(el);
|
|
187
210
|
this.highlightedDom = el;
|
|
188
211
|
}
|
|
189
212
|
|
|
190
|
-
public sortNode(data: SortEventData): void {
|
|
191
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
|
|
213
|
+
public sortNode(data: SortEventData): Promise<void> {
|
|
214
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
|
|
192
215
|
}
|
|
193
216
|
|
|
194
|
-
public add(data: UpdateData): void {
|
|
195
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.add?.(data));
|
|
217
|
+
public add(data: UpdateData): Promise<void> {
|
|
218
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.add?.(data));
|
|
196
219
|
}
|
|
197
220
|
|
|
198
|
-
public remove(data: RemoveData): void {
|
|
199
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.remove?.(data));
|
|
221
|
+
public remove(data: RemoveData): Promise<void> {
|
|
222
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.remove?.(data));
|
|
200
223
|
}
|
|
201
224
|
|
|
202
225
|
public setZoom(zoom: number = DEFAULT_ZOOM): void {
|
|
@@ -242,14 +265,11 @@ export default class StageCore extends EventEmitter {
|
|
|
242
265
|
}
|
|
243
266
|
|
|
244
267
|
private async getTargetElement(idOrEl: Id | HTMLElement): Promise<HTMLElement> {
|
|
245
|
-
let el;
|
|
246
268
|
if (typeof idOrEl === 'string' || typeof idOrEl === 'number') {
|
|
247
|
-
const
|
|
248
|
-
el = await runtime?.select?.(`${idOrEl}`);
|
|
269
|
+
const el = this.renderer.contentWindow?.document.getElementById(`${idOrEl}`);
|
|
249
270
|
if (!el) throw new Error(`不存在ID为${idOrEl}的元素`);
|
|
250
|
-
|
|
251
|
-
el = idOrEl;
|
|
271
|
+
return el;
|
|
252
272
|
}
|
|
253
|
-
return
|
|
273
|
+
return idOrEl;
|
|
254
274
|
}
|
|
255
275
|
}
|
package/src/StageDragResize.ts
CHANGED
|
@@ -23,9 +23,9 @@ 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 } from './const';
|
|
27
27
|
import StageCore from './StageCore';
|
|
28
|
-
import type { SortEventData, StageDragResizeConfig } from './types';
|
|
28
|
+
import type { Offset, Runtime, SortEventData, StageDragResizeConfig } from './types';
|
|
29
29
|
import { getAbsolutePosition, getMode, getOffset } from './util';
|
|
30
30
|
|
|
31
31
|
enum ActionStatus {
|
|
@@ -41,15 +41,16 @@ export default class StageDragResize extends EventEmitter {
|
|
|
41
41
|
public core: StageCore;
|
|
42
42
|
public container: HTMLElement;
|
|
43
43
|
public target?: HTMLElement;
|
|
44
|
-
public dragEl
|
|
44
|
+
public dragEl: HTMLElement;
|
|
45
45
|
public moveable?: Moveable;
|
|
46
46
|
public horizontalGuidelines: number[] = [];
|
|
47
47
|
public verticalGuidelines: number[] = [];
|
|
48
|
+
public elementGuidelines: HTMLElement[] = [];
|
|
49
|
+
public mode: Mode = Mode.ABSOLUTE;
|
|
48
50
|
|
|
49
51
|
private moveableOptions: MoveableOptions = {};
|
|
50
52
|
private dragStatus: ActionStatus = ActionStatus.END;
|
|
51
53
|
private ghostEl: HTMLElement | undefined;
|
|
52
|
-
private mode: Mode = Mode.ABSOLUTE;
|
|
53
54
|
private moveableHelper?: MoveableHelper;
|
|
54
55
|
|
|
55
56
|
constructor(config: StageDragResizeConfig) {
|
|
@@ -57,6 +58,9 @@ export default class StageDragResize extends EventEmitter {
|
|
|
57
58
|
|
|
58
59
|
this.core = config.core;
|
|
59
60
|
this.container = config.container;
|
|
61
|
+
|
|
62
|
+
this.dragEl = globalThis.document.createElement('div');
|
|
63
|
+
this.container.append(this.dragEl);
|
|
60
64
|
}
|
|
61
65
|
|
|
62
66
|
/**
|
|
@@ -65,29 +69,24 @@ export default class StageDragResize extends EventEmitter {
|
|
|
65
69
|
* @param el 选中组件的Dom节点元素
|
|
66
70
|
* @param event 鼠标事件
|
|
67
71
|
*/
|
|
68
|
-
public
|
|
72
|
+
public select(el: HTMLElement, event?: MouseEvent): void {
|
|
73
|
+
const oldTarget = this.target;
|
|
69
74
|
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
75
|
|
|
78
|
-
this.
|
|
76
|
+
this.init(el);
|
|
79
77
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
createAuto: true,
|
|
88
|
-
});
|
|
78
|
+
// 从不能拖动到能拖动的节点之间切换,要重新创建moveable,不然dragStart不生效
|
|
79
|
+
if (!this.moveable || this.target !== oldTarget) {
|
|
80
|
+
this.moveableHelper = MoveableHelper.create({
|
|
81
|
+
useBeforeRender: true,
|
|
82
|
+
useRender: false,
|
|
83
|
+
createAuto: true,
|
|
84
|
+
});
|
|
89
85
|
|
|
90
|
-
|
|
86
|
+
this.initMoveable();
|
|
87
|
+
} else {
|
|
88
|
+
this.updateMoveable();
|
|
89
|
+
}
|
|
91
90
|
|
|
92
91
|
if (event) {
|
|
93
92
|
this.moveable?.dragStart(event);
|
|
@@ -97,11 +96,15 @@ export default class StageDragResize extends EventEmitter {
|
|
|
97
96
|
/**
|
|
98
97
|
* 初始化选中框并渲染出来
|
|
99
98
|
*/
|
|
100
|
-
public
|
|
99
|
+
public updateMoveable(el = this.target): void {
|
|
101
100
|
if (!this.moveable) throw new Error('未初始化moveable');
|
|
101
|
+
if (!el) throw new Error('为选中任何节点');
|
|
102
|
+
|
|
103
|
+
this.target = el;
|
|
102
104
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
this.init(el);
|
|
106
|
+
|
|
107
|
+
Object.entries(this.moveableOptions).forEach(([key, value]) => {
|
|
105
108
|
(this.moveable as any)[key] = value;
|
|
106
109
|
});
|
|
107
110
|
this.moveable.updateTarget();
|
|
@@ -110,17 +113,21 @@ export default class StageDragResize extends EventEmitter {
|
|
|
110
113
|
public setGuidelines(type: GuidesType, guidelines: number[]): void {
|
|
111
114
|
if (type === GuidesType.HORIZONTAL) {
|
|
112
115
|
this.horizontalGuidelines = guidelines;
|
|
116
|
+
this.moveableOptions.horizontalGuidelines = guidelines;
|
|
113
117
|
} else if (type === GuidesType.VERTICAL) {
|
|
114
118
|
this.verticalGuidelines = guidelines;
|
|
119
|
+
this.moveableOptions.verticalGuidelines = guidelines;
|
|
115
120
|
}
|
|
116
121
|
|
|
117
|
-
this.
|
|
122
|
+
this.updateMoveable();
|
|
118
123
|
}
|
|
119
124
|
|
|
120
125
|
public clearGuides() {
|
|
121
|
-
this.verticalGuidelines = [];
|
|
122
126
|
this.horizontalGuidelines = [];
|
|
123
|
-
this.
|
|
127
|
+
this.verticalGuidelines = [];
|
|
128
|
+
this.moveableOptions.horizontalGuidelines = [];
|
|
129
|
+
this.moveableOptions.verticalGuidelines = [];
|
|
130
|
+
this.updateMoveable();
|
|
124
131
|
}
|
|
125
132
|
|
|
126
133
|
/**
|
|
@@ -134,6 +141,22 @@ export default class StageDragResize extends EventEmitter {
|
|
|
134
141
|
this.removeAllListeners();
|
|
135
142
|
}
|
|
136
143
|
|
|
144
|
+
private init(el: HTMLElement): void {
|
|
145
|
+
// 如果有滚动条会导致resize时获取到width,height不准确
|
|
146
|
+
if (/(auto|scroll)/.test(el.style.overflow)) {
|
|
147
|
+
el.style.overflow = 'hidden';
|
|
148
|
+
}
|
|
149
|
+
this.mode = getMode(el);
|
|
150
|
+
|
|
151
|
+
this.destroyGhostEl();
|
|
152
|
+
|
|
153
|
+
this.updateDragEl(el);
|
|
154
|
+
|
|
155
|
+
this.moveableOptions = this.getOptions({
|
|
156
|
+
target: this.dragEl,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
137
160
|
private initMoveable() {
|
|
138
161
|
this.moveable?.destroy();
|
|
139
162
|
|
|
@@ -196,10 +219,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
196
219
|
private bindDragEvent(): void {
|
|
197
220
|
if (!this.moveable) throw new Error('moveable 为初始化');
|
|
198
221
|
|
|
199
|
-
let offset =
|
|
200
|
-
left: 0,
|
|
201
|
-
top: 0,
|
|
202
|
-
};
|
|
222
|
+
let offset: Offset | null = null;
|
|
203
223
|
|
|
204
224
|
this.moveable
|
|
205
225
|
.on('dragStart', (e) => {
|
|
@@ -209,14 +229,17 @@ export default class StageDragResize extends EventEmitter {
|
|
|
209
229
|
|
|
210
230
|
this.moveableHelper?.onDragStart(e);
|
|
211
231
|
|
|
212
|
-
offset = getAbsolutePosition(this.target, { left: 0, top: 0 });
|
|
213
|
-
|
|
214
232
|
if (this.mode === Mode.SORTABLE) {
|
|
215
233
|
this.ghostEl = this.generateGhostEl(this.target);
|
|
216
234
|
}
|
|
217
235
|
})
|
|
218
236
|
.on('drag', (e) => {
|
|
219
237
|
if (!this.target || !this.dragEl) return;
|
|
238
|
+
|
|
239
|
+
if (!offset) {
|
|
240
|
+
offset = getAbsolutePosition(this.target, { left: 0, top: 0 });
|
|
241
|
+
}
|
|
242
|
+
|
|
220
243
|
this.dragStatus = ActionStatus.ING;
|
|
221
244
|
|
|
222
245
|
const { left, top } = e;
|
|
@@ -244,24 +267,23 @@ export default class StageDragResize extends EventEmitter {
|
|
|
244
267
|
this.update();
|
|
245
268
|
}
|
|
246
269
|
}
|
|
270
|
+
offset = null;
|
|
247
271
|
|
|
248
272
|
this.dragStatus = ActionStatus.END;
|
|
249
273
|
this.destroyGhostEl();
|
|
250
274
|
});
|
|
251
275
|
}
|
|
252
276
|
|
|
253
|
-
private
|
|
254
|
-
const { renderer } = this.core;
|
|
277
|
+
private getSnapElements(runtime: Runtime, el?: HTMLElement): HTMLElement[] {
|
|
278
|
+
const { renderer, mask } = this.core;
|
|
255
279
|
const getSnapElements =
|
|
256
|
-
|
|
280
|
+
runtime?.getSnapElements ||
|
|
257
281
|
(() => {
|
|
258
282
|
const doc = renderer.contentWindow?.document;
|
|
259
283
|
return doc ? Array.from(doc.querySelectorAll('[id]')) : [];
|
|
260
284
|
});
|
|
261
|
-
return (
|
|
262
|
-
|
|
263
|
-
// 排除掉当前组件本身
|
|
264
|
-
.filter((element) => element !== this.target && !this.target?.contains(element))
|
|
285
|
+
return getSnapElements(el).filter(
|
|
286
|
+
(element) => element !== this.target && !this.target?.contains(element) && element !== mask.page,
|
|
265
287
|
);
|
|
266
288
|
}
|
|
267
289
|
|
|
@@ -307,7 +329,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
307
329
|
|
|
308
330
|
const ghostEl = el.cloneNode(true) as HTMLElement;
|
|
309
331
|
const { top, left } = getAbsolutePosition(el, getOffset(el));
|
|
310
|
-
ghostEl.id = `${GHOST_EL_ID_PREFIX}${
|
|
332
|
+
ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
|
|
311
333
|
ghostEl.style.zIndex = '5';
|
|
312
334
|
ghostEl.style.opacity = '.5';
|
|
313
335
|
ghostEl.style.position = 'absolute';
|
|
@@ -322,34 +344,31 @@ export default class StageDragResize extends EventEmitter {
|
|
|
322
344
|
this.ghostEl = undefined;
|
|
323
345
|
}
|
|
324
346
|
|
|
325
|
-
private
|
|
326
|
-
if (this.dragEl) {
|
|
327
|
-
this.destroyDragEl();
|
|
328
|
-
}
|
|
329
|
-
|
|
347
|
+
private updateDragEl(el: HTMLElement) {
|
|
330
348
|
const { width, height } = el.getBoundingClientRect();
|
|
331
349
|
const offset = getOffset(el);
|
|
332
|
-
|
|
333
|
-
dragEl.style.cssText = `
|
|
350
|
+
|
|
351
|
+
this.dragEl.style.cssText = `
|
|
334
352
|
position: absolute;
|
|
335
353
|
left: ${offset.left}px;
|
|
336
354
|
top: ${offset.top}px;
|
|
337
355
|
width: ${width}px;
|
|
338
356
|
height: ${height}px;
|
|
357
|
+
z-index: 9;
|
|
339
358
|
`;
|
|
340
|
-
|
|
341
|
-
|
|
359
|
+
|
|
360
|
+
this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
|
|
342
361
|
}
|
|
343
362
|
|
|
344
363
|
private destroyDragEl(): void {
|
|
345
364
|
this.dragEl?.remove();
|
|
346
|
-
this.dragEl = undefined;
|
|
347
365
|
}
|
|
348
366
|
|
|
349
|
-
private
|
|
367
|
+
private getOptions(options: MoveableOptions = {}): MoveableOptions {
|
|
350
368
|
if (!this.target) return {};
|
|
351
369
|
|
|
352
370
|
const isAbsolute = this.mode === Mode.ABSOLUTE;
|
|
371
|
+
const isFixed = this.mode === Mode.FIXED;
|
|
353
372
|
|
|
354
373
|
let { moveableOptions = {} } = this.core.config;
|
|
355
374
|
|
|
@@ -358,14 +377,14 @@ export default class StageDragResize extends EventEmitter {
|
|
|
358
377
|
}
|
|
359
378
|
|
|
360
379
|
return {
|
|
361
|
-
origin:
|
|
380
|
+
origin: false,
|
|
362
381
|
rootContainer: this.core.container,
|
|
363
382
|
zoom: 1,
|
|
364
383
|
dragArea: false,
|
|
365
384
|
draggable: true,
|
|
366
385
|
resizable: true,
|
|
367
|
-
snappable: isAbsolute,
|
|
368
|
-
snapGap: isAbsolute,
|
|
386
|
+
snappable: isAbsolute || isFixed,
|
|
387
|
+
snapGap: isAbsolute || isFixed,
|
|
369
388
|
snapThreshold: 5,
|
|
370
389
|
snapDigit: 0,
|
|
371
390
|
throttleDrag: 0,
|
|
@@ -378,8 +397,16 @@ export default class StageDragResize extends EventEmitter {
|
|
|
378
397
|
center: isAbsolute,
|
|
379
398
|
middle: isAbsolute,
|
|
380
399
|
},
|
|
400
|
+
elementSnapDirections: {
|
|
401
|
+
top: isAbsolute,
|
|
402
|
+
right: isAbsolute,
|
|
403
|
+
bottom: isAbsolute,
|
|
404
|
+
left: isAbsolute,
|
|
405
|
+
},
|
|
406
|
+
isDisplayInnerSnapDigit: true,
|
|
381
407
|
horizontalGuidelines: this.horizontalGuidelines,
|
|
382
408
|
verticalGuidelines: this.verticalGuidelines,
|
|
409
|
+
elementGuidelines: this.elementGuidelines,
|
|
383
410
|
|
|
384
411
|
bounds: {
|
|
385
412
|
top: 0,
|
package/src/StageHighlight.ts
CHANGED
|
@@ -21,19 +21,27 @@ 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
|
+
});
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
/**
|
|
@@ -44,8 +52,12 @@ export default class StageHighlight extends EventEmitter {
|
|
|
44
52
|
if (!el || el === this.target) return;
|
|
45
53
|
this.target = el;
|
|
46
54
|
this.moveable?.destroy();
|
|
55
|
+
|
|
47
56
|
this.moveable = new Moveable(this.container, {
|
|
48
|
-
target: this.
|
|
57
|
+
target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
|
|
58
|
+
origin: false,
|
|
59
|
+
rootContainer: this.core.container,
|
|
60
|
+
zoom: 1,
|
|
49
61
|
});
|
|
50
62
|
}
|
|
51
63
|
|
|
@@ -54,6 +66,7 @@ export default class StageHighlight extends EventEmitter {
|
|
|
54
66
|
*/
|
|
55
67
|
public clearHighlight(): void {
|
|
56
68
|
if (!this.moveable) return;
|
|
69
|
+
this.target = undefined;
|
|
57
70
|
this.moveable.target = null;
|
|
58
71
|
this.moveable.updateTarget();
|
|
59
72
|
}
|
|
@@ -63,5 +76,6 @@ export default class StageHighlight extends EventEmitter {
|
|
|
63
76
|
*/
|
|
64
77
|
public destroy(): void {
|
|
65
78
|
this.moveable?.destroy();
|
|
79
|
+
this.calibrationTarget.destroy();
|
|
66
80
|
}
|
|
67
81
|
}
|