@tmagic/stage 1.0.0-beta.9 → 1.0.0-rc.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/tmagic-stage.es.js +516 -297
- package/dist/tmagic-stage.es.js.map +1 -1
- package/dist/tmagic-stage.umd.js +517 -299
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/dist/types/src/StageCore.d.ts +4 -4
- package/dist/types/src/StageDragResize.d.ts +21 -7
- package/dist/types/src/StageHighlight.d.ts +2 -0
- package/dist/types/src/StageMask.d.ts +18 -0
- package/dist/types/src/TargetCalibrate.d.ts +20 -0
- package/dist/types/src/const.d.ts +26 -1
- package/dist/types/src/types.d.ts +22 -6
- package/dist/types/src/util.d.ts +3 -2
- package/package.json +12 -8
- package/src/Rule.ts +13 -5
- package/src/StageCore.ts +43 -23
- package/src/StageDragResize.ts +214 -98
- package/src/StageHighlight.ts +16 -1
- package/src/StageMask.ts +93 -27
- package/src/StageRender.ts +4 -16
- package/src/TargetCalibrate.ts +119 -0
- package/src/const.ts +28 -2
- package/src/types.ts +23 -6
- package/src/util.ts +40 -29
- package/LICENSE +0 -5432
- package/tsconfig.json +0 -9
- package/vite.config.ts +0 -27
package/dist/tmagic-stage.umd.js
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
var Guides__default = /*#__PURE__*/_interopDefaultLegacy(Guides);
|
|
13
13
|
|
|
14
14
|
const GHOST_EL_ID_PREFIX = "ghost_el_";
|
|
15
|
+
const DRAG_EL_ID_PREFIX = "drag_el_";
|
|
16
|
+
const HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
|
|
15
17
|
const DEFAULT_ZOOM = 1;
|
|
16
18
|
var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
|
|
17
19
|
GuidesType2["HORIZONTAL"] = "horizontal";
|
|
@@ -21,6 +23,8 @@
|
|
|
21
23
|
var ZIndex = /* @__PURE__ */ ((ZIndex2) => {
|
|
22
24
|
ZIndex2["MASK"] = "99999";
|
|
23
25
|
ZIndex2["SELECTED_EL"] = "666";
|
|
26
|
+
ZIndex2["GHOST_EL"] = "700";
|
|
27
|
+
ZIndex2["DRAG_EL"] = "9";
|
|
24
28
|
return ZIndex2;
|
|
25
29
|
})(ZIndex || {});
|
|
26
30
|
var MouseButton = /* @__PURE__ */ ((MouseButton2) => {
|
|
@@ -36,31 +40,22 @@
|
|
|
36
40
|
return Mode2;
|
|
37
41
|
})(Mode || {});
|
|
38
42
|
const SELECTED_CLASS = "tmagic-stage-selected-area";
|
|
43
|
+
const H_GUIDE_LINE_STORAGE_KEY = "$MagicStageHorizontalGuidelinesData";
|
|
44
|
+
const V_GUIDE_LINE_STORAGE_KEY = "$MagicStageVerticalGuidelinesData";
|
|
39
45
|
|
|
46
|
+
const getParents = (el, relative) => {
|
|
47
|
+
let cur = el.parentElement;
|
|
48
|
+
const parents = [];
|
|
49
|
+
while (cur && cur !== relative) {
|
|
50
|
+
parents.push(cur);
|
|
51
|
+
cur = cur.parentElement;
|
|
52
|
+
}
|
|
53
|
+
return parents;
|
|
54
|
+
};
|
|
40
55
|
const getOffset = (el) => {
|
|
41
|
-
const { transform } = getComputedStyle(el);
|
|
42
56
|
const { offsetParent } = el;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (transform.indexOf("matrix") > -1) {
|
|
46
|
-
let a = 1;
|
|
47
|
-
let b = 1;
|
|
48
|
-
let c = 1;
|
|
49
|
-
let d = 1;
|
|
50
|
-
let e = 0;
|
|
51
|
-
let f = 0;
|
|
52
|
-
transform.replace(/matrix\((.+), (.+), (.+), (.+), (.+), (.+)\)/, ($0, $1, $2, $3, $4, $5, $6) => {
|
|
53
|
-
a = +$1;
|
|
54
|
-
b = +$2;
|
|
55
|
-
c = +$3;
|
|
56
|
-
d = +$4;
|
|
57
|
-
e = +$5;
|
|
58
|
-
f = +$6;
|
|
59
|
-
return transform;
|
|
60
|
-
});
|
|
61
|
-
left = a * left + c * top + e;
|
|
62
|
-
top = b * left + d * top + f;
|
|
63
|
-
}
|
|
57
|
+
const left = el.offsetLeft;
|
|
58
|
+
const top = el.offsetTop;
|
|
64
59
|
if (offsetParent) {
|
|
65
60
|
const parentOffset = getOffset(offsetParent);
|
|
66
61
|
return {
|
|
@@ -161,58 +156,76 @@
|
|
|
161
156
|
if (oldEl) {
|
|
162
157
|
oldEl.classList.remove(SELECTED_CLASS);
|
|
163
158
|
oldEl.parentNode?.classList.remove(`${SELECTED_CLASS}-parent`);
|
|
159
|
+
doc.querySelectorAll(`.${SELECTED_CLASS}-parents`).forEach((item) => {
|
|
160
|
+
item.classList.remove(`${SELECTED_CLASS}-parents`);
|
|
161
|
+
});
|
|
164
162
|
}
|
|
165
163
|
};
|
|
166
|
-
const addSelectedClassName = (el) => {
|
|
164
|
+
const addSelectedClassName = (el, doc) => {
|
|
167
165
|
el.classList.add(SELECTED_CLASS);
|
|
168
166
|
el.parentNode?.classList.add(`${SELECTED_CLASS}-parent`);
|
|
167
|
+
getParents(el, doc.body).forEach((item) => {
|
|
168
|
+
item.classList.add(`${SELECTED_CLASS}-parents`);
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
const getGuideLineFromCache = (type) => {
|
|
172
|
+
const key = {
|
|
173
|
+
[GuidesType.HORIZONTAL]: H_GUIDE_LINE_STORAGE_KEY,
|
|
174
|
+
[GuidesType.VERTICAL]: V_GUIDE_LINE_STORAGE_KEY
|
|
175
|
+
}[type];
|
|
176
|
+
if (!key)
|
|
177
|
+
return [];
|
|
178
|
+
const guideLineCacheData = globalThis.localStorage.getItem(key);
|
|
179
|
+
if (guideLineCacheData) {
|
|
180
|
+
try {
|
|
181
|
+
return JSON.parse(guideLineCacheData) || [];
|
|
182
|
+
} catch (e) {
|
|
183
|
+
console.error(e);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return [];
|
|
169
187
|
};
|
|
170
188
|
|
|
171
189
|
class StageDragResize extends EventEmitter.EventEmitter {
|
|
172
|
-
core;
|
|
173
|
-
container;
|
|
174
|
-
target;
|
|
175
|
-
dragEl;
|
|
176
|
-
moveable;
|
|
177
|
-
horizontalGuidelines = [];
|
|
178
|
-
verticalGuidelines = [];
|
|
179
|
-
moveableOptions = {};
|
|
180
|
-
dragStatus = "end" /* END */;
|
|
181
|
-
ghostEl;
|
|
182
|
-
mode = Mode.ABSOLUTE;
|
|
183
|
-
moveableHelper;
|
|
184
190
|
constructor(config) {
|
|
185
191
|
super();
|
|
192
|
+
this.horizontalGuidelines = getGuideLineFromCache(GuidesType.HORIZONTAL);
|
|
193
|
+
this.verticalGuidelines = getGuideLineFromCache(GuidesType.VERTICAL);
|
|
194
|
+
this.elementGuidelines = [];
|
|
195
|
+
this.mode = Mode.ABSOLUTE;
|
|
196
|
+
this.moveableOptions = {};
|
|
197
|
+
this.dragStatus = "end" /* END */;
|
|
186
198
|
this.core = config.core;
|
|
187
199
|
this.container = config.container;
|
|
200
|
+
this.dragEl = globalThis.document.createElement("div");
|
|
201
|
+
this.container.append(this.dragEl);
|
|
188
202
|
}
|
|
189
|
-
|
|
203
|
+
select(el, event) {
|
|
204
|
+
const oldTarget = this.target;
|
|
190
205
|
this.target = el;
|
|
191
|
-
if (
|
|
192
|
-
this.
|
|
206
|
+
if (!this.moveable || this.target !== oldTarget) {
|
|
207
|
+
this.init(el);
|
|
208
|
+
this.moveableHelper = MoveableHelper__default["default"].create({
|
|
209
|
+
useBeforeRender: true,
|
|
210
|
+
useRender: false,
|
|
211
|
+
createAuto: true
|
|
212
|
+
});
|
|
213
|
+
this.initMoveable();
|
|
214
|
+
} else {
|
|
215
|
+
this.updateMoveable();
|
|
193
216
|
}
|
|
194
|
-
this.mode = getMode(el);
|
|
195
|
-
this.destroyDragEl();
|
|
196
|
-
this.destroyGhostEl();
|
|
197
|
-
this.dragEl = this.generateDragEl(el);
|
|
198
|
-
this.moveableOptions = await this.getOptions({
|
|
199
|
-
target: this.dragEl || this.target
|
|
200
|
-
});
|
|
201
|
-
this.moveableHelper = MoveableHelper__default["default"].create({
|
|
202
|
-
useBeforeRender: true,
|
|
203
|
-
useRender: false,
|
|
204
|
-
createAuto: true
|
|
205
|
-
});
|
|
206
|
-
this.initMoveable();
|
|
207
217
|
if (event) {
|
|
208
218
|
this.moveable?.dragStart(event);
|
|
209
219
|
}
|
|
210
220
|
}
|
|
211
|
-
|
|
221
|
+
updateMoveable(el = this.target) {
|
|
212
222
|
if (!this.moveable)
|
|
213
223
|
throw new Error("\u672A\u521D\u59CB\u5316moveable");
|
|
214
|
-
|
|
215
|
-
|
|
224
|
+
if (!el)
|
|
225
|
+
throw new Error("\u4E3A\u9009\u4E2D\u4EFB\u4F55\u8282\u70B9");
|
|
226
|
+
this.target = el;
|
|
227
|
+
this.init(el);
|
|
228
|
+
Object.entries(this.moveableOptions).forEach(([key, value]) => {
|
|
216
229
|
this.moveable[key] = value;
|
|
217
230
|
});
|
|
218
231
|
this.moveable.updateTarget();
|
|
@@ -220,15 +233,19 @@
|
|
|
220
233
|
setGuidelines(type, guidelines) {
|
|
221
234
|
if (type === GuidesType.HORIZONTAL) {
|
|
222
235
|
this.horizontalGuidelines = guidelines;
|
|
236
|
+
this.moveableOptions.horizontalGuidelines = guidelines;
|
|
223
237
|
} else if (type === GuidesType.VERTICAL) {
|
|
224
238
|
this.verticalGuidelines = guidelines;
|
|
239
|
+
this.moveableOptions.verticalGuidelines = guidelines;
|
|
225
240
|
}
|
|
226
|
-
this.
|
|
241
|
+
this.updateMoveable();
|
|
227
242
|
}
|
|
228
243
|
clearGuides() {
|
|
229
|
-
this.verticalGuidelines = [];
|
|
230
244
|
this.horizontalGuidelines = [];
|
|
231
|
-
this.
|
|
245
|
+
this.verticalGuidelines = [];
|
|
246
|
+
this.moveableOptions.horizontalGuidelines = [];
|
|
247
|
+
this.moveableOptions.verticalGuidelines = [];
|
|
248
|
+
this.updateMoveable();
|
|
232
249
|
}
|
|
233
250
|
destroy() {
|
|
234
251
|
this.moveable?.destroy();
|
|
@@ -237,6 +254,37 @@
|
|
|
237
254
|
this.dragStatus = "end" /* END */;
|
|
238
255
|
this.removeAllListeners();
|
|
239
256
|
}
|
|
257
|
+
init(el) {
|
|
258
|
+
if (/(auto|scroll)/.test(el.style.overflow)) {
|
|
259
|
+
el.style.overflow = "hidden";
|
|
260
|
+
}
|
|
261
|
+
this.mode = getMode(el);
|
|
262
|
+
this.destroyGhostEl();
|
|
263
|
+
this.updateDragEl(el);
|
|
264
|
+
this.moveableOptions = this.getOptions({
|
|
265
|
+
target: this.dragEl
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
setElementGuidelines(nodes) {
|
|
269
|
+
this.elementGuidelines.forEach((node) => {
|
|
270
|
+
node.remove();
|
|
271
|
+
});
|
|
272
|
+
this.elementGuidelines = [];
|
|
273
|
+
if (this.mode === Mode.ABSOLUTE) {
|
|
274
|
+
const frame = document.createDocumentFragment();
|
|
275
|
+
for (const node of nodes) {
|
|
276
|
+
const { width, height } = node.getBoundingClientRect();
|
|
277
|
+
if (node === this.target)
|
|
278
|
+
continue;
|
|
279
|
+
const { left, top } = getOffset(node);
|
|
280
|
+
const elementGuideline = document.createElement("div");
|
|
281
|
+
elementGuideline.style.cssText = `position: absolute;width: ${width}px;height: ${height}px;top: ${top}px;left: ${left}px`;
|
|
282
|
+
this.elementGuidelines.push(elementGuideline);
|
|
283
|
+
frame.append(elementGuideline);
|
|
284
|
+
}
|
|
285
|
+
this.container.append(frame);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
240
288
|
initMoveable() {
|
|
241
289
|
this.moveable?.destroy();
|
|
242
290
|
this.moveable = new Moveable__default["default"](this.container, {
|
|
@@ -244,35 +292,38 @@
|
|
|
244
292
|
});
|
|
245
293
|
this.bindResizeEvent();
|
|
246
294
|
this.bindDragEvent();
|
|
295
|
+
this.bindRotateEvent();
|
|
296
|
+
this.bindScaleEvent();
|
|
247
297
|
}
|
|
248
298
|
bindResizeEvent() {
|
|
249
299
|
if (!this.moveable)
|
|
250
300
|
throw new Error("moveable \u4E3A\u521D\u59CB\u5316");
|
|
301
|
+
const frame = {
|
|
302
|
+
left: 0,
|
|
303
|
+
top: 0
|
|
304
|
+
};
|
|
251
305
|
this.moveable.on("resizeStart", (e) => {
|
|
252
|
-
if (
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
306
|
+
if (!this.target)
|
|
307
|
+
return;
|
|
308
|
+
this.dragStatus = "start" /* START */;
|
|
309
|
+
this.moveableHelper?.onResizeStart(e);
|
|
310
|
+
frame.top = this.target.offsetTop;
|
|
311
|
+
frame.left = this.target.offsetLeft;
|
|
312
|
+
}).on("resize", (e) => {
|
|
313
|
+
const { width, height, drag } = e;
|
|
258
314
|
if (!this.moveable || !this.target || !this.dragEl)
|
|
259
315
|
return;
|
|
260
316
|
const { beforeTranslate } = drag;
|
|
261
317
|
this.dragStatus = "ing" /* ING */;
|
|
262
|
-
this.
|
|
263
|
-
this.target.style.height = `${height}px`;
|
|
264
|
-
this.dragEl.style.width = `${width}px`;
|
|
265
|
-
this.dragEl.style.height = `${height}px`;
|
|
318
|
+
this.moveableHelper?.onResize(e);
|
|
266
319
|
if (this.mode === Mode.SORTABLE) {
|
|
267
|
-
this.
|
|
268
|
-
|
|
269
|
-
|
|
320
|
+
this.target.style.top = "0px";
|
|
321
|
+
} else {
|
|
322
|
+
this.target.style.left = `${frame.left + beforeTranslate[0]}px`;
|
|
323
|
+
this.target.style.top = `${frame.top + beforeTranslate[1]}px`;
|
|
270
324
|
}
|
|
271
|
-
this.
|
|
272
|
-
this.
|
|
273
|
-
const offset = getAbsolutePosition(this.target, { left: beforeTranslate[0], top: beforeTranslate[1] });
|
|
274
|
-
this.target.style.left = `${offset.left}px`;
|
|
275
|
-
this.target.style.top = `${offset.top}px`;
|
|
325
|
+
this.target.style.width = `${width}px`;
|
|
326
|
+
this.target.style.height = `${height}px`;
|
|
276
327
|
}).on("resizeEnd", () => {
|
|
277
328
|
this.dragStatus = "end" /* END */;
|
|
278
329
|
this.update(true);
|
|
@@ -281,7 +332,7 @@
|
|
|
281
332
|
bindDragEvent() {
|
|
282
333
|
if (!this.moveable)
|
|
283
334
|
throw new Error("moveable \u4E3A\u521D\u59CB\u5316");
|
|
284
|
-
|
|
335
|
+
const frame = {
|
|
285
336
|
left: 0,
|
|
286
337
|
top: 0
|
|
287
338
|
};
|
|
@@ -290,23 +341,22 @@
|
|
|
290
341
|
throw new Error("\u672A\u9009\u4E2D\u7EC4\u4EF6");
|
|
291
342
|
this.dragStatus = "start" /* START */;
|
|
292
343
|
this.moveableHelper?.onDragStart(e);
|
|
293
|
-
offset = getAbsolutePosition(this.target, { left: 0, top: 0 });
|
|
294
344
|
if (this.mode === Mode.SORTABLE) {
|
|
295
345
|
this.ghostEl = this.generateGhostEl(this.target);
|
|
296
346
|
}
|
|
347
|
+
frame.top = this.target.offsetTop;
|
|
348
|
+
frame.left = this.target.offsetLeft;
|
|
297
349
|
}).on("drag", (e) => {
|
|
298
350
|
if (!this.target || !this.dragEl)
|
|
299
351
|
return;
|
|
300
352
|
this.dragStatus = "ing" /* ING */;
|
|
301
|
-
const { left, top } = e;
|
|
302
353
|
if (this.ghostEl) {
|
|
303
|
-
this.
|
|
304
|
-
this.ghostEl.style.top = `${top + offset.top}px`;
|
|
354
|
+
this.ghostEl.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
305
355
|
return;
|
|
306
356
|
}
|
|
307
357
|
this.moveableHelper?.onDrag(e);
|
|
308
|
-
this.target.style.left = `${left +
|
|
309
|
-
this.target.style.top = `${top +
|
|
358
|
+
this.target.style.left = `${frame.left + e.beforeTranslate[0]}px`;
|
|
359
|
+
this.target.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
310
360
|
}).on("dragEnd", () => {
|
|
311
361
|
if (this.dragStatus === "ing" /* ING */) {
|
|
312
362
|
switch (this.mode) {
|
|
@@ -321,13 +371,53 @@
|
|
|
321
371
|
this.destroyGhostEl();
|
|
322
372
|
});
|
|
323
373
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
374
|
+
bindRotateEvent() {
|
|
375
|
+
if (!this.moveable)
|
|
376
|
+
throw new Error("moveable \u4E3A\u521D\u59CB\u5316");
|
|
377
|
+
this.moveable.on("rotateStart", (e) => {
|
|
378
|
+
this.dragStatus = "start" /* START */;
|
|
379
|
+
this.moveableHelper?.onRotateStart(e);
|
|
380
|
+
}).on("rotate", (e) => {
|
|
381
|
+
if (!this.target || !this.dragEl)
|
|
382
|
+
return;
|
|
383
|
+
this.dragStatus = "ing" /* ING */;
|
|
384
|
+
this.moveableHelper?.onRotate(e);
|
|
385
|
+
const frame = this.moveableHelper?.getFrame(e.target);
|
|
386
|
+
this.target.style.transform = frame?.toCSSObject().transform || "";
|
|
387
|
+
}).on("rotateEnd", (e) => {
|
|
388
|
+
this.dragStatus = "end" /* END */;
|
|
389
|
+
const frame = this.moveableHelper?.getFrame(e.target);
|
|
390
|
+
this.emit("update", {
|
|
391
|
+
el: this.target,
|
|
392
|
+
style: {
|
|
393
|
+
transform: frame?.get("transform")
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
bindScaleEvent() {
|
|
399
|
+
if (!this.moveable)
|
|
400
|
+
throw new Error("moveable \u4E3A\u521D\u59CB\u5316");
|
|
401
|
+
this.moveable.on("scaleStart", (e) => {
|
|
402
|
+
this.dragStatus = "start" /* START */;
|
|
403
|
+
this.moveableHelper?.onScaleStart(e);
|
|
404
|
+
}).on("scale", (e) => {
|
|
405
|
+
if (!this.target || !this.dragEl)
|
|
406
|
+
return;
|
|
407
|
+
this.dragStatus = "ing" /* ING */;
|
|
408
|
+
this.moveableHelper?.onScale(e);
|
|
409
|
+
const frame = this.moveableHelper?.getFrame(e.target);
|
|
410
|
+
this.target.style.transform = frame?.toCSSObject().transform || "";
|
|
411
|
+
}).on("scaleEnd", (e) => {
|
|
412
|
+
this.dragStatus = "end" /* END */;
|
|
413
|
+
const frame = this.moveableHelper?.getFrame(e.target);
|
|
414
|
+
this.emit("update", {
|
|
415
|
+
el: this.target,
|
|
416
|
+
style: {
|
|
417
|
+
transform: frame?.get("transform")
|
|
418
|
+
}
|
|
419
|
+
});
|
|
329
420
|
});
|
|
330
|
-
return getSnapElements(el).filter((element) => element !== this.target && !this.target?.contains(element));
|
|
331
421
|
}
|
|
332
422
|
sort() {
|
|
333
423
|
if (!this.target || !this.ghostEl)
|
|
@@ -349,12 +439,13 @@
|
|
|
349
439
|
}
|
|
350
440
|
}
|
|
351
441
|
update(isResize = false) {
|
|
352
|
-
|
|
353
|
-
|
|
442
|
+
if (!this.target)
|
|
443
|
+
return;
|
|
444
|
+
const offset = this.mode === Mode.SORTABLE ? { left: 0, top: 0 } : { left: this.target.offsetLeft, top: this.target.offsetTop };
|
|
354
445
|
const left = this.calcValueByFontsize(offset.left);
|
|
355
446
|
const top = this.calcValueByFontsize(offset.top);
|
|
356
|
-
const width = this.calcValueByFontsize(
|
|
357
|
-
const height = this.calcValueByFontsize(
|
|
447
|
+
const width = this.calcValueByFontsize(this.target.clientWidth);
|
|
448
|
+
const height = this.calcValueByFontsize(this.target.clientHeight);
|
|
358
449
|
this.emit("update", {
|
|
359
450
|
el: this.target,
|
|
360
451
|
style: isResize ? { left, top, width, height } : { left, top }
|
|
@@ -366,8 +457,8 @@
|
|
|
366
457
|
}
|
|
367
458
|
const ghostEl = el.cloneNode(true);
|
|
368
459
|
const { top, left } = getAbsolutePosition(el, getOffset(el));
|
|
369
|
-
ghostEl.id = `${GHOST_EL_ID_PREFIX}${
|
|
370
|
-
ghostEl.style.zIndex =
|
|
460
|
+
ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
|
|
461
|
+
ghostEl.style.zIndex = ZIndex.GHOST_EL;
|
|
371
462
|
ghostEl.style.opacity = ".5";
|
|
372
463
|
ghostEl.style.position = "absolute";
|
|
373
464
|
ghostEl.style.left = `${left}px`;
|
|
@@ -379,44 +470,51 @@
|
|
|
379
470
|
this.ghostEl?.remove();
|
|
380
471
|
this.ghostEl = void 0;
|
|
381
472
|
}
|
|
382
|
-
|
|
383
|
-
if (this.dragEl) {
|
|
384
|
-
this.destroyDragEl();
|
|
385
|
-
}
|
|
386
|
-
const { width, height } = el.getBoundingClientRect();
|
|
473
|
+
updateDragEl(el) {
|
|
387
474
|
const offset = getOffset(el);
|
|
388
|
-
const
|
|
389
|
-
dragEl.style.cssText = `
|
|
475
|
+
const { transform } = getComputedStyle(el);
|
|
476
|
+
this.dragEl.style.cssText = `
|
|
390
477
|
position: absolute;
|
|
478
|
+
transform: ${transform};
|
|
391
479
|
left: ${offset.left}px;
|
|
392
480
|
top: ${offset.top}px;
|
|
393
|
-
width: ${
|
|
394
|
-
height: ${
|
|
481
|
+
width: ${el.clientWidth}px;
|
|
482
|
+
height: ${el.clientHeight}px;
|
|
483
|
+
z-index: ${ZIndex.DRAG_EL};
|
|
395
484
|
`;
|
|
396
|
-
this.
|
|
397
|
-
|
|
485
|
+
this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
|
|
486
|
+
if (typeof this.core.config.updateDragEl === "function") {
|
|
487
|
+
this.core.config.updateDragEl(this.dragEl, el);
|
|
488
|
+
}
|
|
398
489
|
}
|
|
399
490
|
destroyDragEl() {
|
|
400
491
|
this.dragEl?.remove();
|
|
401
|
-
this.dragEl = void 0;
|
|
402
492
|
}
|
|
403
|
-
|
|
493
|
+
getOptions(options = {}) {
|
|
404
494
|
if (!this.target)
|
|
405
495
|
return {};
|
|
406
496
|
const isAbsolute = this.mode === Mode.ABSOLUTE;
|
|
497
|
+
const isFixed = this.mode === Mode.FIXED;
|
|
407
498
|
let { moveableOptions = {} } = this.core.config;
|
|
408
499
|
if (typeof moveableOptions === "function") {
|
|
409
500
|
moveableOptions = moveableOptions(this.core);
|
|
410
501
|
}
|
|
502
|
+
const elementGuidelines = moveableOptions.elementGuidelines || this.target.parentElement?.children || [];
|
|
503
|
+
this.setElementGuidelines(elementGuidelines);
|
|
504
|
+
if (moveableOptions.elementGuidelines) {
|
|
505
|
+
delete moveableOptions.elementGuidelines;
|
|
506
|
+
}
|
|
411
507
|
return {
|
|
412
|
-
origin:
|
|
508
|
+
origin: false,
|
|
413
509
|
rootContainer: this.core.container,
|
|
414
510
|
zoom: 1,
|
|
415
511
|
dragArea: false,
|
|
416
512
|
draggable: true,
|
|
417
513
|
resizable: true,
|
|
418
|
-
|
|
419
|
-
|
|
514
|
+
scalable: false,
|
|
515
|
+
rotatable: false,
|
|
516
|
+
snappable: isAbsolute || isFixed,
|
|
517
|
+
snapGap: isAbsolute || isFixed,
|
|
420
518
|
snapThreshold: 5,
|
|
421
519
|
snapDigit: 0,
|
|
422
520
|
throttleDrag: 0,
|
|
@@ -429,8 +527,16 @@
|
|
|
429
527
|
center: isAbsolute,
|
|
430
528
|
middle: isAbsolute
|
|
431
529
|
},
|
|
530
|
+
elementSnapDirections: {
|
|
531
|
+
top: isAbsolute,
|
|
532
|
+
right: isAbsolute,
|
|
533
|
+
bottom: isAbsolute,
|
|
534
|
+
left: isAbsolute
|
|
535
|
+
},
|
|
536
|
+
isDisplayInnerSnapDigit: true,
|
|
432
537
|
horizontalGuidelines: this.horizontalGuidelines,
|
|
433
538
|
verticalGuidelines: this.verticalGuidelines,
|
|
539
|
+
elementGuidelines: this.elementGuidelines,
|
|
434
540
|
bounds: {
|
|
435
541
|
top: 0,
|
|
436
542
|
left: 0,
|
|
@@ -499,15 +605,83 @@
|
|
|
499
605
|
};
|
|
500
606
|
};
|
|
501
607
|
|
|
608
|
+
class TargetCalibrate extends EventEmitter.EventEmitter {
|
|
609
|
+
constructor(config) {
|
|
610
|
+
super();
|
|
611
|
+
this.parent = config.parent;
|
|
612
|
+
this.mask = config.mask;
|
|
613
|
+
this.dr = config.dr;
|
|
614
|
+
this.core = config.core;
|
|
615
|
+
this.operationEl = globalThis.document.createElement("div");
|
|
616
|
+
this.parent.append(this.operationEl);
|
|
617
|
+
}
|
|
618
|
+
update(el, prefix) {
|
|
619
|
+
const { left, top } = this.getOffset(el);
|
|
620
|
+
const { transform } = getComputedStyle(el);
|
|
621
|
+
this.operationEl.style.cssText = `
|
|
622
|
+
position: absolute;
|
|
623
|
+
transform: ${transform};
|
|
624
|
+
left: ${left}px;
|
|
625
|
+
top: ${top}px;
|
|
626
|
+
width: ${el.clientWidth}px;
|
|
627
|
+
height: ${el.clientHeight}px;
|
|
628
|
+
`;
|
|
629
|
+
this.operationEl.id = `${prefix}${el.id}`;
|
|
630
|
+
if (typeof this.core.config.updateDragEl === "function") {
|
|
631
|
+
this.core.config.updateDragEl(this.operationEl, el);
|
|
632
|
+
}
|
|
633
|
+
return this.operationEl;
|
|
634
|
+
}
|
|
635
|
+
destroy() {
|
|
636
|
+
this.operationEl?.remove();
|
|
637
|
+
}
|
|
638
|
+
getOffset(el) {
|
|
639
|
+
const { offsetParent } = el;
|
|
640
|
+
const left = el.offsetLeft;
|
|
641
|
+
const top = el.offsetTop;
|
|
642
|
+
if (offsetParent) {
|
|
643
|
+
const parentOffset = this.getOffset(offsetParent);
|
|
644
|
+
return {
|
|
645
|
+
left: left + parentOffset.left,
|
|
646
|
+
top: top + parentOffset.top
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
if (this.dr.mode === Mode.FIXED) {
|
|
650
|
+
if (getMode(el) === Mode.FIXED) {
|
|
651
|
+
return {
|
|
652
|
+
left,
|
|
653
|
+
top
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
return {
|
|
657
|
+
left: left - this.mask.scrollLeft,
|
|
658
|
+
top: top - this.mask.scrollTop
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
if (getMode(el) === Mode.FIXED) {
|
|
662
|
+
return {
|
|
663
|
+
left: left + this.mask.scrollLeft,
|
|
664
|
+
top: top + this.mask.scrollTop
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
return {
|
|
668
|
+
left,
|
|
669
|
+
top
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
|
|
502
674
|
class StageHighlight extends EventEmitter.EventEmitter {
|
|
503
|
-
core;
|
|
504
|
-
container;
|
|
505
|
-
target;
|
|
506
|
-
moveable;
|
|
507
675
|
constructor(config) {
|
|
508
676
|
super();
|
|
509
677
|
this.core = config.core;
|
|
510
678
|
this.container = config.container;
|
|
679
|
+
this.calibrationTarget = new TargetCalibrate({
|
|
680
|
+
parent: this.core.mask.content,
|
|
681
|
+
mask: this.core.mask,
|
|
682
|
+
dr: this.core.dr,
|
|
683
|
+
core: this.core
|
|
684
|
+
});
|
|
511
685
|
}
|
|
512
686
|
highlight(el) {
|
|
513
687
|
if (!el || el === this.target)
|
|
@@ -515,32 +689,66 @@
|
|
|
515
689
|
this.target = el;
|
|
516
690
|
this.moveable?.destroy();
|
|
517
691
|
this.moveable = new Moveable__default["default"](this.container, {
|
|
518
|
-
target: this.
|
|
692
|
+
target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
|
|
693
|
+
origin: false,
|
|
694
|
+
rootContainer: this.core.container,
|
|
695
|
+
zoom: 1
|
|
519
696
|
});
|
|
520
697
|
}
|
|
521
698
|
clearHighlight() {
|
|
522
699
|
if (!this.moveable)
|
|
523
700
|
return;
|
|
701
|
+
this.target = void 0;
|
|
524
702
|
this.moveable.target = null;
|
|
525
703
|
this.moveable.updateTarget();
|
|
526
704
|
}
|
|
527
705
|
destroy() {
|
|
528
706
|
this.moveable?.destroy();
|
|
707
|
+
this.calibrationTarget.destroy();
|
|
529
708
|
}
|
|
530
709
|
}
|
|
531
710
|
|
|
532
711
|
class Rule extends EventEmitter__default["default"] {
|
|
533
|
-
hGuides;
|
|
534
|
-
vGuides;
|
|
535
|
-
horizontalGuidelines = [];
|
|
536
|
-
verticalGuidelines = [];
|
|
537
|
-
container;
|
|
538
|
-
containerResizeObserver;
|
|
539
712
|
constructor(container) {
|
|
540
713
|
super();
|
|
714
|
+
this.horizontalGuidelines = getGuideLineFromCache(GuidesType.HORIZONTAL);
|
|
715
|
+
this.verticalGuidelines = getGuideLineFromCache(GuidesType.VERTICAL);
|
|
716
|
+
this.getGuidesStyle = (type) => ({
|
|
717
|
+
position: "fixed",
|
|
718
|
+
zIndex: 1,
|
|
719
|
+
left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
|
|
720
|
+
top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
|
|
721
|
+
width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
|
|
722
|
+
height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
|
|
723
|
+
});
|
|
724
|
+
this.createGuides = (type, defaultGuides = []) => new Guides__default["default"](this.container, {
|
|
725
|
+
type,
|
|
726
|
+
defaultGuides,
|
|
727
|
+
displayDragPos: true,
|
|
728
|
+
backgroundColor: "#fff",
|
|
729
|
+
lineColor: "#000",
|
|
730
|
+
textColor: "#000",
|
|
731
|
+
style: this.getGuidesStyle(type)
|
|
732
|
+
});
|
|
733
|
+
this.hGuidesChangeGuidesHandler = (e) => {
|
|
734
|
+
this.horizontalGuidelines = e.guides;
|
|
735
|
+
this.emit("changeGuides", {
|
|
736
|
+
type: GuidesType.HORIZONTAL,
|
|
737
|
+
guides: this.horizontalGuidelines
|
|
738
|
+
});
|
|
739
|
+
globalThis.localStorage.setItem(H_GUIDE_LINE_STORAGE_KEY, JSON.stringify(e.guides));
|
|
740
|
+
};
|
|
741
|
+
this.vGuidesChangeGuidesHandler = (e) => {
|
|
742
|
+
this.verticalGuidelines = e.guides;
|
|
743
|
+
this.emit("changeGuides", {
|
|
744
|
+
type: GuidesType.VERTICAL,
|
|
745
|
+
guides: this.verticalGuidelines
|
|
746
|
+
});
|
|
747
|
+
globalThis.localStorage.setItem(V_GUIDE_LINE_STORAGE_KEY, JSON.stringify(e.guides));
|
|
748
|
+
};
|
|
541
749
|
this.container = container;
|
|
542
|
-
this.hGuides = this.createGuides(GuidesType.HORIZONTAL);
|
|
543
|
-
this.vGuides = this.createGuides(GuidesType.VERTICAL);
|
|
750
|
+
this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
|
|
751
|
+
this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
|
|
544
752
|
this.hGuides.on("changeGuides", this.hGuidesChangeGuidesHandler);
|
|
545
753
|
this.vGuides.on("changeGuides", this.vGuidesChangeGuidesHandler);
|
|
546
754
|
this.containerResizeObserver = new ResizeObserver(() => {
|
|
@@ -574,6 +782,8 @@
|
|
|
574
782
|
type: GuidesType.HORIZONTAL,
|
|
575
783
|
guides: []
|
|
576
784
|
});
|
|
785
|
+
globalThis.localStorage.setItem(V_GUIDE_LINE_STORAGE_KEY, "[]");
|
|
786
|
+
globalThis.localStorage.setItem(H_GUIDE_LINE_STORAGE_KEY, "[]");
|
|
577
787
|
}
|
|
578
788
|
showRule(show = true) {
|
|
579
789
|
if (show) {
|
|
@@ -606,37 +816,6 @@
|
|
|
606
816
|
this.containerResizeObserver.disconnect();
|
|
607
817
|
this.removeAllListeners();
|
|
608
818
|
}
|
|
609
|
-
getGuidesStyle = (type) => ({
|
|
610
|
-
position: "fixed",
|
|
611
|
-
zIndex: 1,
|
|
612
|
-
left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
|
|
613
|
-
top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
|
|
614
|
-
width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
|
|
615
|
-
height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
|
|
616
|
-
});
|
|
617
|
-
createGuides = (type, defaultGuides = []) => new Guides__default["default"](this.container, {
|
|
618
|
-
type,
|
|
619
|
-
defaultGuides,
|
|
620
|
-
displayDragPos: true,
|
|
621
|
-
backgroundColor: "#fff",
|
|
622
|
-
lineColor: "#000",
|
|
623
|
-
textColor: "#000",
|
|
624
|
-
style: this.getGuidesStyle(type)
|
|
625
|
-
});
|
|
626
|
-
hGuidesChangeGuidesHandler = (e) => {
|
|
627
|
-
this.horizontalGuidelines = e.guides;
|
|
628
|
-
this.emit("changeGuides", {
|
|
629
|
-
type: GuidesType.HORIZONTAL,
|
|
630
|
-
guides: this.horizontalGuidelines
|
|
631
|
-
});
|
|
632
|
-
};
|
|
633
|
-
vGuidesChangeGuidesHandler = (e) => {
|
|
634
|
-
this.verticalGuidelines = e.guides;
|
|
635
|
-
this.emit("changeGuides", {
|
|
636
|
-
type: GuidesType.VERTICAL,
|
|
637
|
-
guides: this.verticalGuidelines
|
|
638
|
-
});
|
|
639
|
-
};
|
|
640
819
|
}
|
|
641
820
|
|
|
642
821
|
const wrapperClassName = "editor-mask-wrapper";
|
|
@@ -674,32 +853,73 @@
|
|
|
674
853
|
return el;
|
|
675
854
|
};
|
|
676
855
|
class StageMask extends Rule {
|
|
677
|
-
content = createContent();
|
|
678
|
-
wrapper;
|
|
679
|
-
core;
|
|
680
|
-
page = null;
|
|
681
|
-
pageScrollParent = null;
|
|
682
|
-
scrollTop = 0;
|
|
683
|
-
scrollLeft = 0;
|
|
684
|
-
width = 0;
|
|
685
|
-
height = 0;
|
|
686
|
-
wrapperHeight = 0;
|
|
687
|
-
wrapperWidth = 0;
|
|
688
|
-
mode = Mode.ABSOLUTE;
|
|
689
|
-
pageResizeObserver = null;
|
|
690
|
-
wrapperResizeObserver = null;
|
|
691
|
-
highlightHandler = lodashEs.throttle((event) => {
|
|
692
|
-
this.emit("highlight", event);
|
|
693
|
-
}, throttleTime);
|
|
694
856
|
constructor(config) {
|
|
695
857
|
const wrapper = createWrapper();
|
|
696
858
|
super(wrapper);
|
|
859
|
+
this.content = createContent();
|
|
860
|
+
this.page = null;
|
|
861
|
+
this.pageScrollParent = null;
|
|
862
|
+
this.scrollTop = 0;
|
|
863
|
+
this.scrollLeft = 0;
|
|
864
|
+
this.width = 0;
|
|
865
|
+
this.height = 0;
|
|
866
|
+
this.wrapperHeight = 0;
|
|
867
|
+
this.wrapperWidth = 0;
|
|
868
|
+
this.maxScrollTop = 0;
|
|
869
|
+
this.maxScrollLeft = 0;
|
|
870
|
+
this.intersectionObserver = null;
|
|
871
|
+
this.mode = Mode.ABSOLUTE;
|
|
872
|
+
this.pageResizeObserver = null;
|
|
873
|
+
this.wrapperResizeObserver = null;
|
|
874
|
+
this.highlightHandler = lodashEs.throttle((event) => {
|
|
875
|
+
this.emit("highlight", event);
|
|
876
|
+
}, throttleTime);
|
|
877
|
+
this.mouseDownHandler = (event) => {
|
|
878
|
+
this.emit("clearHighlight");
|
|
879
|
+
event.stopImmediatePropagation();
|
|
880
|
+
event.stopPropagation();
|
|
881
|
+
if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
|
|
882
|
+
return;
|
|
883
|
+
if (event.target.className.indexOf("moveable-control") !== -1) {
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
this.content.removeEventListener("mousemove", this.highlightHandler);
|
|
887
|
+
this.emit("beforeSelect", event);
|
|
888
|
+
globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
|
|
889
|
+
};
|
|
890
|
+
this.mouseUpHandler = () => {
|
|
891
|
+
globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
|
|
892
|
+
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
893
|
+
this.emit("select");
|
|
894
|
+
};
|
|
895
|
+
this.mouseWheelHandler = (event) => {
|
|
896
|
+
this.emit("clearHighlight");
|
|
897
|
+
if (!this.page)
|
|
898
|
+
throw new Error("page \u672A\u521D\u59CB\u5316");
|
|
899
|
+
const { deltaY, deltaX } = event;
|
|
900
|
+
if (this.page.clientHeight < this.wrapperHeight && deltaY)
|
|
901
|
+
return;
|
|
902
|
+
if (this.page.clientWidth < this.wrapperWidth && deltaX)
|
|
903
|
+
return;
|
|
904
|
+
if (this.maxScrollTop > 0) {
|
|
905
|
+
this.scrollTop = this.scrollTop + deltaY;
|
|
906
|
+
}
|
|
907
|
+
if (this.maxScrollLeft > 0) {
|
|
908
|
+
this.scrollLeft = this.scrollLeft + deltaX;
|
|
909
|
+
}
|
|
910
|
+
this.scroll();
|
|
911
|
+
this.emit("scroll", event);
|
|
912
|
+
};
|
|
913
|
+
this.mouseLeaveHandler = () => {
|
|
914
|
+
setTimeout(() => this.emit("clearHighlight"), throttleTime);
|
|
915
|
+
};
|
|
697
916
|
this.wrapper = wrapper;
|
|
698
917
|
this.core = config.core;
|
|
699
918
|
this.content.addEventListener("mousedown", this.mouseDownHandler);
|
|
700
919
|
this.wrapper.appendChild(this.content);
|
|
701
920
|
this.content.addEventListener("wheel", this.mouseWheelHandler);
|
|
702
921
|
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
922
|
+
this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
|
|
703
923
|
}
|
|
704
924
|
setMode(mode) {
|
|
705
925
|
this.mode = mode;
|
|
@@ -718,12 +938,33 @@
|
|
|
718
938
|
this.page = page;
|
|
719
939
|
this.pageScrollParent = getScrollParent(page) || this.core.renderer.contentWindow?.document.documentElement || null;
|
|
720
940
|
this.pageResizeObserver?.disconnect();
|
|
941
|
+
this.wrapperResizeObserver?.disconnect();
|
|
942
|
+
this.intersectionObserver?.disconnect();
|
|
943
|
+
if (typeof IntersectionObserver !== "undefined") {
|
|
944
|
+
this.intersectionObserver = new IntersectionObserver((entries) => {
|
|
945
|
+
entries.forEach((entry) => {
|
|
946
|
+
const { target, intersectionRatio } = entry;
|
|
947
|
+
if (intersectionRatio <= 0) {
|
|
948
|
+
this.scrollIntoView(target);
|
|
949
|
+
}
|
|
950
|
+
this.intersectionObserver?.unobserve(target);
|
|
951
|
+
});
|
|
952
|
+
}, {
|
|
953
|
+
root: this.pageScrollParent,
|
|
954
|
+
rootMargin: "0px",
|
|
955
|
+
threshold: 1
|
|
956
|
+
});
|
|
957
|
+
}
|
|
721
958
|
if (typeof ResizeObserver !== "undefined") {
|
|
722
959
|
this.pageResizeObserver = new ResizeObserver((entries) => {
|
|
723
960
|
const [entry] = entries;
|
|
724
961
|
const { clientHeight, clientWidth } = entry.target;
|
|
725
962
|
this.setHeight(clientHeight);
|
|
726
963
|
this.setWidth(clientWidth);
|
|
964
|
+
this.scroll();
|
|
965
|
+
if (this.core.dr.moveable) {
|
|
966
|
+
this.core.dr.updateMoveable();
|
|
967
|
+
}
|
|
727
968
|
});
|
|
728
969
|
this.pageResizeObserver.observe(page);
|
|
729
970
|
this.wrapperResizeObserver = new ResizeObserver((entries) => {
|
|
@@ -731,6 +972,8 @@
|
|
|
731
972
|
const { clientHeight, clientWidth } = entry.target;
|
|
732
973
|
this.wrapperHeight = clientHeight;
|
|
733
974
|
this.wrapperWidth = clientWidth;
|
|
975
|
+
this.setMaxScrollLeft();
|
|
976
|
+
this.setMaxScrollTop();
|
|
734
977
|
});
|
|
735
978
|
this.wrapperResizeObserver.observe(this.wrapper);
|
|
736
979
|
}
|
|
@@ -743,16 +986,32 @@
|
|
|
743
986
|
setLayout(el) {
|
|
744
987
|
this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
|
|
745
988
|
}
|
|
989
|
+
scrollIntoView(el) {
|
|
990
|
+
el.scrollIntoView();
|
|
991
|
+
if (!this.pageScrollParent)
|
|
992
|
+
return;
|
|
993
|
+
this.scrollLeft = this.pageScrollParent.scrollLeft;
|
|
994
|
+
this.scrollTop = this.pageScrollParent.scrollTop;
|
|
995
|
+
this.scroll();
|
|
996
|
+
}
|
|
746
997
|
destroy() {
|
|
747
998
|
this.content?.remove();
|
|
748
999
|
this.page = null;
|
|
749
1000
|
this.pageScrollParent = null;
|
|
750
1001
|
this.pageResizeObserver?.disconnect();
|
|
751
1002
|
this.wrapperResizeObserver?.disconnect();
|
|
1003
|
+
this.content.removeEventListener("mouseleave", this.mouseLeaveHandler);
|
|
752
1004
|
super.destroy();
|
|
753
1005
|
}
|
|
754
1006
|
scroll() {
|
|
1007
|
+
this.fixScrollValue();
|
|
755
1008
|
let { scrollLeft, scrollTop } = this;
|
|
1009
|
+
if (this.pageScrollParent) {
|
|
1010
|
+
this.pageScrollParent.scrollTo({
|
|
1011
|
+
top: scrollTop,
|
|
1012
|
+
left: scrollLeft
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
756
1015
|
if (this.mode === Mode.FIXED) {
|
|
757
1016
|
scrollLeft = 0;
|
|
758
1017
|
scrollTop = 0;
|
|
@@ -765,74 +1024,67 @@
|
|
|
765
1024
|
}
|
|
766
1025
|
setHeight(height) {
|
|
767
1026
|
this.height = height;
|
|
1027
|
+
this.setMaxScrollTop();
|
|
768
1028
|
this.content.style.height = `${height}px`;
|
|
769
1029
|
}
|
|
770
1030
|
setWidth(width) {
|
|
771
1031
|
this.width = width;
|
|
1032
|
+
this.setMaxScrollLeft();
|
|
772
1033
|
this.content.style.width = `${width}px`;
|
|
773
1034
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
this.
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
this.emit("select");
|
|
791
|
-
};
|
|
792
|
-
mouseWheelHandler = (event) => {
|
|
793
|
-
if (!this.page)
|
|
794
|
-
throw new Error("page \u672A\u521D\u59CB\u5316");
|
|
795
|
-
const { deltaY, deltaX } = event;
|
|
796
|
-
const { height, wrapperHeight, width, wrapperWidth } = this;
|
|
797
|
-
const maxScrollTop = height - wrapperHeight;
|
|
798
|
-
const maxScrollLeft = width - wrapperWidth;
|
|
799
|
-
if (maxScrollTop > 0) {
|
|
800
|
-
if (deltaY > 0) {
|
|
801
|
-
this.scrollTop = this.scrollTop + Math.min(maxScrollTop - this.scrollTop, deltaY);
|
|
802
|
-
} else {
|
|
803
|
-
this.scrollTop = Math.max(this.scrollTop + deltaY, 0);
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
if (width > wrapperWidth) {
|
|
807
|
-
if (deltaX > 0) {
|
|
808
|
-
this.scrollLeft = this.scrollLeft + Math.min(maxScrollLeft - this.scrollLeft, deltaX);
|
|
809
|
-
} else {
|
|
810
|
-
this.scrollLeft = Math.max(this.scrollLeft + deltaX, 0);
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
if (this.mode !== Mode.FIXED) {
|
|
814
|
-
this.scrollTo(this.scrollLeft, this.scrollTop);
|
|
815
|
-
}
|
|
816
|
-
if (this.pageScrollParent) {
|
|
817
|
-
this.pageScrollParent.scrollTo({
|
|
818
|
-
top: this.scrollTop,
|
|
819
|
-
left: this.scrollLeft
|
|
820
|
-
});
|
|
821
|
-
}
|
|
822
|
-
this.scroll();
|
|
823
|
-
this.emit("scroll", event);
|
|
824
|
-
};
|
|
1035
|
+
setMaxScrollLeft() {
|
|
1036
|
+
this.maxScrollLeft = Math.max(this.width - this.wrapperWidth, 0);
|
|
1037
|
+
}
|
|
1038
|
+
setMaxScrollTop() {
|
|
1039
|
+
this.maxScrollTop = Math.max(this.height - this.wrapperHeight, 0);
|
|
1040
|
+
}
|
|
1041
|
+
fixScrollValue() {
|
|
1042
|
+
if (this.scrollTop < 0)
|
|
1043
|
+
this.scrollTop = 0;
|
|
1044
|
+
if (this.scrollLeft < 0)
|
|
1045
|
+
this.scrollLeft = 0;
|
|
1046
|
+
if (this.maxScrollTop < this.scrollTop)
|
|
1047
|
+
this.scrollTop = this.maxScrollTop;
|
|
1048
|
+
if (this.maxScrollLeft < this.scrollLeft)
|
|
1049
|
+
this.scrollLeft = this.maxScrollLeft;
|
|
1050
|
+
}
|
|
825
1051
|
}
|
|
826
1052
|
|
|
827
1053
|
class StageRender extends EventEmitter.EventEmitter {
|
|
828
|
-
contentWindow = null;
|
|
829
|
-
runtime = null;
|
|
830
|
-
iframe;
|
|
831
|
-
runtimeUrl;
|
|
832
|
-
core;
|
|
833
|
-
render;
|
|
834
1054
|
constructor({ core }) {
|
|
835
1055
|
super();
|
|
1056
|
+
this.contentWindow = null;
|
|
1057
|
+
this.runtime = null;
|
|
1058
|
+
this.getMagicApi = () => ({
|
|
1059
|
+
onPageElUpdate: (el) => this.emit("page-el-update", el),
|
|
1060
|
+
onRuntimeReady: (runtime) => {
|
|
1061
|
+
this.runtime = runtime;
|
|
1062
|
+
globalThis.runtime = runtime;
|
|
1063
|
+
this.emit("runtime-ready", runtime);
|
|
1064
|
+
}
|
|
1065
|
+
});
|
|
1066
|
+
this.getRuntime = () => {
|
|
1067
|
+
if (this.runtime)
|
|
1068
|
+
return Promise.resolve(this.runtime);
|
|
1069
|
+
return new Promise((resolve) => {
|
|
1070
|
+
const listener = (runtime) => {
|
|
1071
|
+
this.off("runtime-ready", listener);
|
|
1072
|
+
resolve(runtime);
|
|
1073
|
+
};
|
|
1074
|
+
this.on("runtime-ready", listener);
|
|
1075
|
+
});
|
|
1076
|
+
};
|
|
1077
|
+
this.loadHandler = async () => {
|
|
1078
|
+
this.contentWindow = this.iframe?.contentWindow;
|
|
1079
|
+
this.contentWindow.magic = this.getMagicApi();
|
|
1080
|
+
if (this.render) {
|
|
1081
|
+
const el = await this.render(this.core);
|
|
1082
|
+
if (el) {
|
|
1083
|
+
this.iframe?.contentDocument?.body?.appendChild(el);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
this.emit("onload");
|
|
1087
|
+
};
|
|
836
1088
|
this.core = core;
|
|
837
1089
|
this.runtimeUrl = core.config.runtimeUrl || "";
|
|
838
1090
|
this.render = core.config.render;
|
|
@@ -845,14 +1097,6 @@
|
|
|
845
1097
|
`;
|
|
846
1098
|
this.iframe.addEventListener("load", this.loadHandler);
|
|
847
1099
|
}
|
|
848
|
-
getMagicApi = () => ({
|
|
849
|
-
onPageElUpdate: (el) => this.emit("page-el-update", el),
|
|
850
|
-
onRuntimeReady: (runtime) => {
|
|
851
|
-
this.runtime = runtime;
|
|
852
|
-
globalThis.runtime = runtime;
|
|
853
|
-
this.emit("runtime-ready", runtime);
|
|
854
|
-
}
|
|
855
|
-
});
|
|
856
1100
|
async mount(el) {
|
|
857
1101
|
if (this.iframe) {
|
|
858
1102
|
if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
|
|
@@ -863,23 +1107,10 @@
|
|
|
863
1107
|
this.iframe.srcdoc = html;
|
|
864
1108
|
}
|
|
865
1109
|
el.appendChild(this.iframe);
|
|
866
|
-
this.contentWindow = this.iframe?.contentWindow;
|
|
867
|
-
this.contentWindow.magic = this.getMagicApi();
|
|
868
1110
|
} else {
|
|
869
1111
|
throw Error("mount \u5931\u8D25");
|
|
870
1112
|
}
|
|
871
1113
|
}
|
|
872
|
-
getRuntime = () => {
|
|
873
|
-
if (this.runtime)
|
|
874
|
-
return Promise.resolve(this.runtime);
|
|
875
|
-
return new Promise((resolve) => {
|
|
876
|
-
const listener = (runtime) => {
|
|
877
|
-
this.off("runtime-ready", listener);
|
|
878
|
-
resolve(runtime);
|
|
879
|
-
};
|
|
880
|
-
this.on("runtime-ready", listener);
|
|
881
|
-
});
|
|
882
|
-
};
|
|
883
1114
|
destroy() {
|
|
884
1115
|
this.iframe?.removeEventListener("load", this.loadHandler);
|
|
885
1116
|
this.contentWindow = null;
|
|
@@ -887,49 +1118,25 @@
|
|
|
887
1118
|
this.iframe = void 0;
|
|
888
1119
|
this.removeAllListeners();
|
|
889
1120
|
}
|
|
890
|
-
loadHandler = async () => {
|
|
891
|
-
this.emit("onload");
|
|
892
|
-
if (this.render) {
|
|
893
|
-
const el = await this.render(this.core);
|
|
894
|
-
if (el) {
|
|
895
|
-
this.iframe?.contentDocument?.body?.appendChild(el);
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
if (this.contentWindow) {
|
|
899
|
-
const style = this.contentWindow.document.createElement("style");
|
|
900
|
-
style.id = "tmagic-stage-render";
|
|
901
|
-
style.innerHTML = `
|
|
902
|
-
.${SELECTED_CLASS}, .${SELECTED_CLASS}-parent {
|
|
903
|
-
z-index: ${ZIndex.SELECTED_EL};
|
|
904
|
-
}
|
|
905
|
-
`;
|
|
906
|
-
this.contentWindow.document.head.appendChild(style);
|
|
907
|
-
}
|
|
908
|
-
};
|
|
909
1121
|
}
|
|
910
1122
|
|
|
911
1123
|
class StageCore extends EventEmitter.EventEmitter {
|
|
912
|
-
selectedDom;
|
|
913
|
-
highlightedDom;
|
|
914
|
-
renderer;
|
|
915
|
-
mask;
|
|
916
|
-
dr;
|
|
917
|
-
highlightLayer;
|
|
918
|
-
config;
|
|
919
|
-
zoom = DEFAULT_ZOOM;
|
|
920
|
-
container;
|
|
921
|
-
canSelect;
|
|
922
1124
|
constructor(config) {
|
|
923
1125
|
super();
|
|
1126
|
+
this.zoom = DEFAULT_ZOOM;
|
|
924
1127
|
this.config = config;
|
|
925
1128
|
this.setZoom(config.zoom);
|
|
926
1129
|
this.canSelect = config.canSelect || ((el) => !!el.id);
|
|
927
1130
|
this.renderer = new StageRender({ core: this });
|
|
928
1131
|
this.mask = new StageMask({ core: this });
|
|
929
1132
|
this.dr = new StageDragResize({ core: this, container: this.mask.content });
|
|
930
|
-
this.highlightLayer = new StageHighlight({ core: this, container: this.mask.
|
|
931
|
-
this.renderer.on("runtime-ready", (runtime) =>
|
|
932
|
-
|
|
1133
|
+
this.highlightLayer = new StageHighlight({ core: this, container: this.mask.wrapper });
|
|
1134
|
+
this.renderer.on("runtime-ready", (runtime) => {
|
|
1135
|
+
this.emit("runtime-ready", runtime);
|
|
1136
|
+
});
|
|
1137
|
+
this.renderer.on("page-el-update", (el) => {
|
|
1138
|
+
this.mask?.observe(el);
|
|
1139
|
+
});
|
|
933
1140
|
this.mask.on("beforeSelect", (event) => {
|
|
934
1141
|
this.setElementFromPoint(event);
|
|
935
1142
|
}).on("select", () => {
|
|
@@ -939,6 +1146,10 @@
|
|
|
939
1146
|
this.emit("changeGuides", data);
|
|
940
1147
|
}).on("highlight", async (event) => {
|
|
941
1148
|
await this.setElementFromPoint(event);
|
|
1149
|
+
if (this.highlightedDom === this.selectedDom) {
|
|
1150
|
+
this.highlightLayer.clearHighlight();
|
|
1151
|
+
return;
|
|
1152
|
+
}
|
|
942
1153
|
this.highlightLayer.highlight(this.highlightedDom);
|
|
943
1154
|
this.emit("highlight", this.highlightedDom);
|
|
944
1155
|
}).on("clearHighlight", async () => {
|
|
@@ -966,7 +1177,7 @@
|
|
|
966
1177
|
let stopped = false;
|
|
967
1178
|
const stop = () => stopped = true;
|
|
968
1179
|
for (const el of els) {
|
|
969
|
-
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.canSelect(el, stop)) {
|
|
1180
|
+
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.canSelect(el, event, stop)) {
|
|
970
1181
|
if (stopped)
|
|
971
1182
|
break;
|
|
972
1183
|
if (event.type === "mousemove") {
|
|
@@ -983,47 +1194,58 @@
|
|
|
983
1194
|
if (el === this.selectedDom)
|
|
984
1195
|
return;
|
|
985
1196
|
const runtime = await this.renderer.getRuntime();
|
|
1197
|
+
await runtime?.select?.(el.id);
|
|
986
1198
|
if (runtime?.beforeSelect) {
|
|
987
1199
|
await runtime.beforeSelect(el);
|
|
988
1200
|
}
|
|
989
1201
|
this.mask.setLayout(el);
|
|
990
|
-
this.dr
|
|
1202
|
+
this.dr.select(el, event);
|
|
1203
|
+
if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
|
|
1204
|
+
this.mask.intersectionObserver?.observe(el);
|
|
1205
|
+
}
|
|
991
1206
|
this.selectedDom = el;
|
|
992
1207
|
if (this.renderer.contentWindow) {
|
|
993
1208
|
removeSelectedClassName(this.renderer.contentWindow.document);
|
|
994
1209
|
if (this.selectedDom) {
|
|
995
|
-
addSelectedClassName(this.selectedDom);
|
|
1210
|
+
addSelectedClassName(this.selectedDom, this.renderer.contentWindow.document);
|
|
996
1211
|
}
|
|
997
1212
|
}
|
|
998
1213
|
}
|
|
999
1214
|
update(data) {
|
|
1000
1215
|
const { config } = data;
|
|
1001
|
-
this.renderer?.getRuntime().then((runtime) => {
|
|
1216
|
+
return this.renderer?.getRuntime().then((runtime) => {
|
|
1002
1217
|
runtime?.update?.(data);
|
|
1003
1218
|
setTimeout(() => {
|
|
1004
1219
|
const el = this.renderer.contentWindow?.document.getElementById(`${config.id}`);
|
|
1005
|
-
if (el) {
|
|
1220
|
+
if (el && el.id === this.selectedDom?.id) {
|
|
1221
|
+
this.selectedDom = el;
|
|
1006
1222
|
this.mask.setLayout(el);
|
|
1007
|
-
this.dr
|
|
1223
|
+
this.dr.updateMoveable(el);
|
|
1008
1224
|
}
|
|
1009
1225
|
}, 0);
|
|
1010
1226
|
});
|
|
1011
1227
|
}
|
|
1012
1228
|
async highlight(idOrEl) {
|
|
1013
|
-
|
|
1229
|
+
let el;
|
|
1230
|
+
try {
|
|
1231
|
+
el = await this.getTargetElement(idOrEl);
|
|
1232
|
+
} catch (error) {
|
|
1233
|
+
this.highlightLayer.clearHighlight();
|
|
1234
|
+
return;
|
|
1235
|
+
}
|
|
1014
1236
|
if (el === this.highlightedDom)
|
|
1015
1237
|
return;
|
|
1016
1238
|
this.highlightLayer.highlight(el);
|
|
1017
1239
|
this.highlightedDom = el;
|
|
1018
1240
|
}
|
|
1019
1241
|
sortNode(data) {
|
|
1020
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
|
|
1242
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
|
|
1021
1243
|
}
|
|
1022
1244
|
add(data) {
|
|
1023
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.add?.(data));
|
|
1245
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.add?.(data));
|
|
1024
1246
|
}
|
|
1025
1247
|
remove(data) {
|
|
1026
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.remove?.(data));
|
|
1248
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.remove?.(data));
|
|
1027
1249
|
}
|
|
1028
1250
|
setZoom(zoom = DEFAULT_ZOOM) {
|
|
1029
1251
|
this.zoom = zoom;
|
|
@@ -1049,16 +1271,13 @@
|
|
|
1049
1271
|
this.container = void 0;
|
|
1050
1272
|
}
|
|
1051
1273
|
async getTargetElement(idOrEl) {
|
|
1052
|
-
let el;
|
|
1053
1274
|
if (typeof idOrEl === "string" || typeof idOrEl === "number") {
|
|
1054
|
-
const
|
|
1055
|
-
el = await runtime?.select?.(`${idOrEl}`);
|
|
1275
|
+
const el = this.renderer.contentWindow?.document.getElementById(`${idOrEl}`);
|
|
1056
1276
|
if (!el)
|
|
1057
1277
|
throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
|
|
1058
|
-
|
|
1059
|
-
el = idOrEl;
|
|
1278
|
+
return el;
|
|
1060
1279
|
}
|
|
1061
|
-
return
|
|
1280
|
+
return idOrEl;
|
|
1062
1281
|
}
|
|
1063
1282
|
}
|
|
1064
1283
|
|
|
@@ -1067,8 +1286,7 @@
|
|
|
1067
1286
|
exports.StageRender = StageRender;
|
|
1068
1287
|
exports["default"] = StageCore;
|
|
1069
1288
|
|
|
1070
|
-
Object.
|
|
1071
|
-
exports[Symbol.toStringTag] = 'Module';
|
|
1289
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
|
|
1072
1290
|
|
|
1073
1291
|
}));
|
|
1074
1292
|
//# sourceMappingURL=tmagic-stage.umd.js.map
|