@tmagic/stage 1.0.0-beta.8 → 1.0.0-rc.10
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 +609 -273
- package/dist/tmagic-stage.es.js.map +1 -1
- package/dist/tmagic-stage.umd.js +613 -279
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/dist/types/src/StageCore.d.ts +14 -4
- package/dist/types/src/StageDragResize.d.ts +22 -7
- package/dist/types/src/StageHighlight.d.ts +27 -0
- package/dist/types/src/StageMask.d.ts +23 -0
- package/dist/types/src/TargetCalibrate.d.ts +20 -0
- package/dist/types/src/const.d.ts +28 -1
- package/dist/types/src/types.d.ts +25 -5
- package/dist/types/src/util.d.ts +4 -1
- package/package.json +13 -8
- package/src/Rule.ts +13 -5
- package/src/StageCore.ts +90 -24
- package/src/StageDragResize.ts +239 -99
- package/src/StageHighlight.ts +82 -0
- package/src/StageMask.ts +106 -26
- package/src/StageRender.ts +1 -0
- package/src/TargetCalibrate.ts +119 -0
- package/src/const.ts +31 -2
- package/src/types.ts +27 -5
- package/src/util.ts +53 -28
- package/LICENSE +0 -5432
- package/tsconfig.json +0 -9
- package/vite.config.ts +0 -27
package/dist/tmagic-stage.umd.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('events'), require('moveable'), require('@scena/guides')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'events', 'moveable', '@scena/guides'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicStage = {}, global.EventEmitter, global.Moveable, global.Guides));
|
|
5
|
-
})(this, (function (exports, EventEmitter, Moveable, Guides) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('events'), require('moveable'), require('moveable-helper'), require('lodash-es'), require('@scena/guides')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'events', 'moveable', 'moveable-helper', 'lodash-es', '@scena/guides'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicStage = {}, global.EventEmitter, global.Moveable, global.MoveableHelper, global.lodashEs, global.Guides));
|
|
5
|
+
})(this, (function (exports, EventEmitter, Moveable, MoveableHelper, lodashEs, Guides) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
8
|
|
|
9
9
|
var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
|
|
10
10
|
var Moveable__default = /*#__PURE__*/_interopDefaultLegacy(Moveable);
|
|
11
|
+
var MoveableHelper__default = /*#__PURE__*/_interopDefaultLegacy(MoveableHelper);
|
|
11
12
|
var Guides__default = /*#__PURE__*/_interopDefaultLegacy(Guides);
|
|
12
13
|
|
|
13
14
|
const GHOST_EL_ID_PREFIX = "ghost_el_";
|
|
15
|
+
const DRAG_EL_ID_PREFIX = "drag_el_";
|
|
16
|
+
const HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
|
|
14
17
|
const DEFAULT_ZOOM = 1;
|
|
15
18
|
var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
|
|
16
19
|
GuidesType2["HORIZONTAL"] = "horizontal";
|
|
@@ -19,6 +22,9 @@
|
|
|
19
22
|
})(GuidesType || {});
|
|
20
23
|
var ZIndex = /* @__PURE__ */ ((ZIndex2) => {
|
|
21
24
|
ZIndex2["MASK"] = "99999";
|
|
25
|
+
ZIndex2["SELECTED_EL"] = "666";
|
|
26
|
+
ZIndex2["GHOST_EL"] = "700";
|
|
27
|
+
ZIndex2["DRAG_EL"] = "9";
|
|
22
28
|
return ZIndex2;
|
|
23
29
|
})(ZIndex || {});
|
|
24
30
|
var MouseButton = /* @__PURE__ */ ((MouseButton2) => {
|
|
@@ -33,31 +39,23 @@
|
|
|
33
39
|
Mode2["SORTABLE"] = "sortable";
|
|
34
40
|
return Mode2;
|
|
35
41
|
})(Mode || {});
|
|
42
|
+
const SELECTED_CLASS = "tmagic-stage-selected-area";
|
|
43
|
+
const H_GUIDE_LINE_STORAGE_KEY = "$MagicStageHorizontalGuidelinesData";
|
|
44
|
+
const V_GUIDE_LINE_STORAGE_KEY = "$MagicStageVerticalGuidelinesData";
|
|
36
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
|
+
};
|
|
37
55
|
const getOffset = (el) => {
|
|
38
|
-
const { transform } = getComputedStyle(el);
|
|
39
56
|
const { offsetParent } = el;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (transform.indexOf("matrix") > -1) {
|
|
43
|
-
let a = 1;
|
|
44
|
-
let b = 1;
|
|
45
|
-
let c = 1;
|
|
46
|
-
let d = 1;
|
|
47
|
-
let e = 0;
|
|
48
|
-
let f = 0;
|
|
49
|
-
transform.replace(/matrix\((.+), (.+), (.+), (.+), (.+), (.+)\)/, ($0, $1, $2, $3, $4, $5, $6) => {
|
|
50
|
-
a = +$1;
|
|
51
|
-
b = +$2;
|
|
52
|
-
c = +$3;
|
|
53
|
-
d = +$4;
|
|
54
|
-
e = +$5;
|
|
55
|
-
f = +$6;
|
|
56
|
-
return transform;
|
|
57
|
-
});
|
|
58
|
-
left = a * left + c * top + e;
|
|
59
|
-
top = b * left + d * top + f;
|
|
60
|
-
}
|
|
57
|
+
const left = el.offsetLeft;
|
|
58
|
+
const top = el.offsetTop;
|
|
61
59
|
if (offsetParent) {
|
|
62
60
|
const parentOffset = getOffset(offsetParent);
|
|
63
61
|
return {
|
|
@@ -153,46 +151,81 @@
|
|
|
153
151
|
el.style.cssText = cssText;
|
|
154
152
|
return el;
|
|
155
153
|
};
|
|
154
|
+
const removeSelectedClassName = (doc) => {
|
|
155
|
+
const oldEl = doc.querySelector(`.${SELECTED_CLASS}`);
|
|
156
|
+
if (oldEl) {
|
|
157
|
+
oldEl.classList.remove(SELECTED_CLASS);
|
|
158
|
+
oldEl.parentNode?.classList.remove(`${SELECTED_CLASS}-parent`);
|
|
159
|
+
doc.querySelectorAll(`.${SELECTED_CLASS}-parents`).forEach((item) => {
|
|
160
|
+
item.classList.remove(`${SELECTED_CLASS}-parents`);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
const addSelectedClassName = (el, doc) => {
|
|
165
|
+
el.classList.add(SELECTED_CLASS);
|
|
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 [];
|
|
187
|
+
};
|
|
156
188
|
|
|
157
189
|
class StageDragResize extends EventEmitter.EventEmitter {
|
|
158
|
-
core;
|
|
159
|
-
container;
|
|
160
|
-
target;
|
|
161
|
-
dragEl;
|
|
162
|
-
moveable;
|
|
163
|
-
horizontalGuidelines = [];
|
|
164
|
-
verticalGuidelines = [];
|
|
165
|
-
moveableOptions = {};
|
|
166
|
-
dragStatus = "end" /* END */;
|
|
167
|
-
ghostEl;
|
|
168
|
-
mode = Mode.ABSOLUTE;
|
|
169
190
|
constructor(config) {
|
|
170
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 */;
|
|
171
198
|
this.core = config.core;
|
|
172
199
|
this.container = config.container;
|
|
200
|
+
this.dragEl = globalThis.document.createElement("div");
|
|
201
|
+
this.container.append(this.dragEl);
|
|
173
202
|
}
|
|
174
|
-
|
|
203
|
+
select(el, event) {
|
|
204
|
+
const oldTarget = this.target;
|
|
175
205
|
this.target = el;
|
|
176
|
-
if (
|
|
177
|
-
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();
|
|
178
216
|
}
|
|
179
|
-
this.mode = getMode(el);
|
|
180
|
-
this.destroyDragEl();
|
|
181
|
-
this.destroyGhostEl();
|
|
182
|
-
this.dragEl = this.generateDragEl(el);
|
|
183
|
-
this.moveableOptions = await this.getOptions({
|
|
184
|
-
target: this.dragEl || this.target
|
|
185
|
-
});
|
|
186
|
-
this.initMoveable();
|
|
187
217
|
if (event) {
|
|
188
218
|
this.moveable?.dragStart(event);
|
|
189
219
|
}
|
|
190
220
|
}
|
|
191
|
-
|
|
221
|
+
updateMoveable(el = this.target) {
|
|
192
222
|
if (!this.moveable)
|
|
193
223
|
throw new Error("\u672A\u521D\u59CB\u5316moveable");
|
|
194
|
-
|
|
195
|
-
|
|
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]) => {
|
|
196
229
|
this.moveable[key] = value;
|
|
197
230
|
});
|
|
198
231
|
this.moveable.updateTarget();
|
|
@@ -200,15 +233,19 @@
|
|
|
200
233
|
setGuidelines(type, guidelines) {
|
|
201
234
|
if (type === GuidesType.HORIZONTAL) {
|
|
202
235
|
this.horizontalGuidelines = guidelines;
|
|
236
|
+
this.moveableOptions.horizontalGuidelines = guidelines;
|
|
203
237
|
} else if (type === GuidesType.VERTICAL) {
|
|
204
238
|
this.verticalGuidelines = guidelines;
|
|
239
|
+
this.moveableOptions.verticalGuidelines = guidelines;
|
|
205
240
|
}
|
|
206
|
-
this.
|
|
241
|
+
this.updateMoveable();
|
|
207
242
|
}
|
|
208
243
|
clearGuides() {
|
|
209
|
-
this.verticalGuidelines = [];
|
|
210
244
|
this.horizontalGuidelines = [];
|
|
211
|
-
this.
|
|
245
|
+
this.verticalGuidelines = [];
|
|
246
|
+
this.moveableOptions.horizontalGuidelines = [];
|
|
247
|
+
this.moveableOptions.verticalGuidelines = [];
|
|
248
|
+
this.updateMoveable();
|
|
212
249
|
}
|
|
213
250
|
destroy() {
|
|
214
251
|
this.moveable?.destroy();
|
|
@@ -217,6 +254,37 @@
|
|
|
217
254
|
this.dragStatus = "end" /* END */;
|
|
218
255
|
this.removeAllListeners();
|
|
219
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
|
+
}
|
|
220
288
|
initMoveable() {
|
|
221
289
|
this.moveable?.destroy();
|
|
222
290
|
this.moveable = new Moveable__default["default"](this.container, {
|
|
@@ -224,35 +292,38 @@
|
|
|
224
292
|
});
|
|
225
293
|
this.bindResizeEvent();
|
|
226
294
|
this.bindDragEvent();
|
|
295
|
+
this.bindRotateEvent();
|
|
296
|
+
this.bindScaleEvent();
|
|
227
297
|
}
|
|
228
298
|
bindResizeEvent() {
|
|
229
299
|
if (!this.moveable)
|
|
230
300
|
throw new Error("moveable \u4E3A\u521D\u59CB\u5316");
|
|
301
|
+
const frame = {
|
|
302
|
+
left: 0,
|
|
303
|
+
top: 0
|
|
304
|
+
};
|
|
231
305
|
this.moveable.on("resizeStart", (e) => {
|
|
232
|
-
if (
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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;
|
|
238
314
|
if (!this.moveable || !this.target || !this.dragEl)
|
|
239
315
|
return;
|
|
240
316
|
const { beforeTranslate } = drag;
|
|
241
317
|
this.dragStatus = "ing" /* ING */;
|
|
242
|
-
this.
|
|
243
|
-
this.target.style.height = `${height}px`;
|
|
244
|
-
this.dragEl.style.width = `${width}px`;
|
|
245
|
-
this.dragEl.style.height = `${height}px`;
|
|
318
|
+
this.moveableHelper?.onResize(e);
|
|
246
319
|
if (this.mode === Mode.SORTABLE) {
|
|
247
|
-
this.
|
|
248
|
-
|
|
249
|
-
|
|
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`;
|
|
250
324
|
}
|
|
251
|
-
this.
|
|
252
|
-
this.
|
|
253
|
-
const offset = getAbsolutePosition(this.target, { left: beforeTranslate[0], top: beforeTranslate[1] });
|
|
254
|
-
this.target.style.left = `${offset.left}px`;
|
|
255
|
-
this.target.style.top = `${offset.top}px`;
|
|
325
|
+
this.target.style.width = `${width}px`;
|
|
326
|
+
this.target.style.height = `${height}px`;
|
|
256
327
|
}).on("resizeEnd", () => {
|
|
257
328
|
this.dragStatus = "end" /* END */;
|
|
258
329
|
this.update(true);
|
|
@@ -261,27 +332,31 @@
|
|
|
261
332
|
bindDragEvent() {
|
|
262
333
|
if (!this.moveable)
|
|
263
334
|
throw new Error("moveable \u4E3A\u521D\u59CB\u5316");
|
|
264
|
-
|
|
335
|
+
const frame = {
|
|
336
|
+
left: 0,
|
|
337
|
+
top: 0
|
|
338
|
+
};
|
|
339
|
+
this.moveable.on("dragStart", (e) => {
|
|
265
340
|
if (!this.target)
|
|
266
341
|
throw new Error("\u672A\u9009\u4E2D\u7EC4\u4EF6");
|
|
267
342
|
this.dragStatus = "start" /* START */;
|
|
343
|
+
this.moveableHelper?.onDragStart(e);
|
|
268
344
|
if (this.mode === Mode.SORTABLE) {
|
|
269
345
|
this.ghostEl = this.generateGhostEl(this.target);
|
|
270
346
|
}
|
|
271
|
-
|
|
347
|
+
frame.top = this.target.offsetTop;
|
|
348
|
+
frame.left = this.target.offsetLeft;
|
|
349
|
+
}).on("drag", (e) => {
|
|
272
350
|
if (!this.target || !this.dragEl)
|
|
273
351
|
return;
|
|
274
352
|
this.dragStatus = "ing" /* ING */;
|
|
275
|
-
const offset = getAbsolutePosition(this.target, { left, top });
|
|
276
353
|
if (this.ghostEl) {
|
|
277
|
-
this.
|
|
278
|
-
this.ghostEl.style.top = `${offset.top}px`;
|
|
354
|
+
this.ghostEl.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
279
355
|
return;
|
|
280
356
|
}
|
|
281
|
-
this.
|
|
282
|
-
this.
|
|
283
|
-
this.target.style.
|
|
284
|
-
this.target.style.top = `${offset.top}px`;
|
|
357
|
+
this.moveableHelper?.onDrag(e);
|
|
358
|
+
this.target.style.left = `${frame.left + e.beforeTranslate[0]}px`;
|
|
359
|
+
this.target.style.top = `${frame.top + e.beforeTranslate[1]}px`;
|
|
285
360
|
}).on("dragEnd", () => {
|
|
286
361
|
if (this.dragStatus === "ing" /* ING */) {
|
|
287
362
|
switch (this.mode) {
|
|
@@ -296,13 +371,53 @@
|
|
|
296
371
|
this.destroyGhostEl();
|
|
297
372
|
});
|
|
298
373
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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
|
+
});
|
|
304
420
|
});
|
|
305
|
-
return getSnapElements(el).filter((element) => element !== this.target && !this.target?.contains(element));
|
|
306
421
|
}
|
|
307
422
|
sort() {
|
|
308
423
|
if (!this.target || !this.ghostEl)
|
|
@@ -324,12 +439,13 @@
|
|
|
324
439
|
}
|
|
325
440
|
}
|
|
326
441
|
update(isResize = false) {
|
|
327
|
-
|
|
328
|
-
|
|
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 };
|
|
329
445
|
const left = this.calcValueByFontsize(offset.left);
|
|
330
446
|
const top = this.calcValueByFontsize(offset.top);
|
|
331
|
-
const width = this.calcValueByFontsize(
|
|
332
|
-
const height = this.calcValueByFontsize(
|
|
447
|
+
const width = this.calcValueByFontsize(this.target.clientWidth);
|
|
448
|
+
const height = this.calcValueByFontsize(this.target.clientHeight);
|
|
333
449
|
this.emit("update", {
|
|
334
450
|
el: this.target,
|
|
335
451
|
style: isResize ? { left, top, width, height } : { left, top }
|
|
@@ -341,8 +457,8 @@
|
|
|
341
457
|
}
|
|
342
458
|
const ghostEl = el.cloneNode(true);
|
|
343
459
|
const { top, left } = getAbsolutePosition(el, getOffset(el));
|
|
344
|
-
ghostEl.id = `${GHOST_EL_ID_PREFIX}${
|
|
345
|
-
ghostEl.style.zIndex =
|
|
460
|
+
ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
|
|
461
|
+
ghostEl.style.zIndex = ZIndex.GHOST_EL;
|
|
346
462
|
ghostEl.style.opacity = ".5";
|
|
347
463
|
ghostEl.style.position = "absolute";
|
|
348
464
|
ghostEl.style.left = `${left}px`;
|
|
@@ -354,49 +470,73 @@
|
|
|
354
470
|
this.ghostEl?.remove();
|
|
355
471
|
this.ghostEl = void 0;
|
|
356
472
|
}
|
|
357
|
-
|
|
358
|
-
if (this.dragEl) {
|
|
359
|
-
this.destroyDragEl();
|
|
360
|
-
}
|
|
361
|
-
const { width, height } = el.getBoundingClientRect();
|
|
473
|
+
updateDragEl(el) {
|
|
362
474
|
const offset = getOffset(el);
|
|
363
|
-
const
|
|
364
|
-
dragEl.style.cssText = `
|
|
475
|
+
const { transform } = getComputedStyle(el);
|
|
476
|
+
this.dragEl.style.cssText = `
|
|
365
477
|
position: absolute;
|
|
478
|
+
transform: ${transform};
|
|
366
479
|
left: ${offset.left}px;
|
|
367
480
|
top: ${offset.top}px;
|
|
368
|
-
width: ${
|
|
369
|
-
height: ${
|
|
481
|
+
width: ${el.clientWidth}px;
|
|
482
|
+
height: ${el.clientHeight}px;
|
|
483
|
+
z-index: ${ZIndex.DRAG_EL};
|
|
370
484
|
`;
|
|
371
|
-
this.
|
|
372
|
-
|
|
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
|
+
}
|
|
373
489
|
}
|
|
374
490
|
destroyDragEl() {
|
|
375
491
|
this.dragEl?.remove();
|
|
376
|
-
this.dragEl = void 0;
|
|
377
492
|
}
|
|
378
|
-
|
|
493
|
+
getOptions(options = {}) {
|
|
379
494
|
if (!this.target)
|
|
380
495
|
return {};
|
|
381
496
|
const isAbsolute = this.mode === Mode.ABSOLUTE;
|
|
497
|
+
const isFixed = this.mode === Mode.FIXED;
|
|
382
498
|
let { moveableOptions = {} } = this.core.config;
|
|
383
499
|
if (typeof moveableOptions === "function") {
|
|
384
500
|
moveableOptions = moveableOptions(this.core);
|
|
385
501
|
}
|
|
502
|
+
const elementGuidelines = moveableOptions.elementGuidelines || this.target.parentElement?.children || [];
|
|
503
|
+
this.setElementGuidelines(elementGuidelines);
|
|
504
|
+
if (moveableOptions.elementGuidelines) {
|
|
505
|
+
delete moveableOptions.elementGuidelines;
|
|
506
|
+
}
|
|
386
507
|
return {
|
|
387
|
-
|
|
388
|
-
|
|
508
|
+
origin: false,
|
|
509
|
+
rootContainer: this.core.container,
|
|
389
510
|
zoom: 1,
|
|
390
|
-
dragArea:
|
|
511
|
+
dragArea: false,
|
|
391
512
|
draggable: true,
|
|
392
513
|
resizable: true,
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
514
|
+
scalable: false,
|
|
515
|
+
rotatable: false,
|
|
516
|
+
snappable: isAbsolute || isFixed,
|
|
517
|
+
snapGap: isAbsolute || isFixed,
|
|
518
|
+
snapThreshold: 5,
|
|
519
|
+
snapDigit: 0,
|
|
520
|
+
throttleDrag: 0,
|
|
521
|
+
isDisplaySnapDigit: isAbsolute,
|
|
522
|
+
snapDirections: {
|
|
523
|
+
top: isAbsolute,
|
|
524
|
+
right: isAbsolute,
|
|
525
|
+
bottom: isAbsolute,
|
|
526
|
+
left: isAbsolute,
|
|
527
|
+
center: isAbsolute,
|
|
528
|
+
middle: isAbsolute
|
|
529
|
+
},
|
|
530
|
+
elementSnapDirections: {
|
|
531
|
+
top: isAbsolute,
|
|
532
|
+
right: isAbsolute,
|
|
533
|
+
bottom: isAbsolute,
|
|
534
|
+
left: isAbsolute
|
|
535
|
+
},
|
|
536
|
+
isDisplayInnerSnapDigit: true,
|
|
398
537
|
horizontalGuidelines: this.horizontalGuidelines,
|
|
399
538
|
verticalGuidelines: this.verticalGuidelines,
|
|
539
|
+
elementGuidelines: this.elementGuidelines,
|
|
400
540
|
bounds: {
|
|
401
541
|
top: 0,
|
|
402
542
|
left: 0,
|
|
@@ -465,18 +605,150 @@
|
|
|
465
605
|
};
|
|
466
606
|
};
|
|
467
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
|
+
|
|
674
|
+
class StageHighlight extends EventEmitter.EventEmitter {
|
|
675
|
+
constructor(config) {
|
|
676
|
+
super();
|
|
677
|
+
this.core = config.core;
|
|
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
|
+
});
|
|
685
|
+
}
|
|
686
|
+
highlight(el) {
|
|
687
|
+
if (!el || el === this.target)
|
|
688
|
+
return;
|
|
689
|
+
this.target = el;
|
|
690
|
+
this.moveable?.destroy();
|
|
691
|
+
this.moveable = new Moveable__default["default"](this.container, {
|
|
692
|
+
target: this.calibrationTarget.update(el, HIGHLIGHT_EL_ID_PREFIX),
|
|
693
|
+
origin: false,
|
|
694
|
+
rootContainer: this.core.container,
|
|
695
|
+
zoom: 1
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
clearHighlight() {
|
|
699
|
+
if (!this.moveable)
|
|
700
|
+
return;
|
|
701
|
+
this.target = void 0;
|
|
702
|
+
this.moveable.target = null;
|
|
703
|
+
this.moveable.updateTarget();
|
|
704
|
+
}
|
|
705
|
+
destroy() {
|
|
706
|
+
this.moveable?.destroy();
|
|
707
|
+
this.calibrationTarget.destroy();
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
468
711
|
class Rule extends EventEmitter__default["default"] {
|
|
469
|
-
hGuides;
|
|
470
|
-
vGuides;
|
|
471
|
-
horizontalGuidelines = [];
|
|
472
|
-
verticalGuidelines = [];
|
|
473
|
-
container;
|
|
474
|
-
containerResizeObserver;
|
|
475
712
|
constructor(container) {
|
|
476
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
|
+
};
|
|
477
749
|
this.container = container;
|
|
478
|
-
this.hGuides = this.createGuides(GuidesType.HORIZONTAL);
|
|
479
|
-
this.vGuides = this.createGuides(GuidesType.VERTICAL);
|
|
750
|
+
this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
|
|
751
|
+
this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
|
|
480
752
|
this.hGuides.on("changeGuides", this.hGuidesChangeGuidesHandler);
|
|
481
753
|
this.vGuides.on("changeGuides", this.vGuidesChangeGuidesHandler);
|
|
482
754
|
this.containerResizeObserver = new ResizeObserver(() => {
|
|
@@ -510,6 +782,8 @@
|
|
|
510
782
|
type: GuidesType.HORIZONTAL,
|
|
511
783
|
guides: []
|
|
512
784
|
});
|
|
785
|
+
globalThis.localStorage.setItem(V_GUIDE_LINE_STORAGE_KEY, "[]");
|
|
786
|
+
globalThis.localStorage.setItem(H_GUIDE_LINE_STORAGE_KEY, "[]");
|
|
513
787
|
}
|
|
514
788
|
showRule(show = true) {
|
|
515
789
|
if (show) {
|
|
@@ -542,40 +816,10 @@
|
|
|
542
816
|
this.containerResizeObserver.disconnect();
|
|
543
817
|
this.removeAllListeners();
|
|
544
818
|
}
|
|
545
|
-
getGuidesStyle = (type) => ({
|
|
546
|
-
position: "fixed",
|
|
547
|
-
zIndex: 1,
|
|
548
|
-
left: type === GuidesType.HORIZONTAL ? 0 : "-30px",
|
|
549
|
-
top: type === GuidesType.HORIZONTAL ? "-30px" : 0,
|
|
550
|
-
width: type === GuidesType.HORIZONTAL ? "100%" : "30px",
|
|
551
|
-
height: type === GuidesType.HORIZONTAL ? "30px" : "100%"
|
|
552
|
-
});
|
|
553
|
-
createGuides = (type, defaultGuides = []) => new Guides__default["default"](this.container, {
|
|
554
|
-
type,
|
|
555
|
-
defaultGuides,
|
|
556
|
-
displayDragPos: true,
|
|
557
|
-
backgroundColor: "#fff",
|
|
558
|
-
lineColor: "#000",
|
|
559
|
-
textColor: "#000",
|
|
560
|
-
style: this.getGuidesStyle(type)
|
|
561
|
-
});
|
|
562
|
-
hGuidesChangeGuidesHandler = (e) => {
|
|
563
|
-
this.horizontalGuidelines = e.guides;
|
|
564
|
-
this.emit("changeGuides", {
|
|
565
|
-
type: GuidesType.HORIZONTAL,
|
|
566
|
-
guides: this.horizontalGuidelines
|
|
567
|
-
});
|
|
568
|
-
};
|
|
569
|
-
vGuidesChangeGuidesHandler = (e) => {
|
|
570
|
-
this.verticalGuidelines = e.guides;
|
|
571
|
-
this.emit("changeGuides", {
|
|
572
|
-
type: GuidesType.VERTICAL,
|
|
573
|
-
guides: this.verticalGuidelines
|
|
574
|
-
});
|
|
575
|
-
};
|
|
576
819
|
}
|
|
577
820
|
|
|
578
821
|
const wrapperClassName = "editor-mask-wrapper";
|
|
822
|
+
const throttleTime = 100;
|
|
579
823
|
const hideScrollbar = () => {
|
|
580
824
|
const style = globalThis.document.createElement("style");
|
|
581
825
|
style.innerHTML = `
|
|
@@ -609,28 +853,73 @@
|
|
|
609
853
|
return el;
|
|
610
854
|
};
|
|
611
855
|
class StageMask extends Rule {
|
|
612
|
-
content = createContent();
|
|
613
|
-
wrapper;
|
|
614
|
-
core;
|
|
615
|
-
page = null;
|
|
616
|
-
pageScrollParent = null;
|
|
617
|
-
scrollTop = 0;
|
|
618
|
-
scrollLeft = 0;
|
|
619
|
-
width = 0;
|
|
620
|
-
height = 0;
|
|
621
|
-
wrapperHeight = 0;
|
|
622
|
-
wrapperWidth = 0;
|
|
623
|
-
mode = Mode.ABSOLUTE;
|
|
624
|
-
pageResizeObserver = null;
|
|
625
|
-
wrapperResizeObserver = null;
|
|
626
856
|
constructor(config) {
|
|
627
857
|
const wrapper = createWrapper();
|
|
628
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
|
+
};
|
|
629
916
|
this.wrapper = wrapper;
|
|
630
917
|
this.core = config.core;
|
|
631
918
|
this.content.addEventListener("mousedown", this.mouseDownHandler);
|
|
632
919
|
this.wrapper.appendChild(this.content);
|
|
633
920
|
this.content.addEventListener("wheel", this.mouseWheelHandler);
|
|
921
|
+
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
922
|
+
this.content.addEventListener("mouseleave", this.mouseLeaveHandler);
|
|
634
923
|
}
|
|
635
924
|
setMode(mode) {
|
|
636
925
|
this.mode = mode;
|
|
@@ -649,12 +938,33 @@
|
|
|
649
938
|
this.page = page;
|
|
650
939
|
this.pageScrollParent = getScrollParent(page) || this.core.renderer.contentWindow?.document.documentElement || null;
|
|
651
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
|
+
}
|
|
652
958
|
if (typeof ResizeObserver !== "undefined") {
|
|
653
959
|
this.pageResizeObserver = new ResizeObserver((entries) => {
|
|
654
960
|
const [entry] = entries;
|
|
655
961
|
const { clientHeight, clientWidth } = entry.target;
|
|
656
962
|
this.setHeight(clientHeight);
|
|
657
963
|
this.setWidth(clientWidth);
|
|
964
|
+
this.scroll();
|
|
965
|
+
if (this.core.dr.moveable) {
|
|
966
|
+
this.core.dr.updateMoveable();
|
|
967
|
+
}
|
|
658
968
|
});
|
|
659
969
|
this.pageResizeObserver.observe(page);
|
|
660
970
|
this.wrapperResizeObserver = new ResizeObserver((entries) => {
|
|
@@ -662,6 +972,8 @@
|
|
|
662
972
|
const { clientHeight, clientWidth } = entry.target;
|
|
663
973
|
this.wrapperHeight = clientHeight;
|
|
664
974
|
this.wrapperWidth = clientWidth;
|
|
975
|
+
this.setMaxScrollLeft();
|
|
976
|
+
this.setMaxScrollTop();
|
|
665
977
|
});
|
|
666
978
|
this.wrapperResizeObserver.observe(this.wrapper);
|
|
667
979
|
}
|
|
@@ -674,16 +986,32 @@
|
|
|
674
986
|
setLayout(el) {
|
|
675
987
|
this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
|
|
676
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
|
+
}
|
|
677
997
|
destroy() {
|
|
678
998
|
this.content?.remove();
|
|
679
999
|
this.page = null;
|
|
680
1000
|
this.pageScrollParent = null;
|
|
681
1001
|
this.pageResizeObserver?.disconnect();
|
|
682
1002
|
this.wrapperResizeObserver?.disconnect();
|
|
1003
|
+
this.content.removeEventListener("mouseleave", this.mouseLeaveHandler);
|
|
683
1004
|
super.destroy();
|
|
684
1005
|
}
|
|
685
1006
|
scroll() {
|
|
1007
|
+
this.fixScrollValue();
|
|
686
1008
|
let { scrollLeft, scrollTop } = this;
|
|
1009
|
+
if (this.pageScrollParent) {
|
|
1010
|
+
this.pageScrollParent.scrollTo({
|
|
1011
|
+
top: scrollTop,
|
|
1012
|
+
left: scrollLeft
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
687
1015
|
if (this.mode === Mode.FIXED) {
|
|
688
1016
|
scrollLeft = 0;
|
|
689
1017
|
scrollTop = 0;
|
|
@@ -696,71 +1024,65 @@
|
|
|
696
1024
|
}
|
|
697
1025
|
setHeight(height) {
|
|
698
1026
|
this.height = height;
|
|
1027
|
+
this.setMaxScrollTop();
|
|
699
1028
|
this.content.style.height = `${height}px`;
|
|
700
1029
|
}
|
|
701
1030
|
setWidth(width) {
|
|
702
1031
|
this.width = width;
|
|
1032
|
+
this.setMaxScrollLeft();
|
|
703
1033
|
this.content.style.width = `${width}px`;
|
|
704
1034
|
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
this.
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
if (!this.page)
|
|
722
|
-
throw new Error("page \u672A\u521D\u59CB\u5316");
|
|
723
|
-
const { deltaY, deltaX } = event;
|
|
724
|
-
const { height, wrapperHeight, width, wrapperWidth } = this;
|
|
725
|
-
const maxScrollTop = height - wrapperHeight;
|
|
726
|
-
const maxScrollLeft = width - wrapperWidth;
|
|
727
|
-
if (maxScrollTop > 0) {
|
|
728
|
-
if (deltaY > 0) {
|
|
729
|
-
this.scrollTop = this.scrollTop + Math.min(maxScrollTop - this.scrollTop, deltaY);
|
|
730
|
-
} else {
|
|
731
|
-
this.scrollTop = Math.max(this.scrollTop + deltaY, 0);
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
if (width > wrapperWidth) {
|
|
735
|
-
if (deltaX > 0) {
|
|
736
|
-
this.scrollLeft = this.scrollLeft + Math.min(maxScrollLeft - this.scrollLeft, deltaX);
|
|
737
|
-
} else {
|
|
738
|
-
this.scrollLeft = Math.max(this.scrollLeft + deltaX, 0);
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
if (this.mode !== Mode.FIXED) {
|
|
742
|
-
this.scrollTo(this.scrollLeft, this.scrollTop);
|
|
743
|
-
}
|
|
744
|
-
if (this.pageScrollParent) {
|
|
745
|
-
this.pageScrollParent.scrollTo({
|
|
746
|
-
top: this.scrollTop,
|
|
747
|
-
left: this.scrollLeft
|
|
748
|
-
});
|
|
749
|
-
}
|
|
750
|
-
this.scroll();
|
|
751
|
-
this.emit("scroll", event);
|
|
752
|
-
};
|
|
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
|
+
}
|
|
753
1051
|
}
|
|
754
1052
|
|
|
755
1053
|
class StageRender extends EventEmitter.EventEmitter {
|
|
756
|
-
contentWindow = null;
|
|
757
|
-
runtime = null;
|
|
758
|
-
iframe;
|
|
759
|
-
runtimeUrl;
|
|
760
|
-
core;
|
|
761
|
-
render;
|
|
762
1054
|
constructor({ core }) {
|
|
763
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.emit("onload");
|
|
1079
|
+
if (this.render) {
|
|
1080
|
+
const el = await this.render(this.core);
|
|
1081
|
+
if (el) {
|
|
1082
|
+
this.iframe?.contentDocument?.body?.appendChild(el);
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
};
|
|
764
1086
|
this.core = core;
|
|
765
1087
|
this.runtimeUrl = core.config.runtimeUrl || "";
|
|
766
1088
|
this.render = core.config.render;
|
|
@@ -773,14 +1095,6 @@
|
|
|
773
1095
|
`;
|
|
774
1096
|
this.iframe.addEventListener("load", this.loadHandler);
|
|
775
1097
|
}
|
|
776
|
-
getMagicApi = () => ({
|
|
777
|
-
onPageElUpdate: (el) => this.emit("page-el-update", el),
|
|
778
|
-
onRuntimeReady: (runtime) => {
|
|
779
|
-
this.runtime = runtime;
|
|
780
|
-
globalThis.runtime = runtime;
|
|
781
|
-
this.emit("runtime-ready", runtime);
|
|
782
|
-
}
|
|
783
|
-
});
|
|
784
1098
|
async mount(el) {
|
|
785
1099
|
if (this.iframe) {
|
|
786
1100
|
if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
|
|
@@ -797,17 +1111,6 @@
|
|
|
797
1111
|
throw Error("mount \u5931\u8D25");
|
|
798
1112
|
}
|
|
799
1113
|
}
|
|
800
|
-
getRuntime = () => {
|
|
801
|
-
if (this.runtime)
|
|
802
|
-
return Promise.resolve(this.runtime);
|
|
803
|
-
return new Promise((resolve) => {
|
|
804
|
-
const listener = (runtime) => {
|
|
805
|
-
this.off("runtime-ready", listener);
|
|
806
|
-
resolve(runtime);
|
|
807
|
-
};
|
|
808
|
-
this.on("runtime-ready", listener);
|
|
809
|
-
});
|
|
810
|
-
};
|
|
811
1114
|
destroy() {
|
|
812
1115
|
this.iframe?.removeEventListener("load", this.loadHandler);
|
|
813
1116
|
this.contentWindow = null;
|
|
@@ -815,35 +1118,25 @@
|
|
|
815
1118
|
this.iframe = void 0;
|
|
816
1119
|
this.removeAllListeners();
|
|
817
1120
|
}
|
|
818
|
-
loadHandler = async () => {
|
|
819
|
-
this.emit("onload");
|
|
820
|
-
if (this.render) {
|
|
821
|
-
const el = await this.render(this.core);
|
|
822
|
-
if (el) {
|
|
823
|
-
this.iframe?.contentDocument?.body?.appendChild(el);
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
};
|
|
827
1121
|
}
|
|
828
1122
|
|
|
829
1123
|
class StageCore extends EventEmitter.EventEmitter {
|
|
830
|
-
selectedDom;
|
|
831
|
-
renderer;
|
|
832
|
-
mask;
|
|
833
|
-
dr;
|
|
834
|
-
config;
|
|
835
|
-
zoom = DEFAULT_ZOOM;
|
|
836
|
-
canSelect;
|
|
837
1124
|
constructor(config) {
|
|
838
1125
|
super();
|
|
1126
|
+
this.zoom = DEFAULT_ZOOM;
|
|
839
1127
|
this.config = config;
|
|
840
1128
|
this.setZoom(config.zoom);
|
|
841
1129
|
this.canSelect = config.canSelect || ((el) => !!el.id);
|
|
842
1130
|
this.renderer = new StageRender({ core: this });
|
|
843
1131
|
this.mask = new StageMask({ core: this });
|
|
844
1132
|
this.dr = new StageDragResize({ core: this, container: this.mask.content });
|
|
845
|
-
this.
|
|
846
|
-
this.renderer.on("
|
|
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
|
+
});
|
|
847
1140
|
this.mask.on("beforeSelect", (event) => {
|
|
848
1141
|
this.setElementFromPoint(event);
|
|
849
1142
|
}).on("select", () => {
|
|
@@ -851,6 +1144,16 @@
|
|
|
851
1144
|
}).on("changeGuides", (data) => {
|
|
852
1145
|
this.dr.setGuidelines(data.type, data.guides);
|
|
853
1146
|
this.emit("changeGuides", data);
|
|
1147
|
+
}).on("highlight", async (event) => {
|
|
1148
|
+
await this.setElementFromPoint(event);
|
|
1149
|
+
if (this.highlightedDom === this.selectedDom) {
|
|
1150
|
+
this.highlightLayer.clearHighlight();
|
|
1151
|
+
return;
|
|
1152
|
+
}
|
|
1153
|
+
this.highlightLayer.highlight(this.highlightedDom);
|
|
1154
|
+
this.emit("highlight", this.highlightedDom);
|
|
1155
|
+
}).on("clearHighlight", async () => {
|
|
1156
|
+
this.highlightLayer.clearHighlight();
|
|
854
1157
|
});
|
|
855
1158
|
this.dr.on("update", (data) => {
|
|
856
1159
|
setTimeout(() => this.emit("update", data));
|
|
@@ -874,60 +1177,81 @@
|
|
|
874
1177
|
let stopped = false;
|
|
875
1178
|
const stop = () => stopped = true;
|
|
876
1179
|
for (const el of els) {
|
|
877
|
-
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)) {
|
|
878
1181
|
if (stopped)
|
|
879
1182
|
break;
|
|
1183
|
+
if (event.type === "mousemove") {
|
|
1184
|
+
this.highlight(el);
|
|
1185
|
+
break;
|
|
1186
|
+
}
|
|
880
1187
|
this.select(el, event);
|
|
881
1188
|
break;
|
|
882
1189
|
}
|
|
883
1190
|
}
|
|
884
1191
|
}
|
|
885
1192
|
async select(idOrEl, event) {
|
|
886
|
-
|
|
887
|
-
if (typeof idOrEl === "string" || typeof idOrEl === "number") {
|
|
888
|
-
const runtime2 = await this.renderer?.getRuntime();
|
|
889
|
-
el = await runtime2?.select?.(`${idOrEl}`);
|
|
890
|
-
if (!el)
|
|
891
|
-
throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
|
|
892
|
-
} else {
|
|
893
|
-
el = idOrEl;
|
|
894
|
-
}
|
|
1193
|
+
const el = await this.getTargetElement(idOrEl);
|
|
895
1194
|
if (el === this.selectedDom)
|
|
896
1195
|
return;
|
|
897
|
-
const runtime = await this.renderer
|
|
1196
|
+
const runtime = await this.renderer.getRuntime();
|
|
1197
|
+
await runtime?.select?.(el.id);
|
|
898
1198
|
if (runtime?.beforeSelect) {
|
|
899
1199
|
await runtime.beforeSelect(el);
|
|
900
1200
|
}
|
|
901
1201
|
this.mask.setLayout(el);
|
|
902
|
-
this.dr
|
|
1202
|
+
this.dr.select(el, event);
|
|
1203
|
+
if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
|
|
1204
|
+
this.mask.intersectionObserver?.observe(el);
|
|
1205
|
+
}
|
|
903
1206
|
this.selectedDom = el;
|
|
1207
|
+
if (this.renderer.contentWindow) {
|
|
1208
|
+
removeSelectedClassName(this.renderer.contentWindow.document);
|
|
1209
|
+
if (this.selectedDom) {
|
|
1210
|
+
addSelectedClassName(this.selectedDom, this.renderer.contentWindow.document);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
904
1213
|
}
|
|
905
1214
|
update(data) {
|
|
906
1215
|
const { config } = data;
|
|
907
|
-
this.renderer?.getRuntime().then((runtime) => {
|
|
1216
|
+
return this.renderer?.getRuntime().then((runtime) => {
|
|
908
1217
|
runtime?.update?.(data);
|
|
909
1218
|
setTimeout(() => {
|
|
910
1219
|
const el = this.renderer.contentWindow?.document.getElementById(`${config.id}`);
|
|
911
|
-
if (el) {
|
|
1220
|
+
if (el && el.id === this.selectedDom?.id) {
|
|
1221
|
+
this.selectedDom = el;
|
|
912
1222
|
this.mask.setLayout(el);
|
|
913
|
-
this.dr
|
|
1223
|
+
this.dr.updateMoveable(el);
|
|
914
1224
|
}
|
|
915
1225
|
}, 0);
|
|
916
1226
|
});
|
|
917
1227
|
}
|
|
1228
|
+
async highlight(idOrEl) {
|
|
1229
|
+
let el;
|
|
1230
|
+
try {
|
|
1231
|
+
el = await this.getTargetElement(idOrEl);
|
|
1232
|
+
} catch (error) {
|
|
1233
|
+
this.highlightLayer.clearHighlight();
|
|
1234
|
+
return;
|
|
1235
|
+
}
|
|
1236
|
+
if (el === this.highlightedDom)
|
|
1237
|
+
return;
|
|
1238
|
+
this.highlightLayer.highlight(el);
|
|
1239
|
+
this.highlightedDom = el;
|
|
1240
|
+
}
|
|
918
1241
|
sortNode(data) {
|
|
919
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
|
|
1242
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
|
|
920
1243
|
}
|
|
921
1244
|
add(data) {
|
|
922
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.add?.(data));
|
|
1245
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.add?.(data));
|
|
923
1246
|
}
|
|
924
1247
|
remove(data) {
|
|
925
|
-
this.renderer?.getRuntime().then((runtime) => runtime?.remove?.(data));
|
|
1248
|
+
return this.renderer?.getRuntime().then((runtime) => runtime?.remove?.(data));
|
|
926
1249
|
}
|
|
927
1250
|
setZoom(zoom = DEFAULT_ZOOM) {
|
|
928
1251
|
this.zoom = zoom;
|
|
929
1252
|
}
|
|
930
1253
|
mount(el) {
|
|
1254
|
+
this.container = el;
|
|
931
1255
|
const { mask, renderer } = this;
|
|
932
1256
|
renderer.mount(el);
|
|
933
1257
|
mask.mount(el);
|
|
@@ -938,11 +1262,22 @@
|
|
|
938
1262
|
this.dr.clearGuides();
|
|
939
1263
|
}
|
|
940
1264
|
destroy() {
|
|
941
|
-
const { mask, renderer, dr } = this;
|
|
1265
|
+
const { mask, renderer, dr, highlightLayer } = this;
|
|
942
1266
|
renderer.destroy();
|
|
943
1267
|
mask.destroy();
|
|
944
1268
|
dr.destroy();
|
|
1269
|
+
highlightLayer.destroy();
|
|
945
1270
|
this.removeAllListeners();
|
|
1271
|
+
this.container = void 0;
|
|
1272
|
+
}
|
|
1273
|
+
async getTargetElement(idOrEl) {
|
|
1274
|
+
if (typeof idOrEl === "string" || typeof idOrEl === "number") {
|
|
1275
|
+
const el = this.renderer.contentWindow?.document.getElementById(`${idOrEl}`);
|
|
1276
|
+
if (!el)
|
|
1277
|
+
throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
|
|
1278
|
+
return el;
|
|
1279
|
+
}
|
|
1280
|
+
return idOrEl;
|
|
946
1281
|
}
|
|
947
1282
|
}
|
|
948
1283
|
|
|
@@ -951,8 +1286,7 @@
|
|
|
951
1286
|
exports.StageRender = StageRender;
|
|
952
1287
|
exports["default"] = StageCore;
|
|
953
1288
|
|
|
954
|
-
Object.
|
|
955
|
-
exports[Symbol.toStringTag] = 'Module';
|
|
1289
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
|
|
956
1290
|
|
|
957
1291
|
}));
|
|
958
1292
|
//# sourceMappingURL=tmagic-stage.umd.js.map
|