@tmagic/stage 1.0.0-beta.8 → 1.0.0-beta.9
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/dist/tmagic-stage.es.js +142 -25
- package/dist/tmagic-stage.es.js.map +1 -1
- package/dist/tmagic-stage.umd.js +145 -29
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/dist/types/src/StageCore.d.ts +10 -0
- package/dist/types/src/StageDragResize.d.ts +1 -0
- package/dist/types/src/StageHighlight.d.ts +25 -0
- package/dist/types/src/StageMask.d.ts +5 -0
- package/dist/types/src/const.d.ts +3 -1
- package/dist/types/src/types.d.ts +4 -0
- package/dist/types/src/util.d.ts +2 -0
- package/package.json +5 -4
- package/src/StageCore.ts +56 -10
- package/src/StageDragResize.ts +38 -14
- package/src/StageHighlight.ts +67 -0
- package/src/StageMask.ts +15 -1
- package/src/StageRender.ts +13 -0
- package/src/const.ts +3 -0
- package/src/types.ts +5 -0
- package/src/util.ts +15 -1
package/dist/tmagic-stage.es.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import EventEmitter$1, { EventEmitter } from 'events';
|
|
2
2
|
import Moveable from 'moveable';
|
|
3
|
+
import MoveableHelper from 'moveable-helper';
|
|
4
|
+
import { throttle } from 'lodash-es';
|
|
3
5
|
import Guides from '@scena/guides';
|
|
4
6
|
|
|
5
7
|
const GHOST_EL_ID_PREFIX = "ghost_el_";
|
|
@@ -11,6 +13,7 @@ var GuidesType = /* @__PURE__ */ ((GuidesType2) => {
|
|
|
11
13
|
})(GuidesType || {});
|
|
12
14
|
var ZIndex = /* @__PURE__ */ ((ZIndex2) => {
|
|
13
15
|
ZIndex2["MASK"] = "99999";
|
|
16
|
+
ZIndex2["SELECTED_EL"] = "666";
|
|
14
17
|
return ZIndex2;
|
|
15
18
|
})(ZIndex || {});
|
|
16
19
|
var MouseButton = /* @__PURE__ */ ((MouseButton2) => {
|
|
@@ -25,6 +28,7 @@ var Mode = /* @__PURE__ */ ((Mode2) => {
|
|
|
25
28
|
Mode2["SORTABLE"] = "sortable";
|
|
26
29
|
return Mode2;
|
|
27
30
|
})(Mode || {});
|
|
31
|
+
const SELECTED_CLASS = "tmagic-stage-selected-area";
|
|
28
32
|
|
|
29
33
|
const getOffset = (el) => {
|
|
30
34
|
const { transform } = getComputedStyle(el);
|
|
@@ -145,6 +149,17 @@ const createDiv = ({ className, cssText }) => {
|
|
|
145
149
|
el.style.cssText = cssText;
|
|
146
150
|
return el;
|
|
147
151
|
};
|
|
152
|
+
const removeSelectedClassName = (doc) => {
|
|
153
|
+
const oldEl = doc.querySelector(`.${SELECTED_CLASS}`);
|
|
154
|
+
if (oldEl) {
|
|
155
|
+
oldEl.classList.remove(SELECTED_CLASS);
|
|
156
|
+
oldEl.parentNode?.classList.remove(`${SELECTED_CLASS}-parent`);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
const addSelectedClassName = (el) => {
|
|
160
|
+
el.classList.add(SELECTED_CLASS);
|
|
161
|
+
el.parentNode?.classList.add(`${SELECTED_CLASS}-parent`);
|
|
162
|
+
};
|
|
148
163
|
|
|
149
164
|
class StageDragResize extends EventEmitter {
|
|
150
165
|
core;
|
|
@@ -158,6 +173,7 @@ class StageDragResize extends EventEmitter {
|
|
|
158
173
|
dragStatus = "end" /* END */;
|
|
159
174
|
ghostEl;
|
|
160
175
|
mode = Mode.ABSOLUTE;
|
|
176
|
+
moveableHelper;
|
|
161
177
|
constructor(config) {
|
|
162
178
|
super();
|
|
163
179
|
this.core = config.core;
|
|
@@ -175,6 +191,11 @@ class StageDragResize extends EventEmitter {
|
|
|
175
191
|
this.moveableOptions = await this.getOptions({
|
|
176
192
|
target: this.dragEl || this.target
|
|
177
193
|
});
|
|
194
|
+
this.moveableHelper = MoveableHelper.create({
|
|
195
|
+
useBeforeRender: true,
|
|
196
|
+
useRender: false,
|
|
197
|
+
createAuto: true
|
|
198
|
+
});
|
|
178
199
|
this.initMoveable();
|
|
179
200
|
if (event) {
|
|
180
201
|
this.moveable?.dragStart(event);
|
|
@@ -253,27 +274,32 @@ class StageDragResize extends EventEmitter {
|
|
|
253
274
|
bindDragEvent() {
|
|
254
275
|
if (!this.moveable)
|
|
255
276
|
throw new Error("moveable \u4E3A\u521D\u59CB\u5316");
|
|
256
|
-
|
|
277
|
+
let offset = {
|
|
278
|
+
left: 0,
|
|
279
|
+
top: 0
|
|
280
|
+
};
|
|
281
|
+
this.moveable.on("dragStart", (e) => {
|
|
257
282
|
if (!this.target)
|
|
258
283
|
throw new Error("\u672A\u9009\u4E2D\u7EC4\u4EF6");
|
|
259
284
|
this.dragStatus = "start" /* START */;
|
|
285
|
+
this.moveableHelper?.onDragStart(e);
|
|
286
|
+
offset = getAbsolutePosition(this.target, { left: 0, top: 0 });
|
|
260
287
|
if (this.mode === Mode.SORTABLE) {
|
|
261
288
|
this.ghostEl = this.generateGhostEl(this.target);
|
|
262
289
|
}
|
|
263
|
-
}).on("drag", (
|
|
290
|
+
}).on("drag", (e) => {
|
|
264
291
|
if (!this.target || !this.dragEl)
|
|
265
292
|
return;
|
|
266
293
|
this.dragStatus = "ing" /* ING */;
|
|
267
|
-
const
|
|
294
|
+
const { left, top } = e;
|
|
268
295
|
if (this.ghostEl) {
|
|
269
296
|
this.dragEl.style.top = `${top}px`;
|
|
270
|
-
this.ghostEl.style.top = `${offset.top}px`;
|
|
297
|
+
this.ghostEl.style.top = `${top + offset.top}px`;
|
|
271
298
|
return;
|
|
272
299
|
}
|
|
273
|
-
this.
|
|
274
|
-
this.
|
|
275
|
-
this.target.style.
|
|
276
|
-
this.target.style.top = `${offset.top}px`;
|
|
300
|
+
this.moveableHelper?.onDrag(e);
|
|
301
|
+
this.target.style.left = `${left + offset.left}px`;
|
|
302
|
+
this.target.style.top = `${top + offset.top}px`;
|
|
277
303
|
}).on("dragEnd", () => {
|
|
278
304
|
if (this.dragStatus === "ing" /* ING */) {
|
|
279
305
|
switch (this.mode) {
|
|
@@ -376,17 +402,26 @@ class StageDragResize extends EventEmitter {
|
|
|
376
402
|
moveableOptions = moveableOptions(this.core);
|
|
377
403
|
}
|
|
378
404
|
return {
|
|
379
|
-
scrollable: true,
|
|
380
405
|
origin: true,
|
|
406
|
+
rootContainer: this.core.container,
|
|
381
407
|
zoom: 1,
|
|
382
|
-
dragArea:
|
|
408
|
+
dragArea: false,
|
|
383
409
|
draggable: true,
|
|
384
410
|
resizable: true,
|
|
385
411
|
snappable: isAbsolute,
|
|
386
412
|
snapGap: isAbsolute,
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
413
|
+
snapThreshold: 5,
|
|
414
|
+
snapDigit: 0,
|
|
415
|
+
throttleDrag: 0,
|
|
416
|
+
isDisplaySnapDigit: isAbsolute,
|
|
417
|
+
snapDirections: {
|
|
418
|
+
top: isAbsolute,
|
|
419
|
+
right: isAbsolute,
|
|
420
|
+
bottom: isAbsolute,
|
|
421
|
+
left: isAbsolute,
|
|
422
|
+
center: isAbsolute,
|
|
423
|
+
middle: isAbsolute
|
|
424
|
+
},
|
|
390
425
|
horizontalGuidelines: this.horizontalGuidelines,
|
|
391
426
|
verticalGuidelines: this.verticalGuidelines,
|
|
392
427
|
bounds: {
|
|
@@ -457,6 +492,36 @@ const up = (deltaTop, target) => {
|
|
|
457
492
|
};
|
|
458
493
|
};
|
|
459
494
|
|
|
495
|
+
class StageHighlight extends EventEmitter {
|
|
496
|
+
core;
|
|
497
|
+
container;
|
|
498
|
+
target;
|
|
499
|
+
moveable;
|
|
500
|
+
constructor(config) {
|
|
501
|
+
super();
|
|
502
|
+
this.core = config.core;
|
|
503
|
+
this.container = config.container;
|
|
504
|
+
}
|
|
505
|
+
highlight(el) {
|
|
506
|
+
if (!el || el === this.target)
|
|
507
|
+
return;
|
|
508
|
+
this.target = el;
|
|
509
|
+
this.moveable?.destroy();
|
|
510
|
+
this.moveable = new Moveable(this.container, {
|
|
511
|
+
target: this.target
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
clearHighlight() {
|
|
515
|
+
if (!this.moveable)
|
|
516
|
+
return;
|
|
517
|
+
this.moveable.target = null;
|
|
518
|
+
this.moveable.updateTarget();
|
|
519
|
+
}
|
|
520
|
+
destroy() {
|
|
521
|
+
this.moveable?.destroy();
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
460
525
|
class Rule extends EventEmitter$1 {
|
|
461
526
|
hGuides;
|
|
462
527
|
vGuides;
|
|
@@ -568,6 +633,7 @@ class Rule extends EventEmitter$1 {
|
|
|
568
633
|
}
|
|
569
634
|
|
|
570
635
|
const wrapperClassName = "editor-mask-wrapper";
|
|
636
|
+
const throttleTime = 100;
|
|
571
637
|
const hideScrollbar = () => {
|
|
572
638
|
const style = globalThis.document.createElement("style");
|
|
573
639
|
style.innerHTML = `
|
|
@@ -615,6 +681,9 @@ class StageMask extends Rule {
|
|
|
615
681
|
mode = Mode.ABSOLUTE;
|
|
616
682
|
pageResizeObserver = null;
|
|
617
683
|
wrapperResizeObserver = null;
|
|
684
|
+
highlightHandler = throttle((event) => {
|
|
685
|
+
this.emit("highlight", event);
|
|
686
|
+
}, throttleTime);
|
|
618
687
|
constructor(config) {
|
|
619
688
|
const wrapper = createWrapper();
|
|
620
689
|
super(wrapper);
|
|
@@ -623,6 +692,7 @@ class StageMask extends Rule {
|
|
|
623
692
|
this.content.addEventListener("mousedown", this.mouseDownHandler);
|
|
624
693
|
this.wrapper.appendChild(this.content);
|
|
625
694
|
this.content.addEventListener("wheel", this.mouseWheelHandler);
|
|
695
|
+
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
626
696
|
}
|
|
627
697
|
setMode(mode) {
|
|
628
698
|
this.mode = mode;
|
|
@@ -694,7 +764,7 @@ class StageMask extends Rule {
|
|
|
694
764
|
this.width = width;
|
|
695
765
|
this.content.style.width = `${width}px`;
|
|
696
766
|
}
|
|
697
|
-
mouseDownHandler =
|
|
767
|
+
mouseDownHandler = (event) => {
|
|
698
768
|
event.stopImmediatePropagation();
|
|
699
769
|
event.stopPropagation();
|
|
700
770
|
if (event.button !== MouseButton.LEFT && event.button !== MouseButton.RIGHT)
|
|
@@ -704,9 +774,12 @@ class StageMask extends Rule {
|
|
|
704
774
|
}
|
|
705
775
|
this.emit("beforeSelect", event);
|
|
706
776
|
globalThis.document.addEventListener("mouseup", this.mouseUpHandler);
|
|
777
|
+
this.content.removeEventListener("mousemove", this.highlightHandler);
|
|
778
|
+
this.emit("clearHighlight");
|
|
707
779
|
};
|
|
708
780
|
mouseUpHandler = () => {
|
|
709
781
|
globalThis.document.removeEventListener("mouseup", this.mouseUpHandler);
|
|
782
|
+
this.content.addEventListener("mousemove", this.highlightHandler);
|
|
710
783
|
this.emit("select");
|
|
711
784
|
};
|
|
712
785
|
mouseWheelHandler = (event) => {
|
|
@@ -815,16 +888,29 @@ class StageRender extends EventEmitter {
|
|
|
815
888
|
this.iframe?.contentDocument?.body?.appendChild(el);
|
|
816
889
|
}
|
|
817
890
|
}
|
|
891
|
+
if (this.contentWindow) {
|
|
892
|
+
const style = this.contentWindow.document.createElement("style");
|
|
893
|
+
style.id = "tmagic-stage-render";
|
|
894
|
+
style.innerHTML = `
|
|
895
|
+
.${SELECTED_CLASS}, .${SELECTED_CLASS}-parent {
|
|
896
|
+
z-index: ${ZIndex.SELECTED_EL};
|
|
897
|
+
}
|
|
898
|
+
`;
|
|
899
|
+
this.contentWindow.document.head.appendChild(style);
|
|
900
|
+
}
|
|
818
901
|
};
|
|
819
902
|
}
|
|
820
903
|
|
|
821
904
|
class StageCore extends EventEmitter {
|
|
822
905
|
selectedDom;
|
|
906
|
+
highlightedDom;
|
|
823
907
|
renderer;
|
|
824
908
|
mask;
|
|
825
909
|
dr;
|
|
910
|
+
highlightLayer;
|
|
826
911
|
config;
|
|
827
912
|
zoom = DEFAULT_ZOOM;
|
|
913
|
+
container;
|
|
828
914
|
canSelect;
|
|
829
915
|
constructor(config) {
|
|
830
916
|
super();
|
|
@@ -834,6 +920,7 @@ class StageCore extends EventEmitter {
|
|
|
834
920
|
this.renderer = new StageRender({ core: this });
|
|
835
921
|
this.mask = new StageMask({ core: this });
|
|
836
922
|
this.dr = new StageDragResize({ core: this, container: this.mask.content });
|
|
923
|
+
this.highlightLayer = new StageHighlight({ core: this, container: this.mask.content });
|
|
837
924
|
this.renderer.on("runtime-ready", (runtime) => this.emit("runtime-ready", runtime));
|
|
838
925
|
this.renderer.on("page-el-update", (el) => this.mask?.observe(el));
|
|
839
926
|
this.mask.on("beforeSelect", (event) => {
|
|
@@ -843,6 +930,12 @@ class StageCore extends EventEmitter {
|
|
|
843
930
|
}).on("changeGuides", (data) => {
|
|
844
931
|
this.dr.setGuidelines(data.type, data.guides);
|
|
845
932
|
this.emit("changeGuides", data);
|
|
933
|
+
}).on("highlight", async (event) => {
|
|
934
|
+
await this.setElementFromPoint(event);
|
|
935
|
+
this.highlightLayer.highlight(this.highlightedDom);
|
|
936
|
+
this.emit("highlight", this.highlightedDom);
|
|
937
|
+
}).on("clearHighlight", async () => {
|
|
938
|
+
this.highlightLayer.clearHighlight();
|
|
846
939
|
});
|
|
847
940
|
this.dr.on("update", (data) => {
|
|
848
941
|
setTimeout(() => this.emit("update", data));
|
|
@@ -869,30 +962,32 @@ class StageCore extends EventEmitter {
|
|
|
869
962
|
if (!el.id.startsWith(GHOST_EL_ID_PREFIX) && await this.canSelect(el, stop)) {
|
|
870
963
|
if (stopped)
|
|
871
964
|
break;
|
|
965
|
+
if (event.type === "mousemove") {
|
|
966
|
+
this.highlight(el);
|
|
967
|
+
break;
|
|
968
|
+
}
|
|
872
969
|
this.select(el, event);
|
|
873
970
|
break;
|
|
874
971
|
}
|
|
875
972
|
}
|
|
876
973
|
}
|
|
877
974
|
async select(idOrEl, event) {
|
|
878
|
-
|
|
879
|
-
if (typeof idOrEl === "string" || typeof idOrEl === "number") {
|
|
880
|
-
const runtime2 = await this.renderer?.getRuntime();
|
|
881
|
-
el = await runtime2?.select?.(`${idOrEl}`);
|
|
882
|
-
if (!el)
|
|
883
|
-
throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
|
|
884
|
-
} else {
|
|
885
|
-
el = idOrEl;
|
|
886
|
-
}
|
|
975
|
+
const el = await this.getTargetElement(idOrEl);
|
|
887
976
|
if (el === this.selectedDom)
|
|
888
977
|
return;
|
|
889
|
-
const runtime = await this.renderer
|
|
978
|
+
const runtime = await this.renderer.getRuntime();
|
|
890
979
|
if (runtime?.beforeSelect) {
|
|
891
980
|
await runtime.beforeSelect(el);
|
|
892
981
|
}
|
|
893
982
|
this.mask.setLayout(el);
|
|
894
983
|
this.dr?.select(el, event);
|
|
895
984
|
this.selectedDom = el;
|
|
985
|
+
if (this.renderer.contentWindow) {
|
|
986
|
+
removeSelectedClassName(this.renderer.contentWindow.document);
|
|
987
|
+
if (this.selectedDom) {
|
|
988
|
+
addSelectedClassName(this.selectedDom);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
896
991
|
}
|
|
897
992
|
update(data) {
|
|
898
993
|
const { config } = data;
|
|
@@ -907,6 +1002,13 @@ class StageCore extends EventEmitter {
|
|
|
907
1002
|
}, 0);
|
|
908
1003
|
});
|
|
909
1004
|
}
|
|
1005
|
+
async highlight(idOrEl) {
|
|
1006
|
+
const el = await this.getTargetElement(idOrEl);
|
|
1007
|
+
if (el === this.highlightedDom)
|
|
1008
|
+
return;
|
|
1009
|
+
this.highlightLayer.highlight(el);
|
|
1010
|
+
this.highlightedDom = el;
|
|
1011
|
+
}
|
|
910
1012
|
sortNode(data) {
|
|
911
1013
|
this.renderer?.getRuntime().then((runtime) => runtime?.sortNode?.(data));
|
|
912
1014
|
}
|
|
@@ -920,6 +1022,7 @@ class StageCore extends EventEmitter {
|
|
|
920
1022
|
this.zoom = zoom;
|
|
921
1023
|
}
|
|
922
1024
|
mount(el) {
|
|
1025
|
+
this.container = el;
|
|
923
1026
|
const { mask, renderer } = this;
|
|
924
1027
|
renderer.mount(el);
|
|
925
1028
|
mask.mount(el);
|
|
@@ -930,11 +1033,25 @@ class StageCore extends EventEmitter {
|
|
|
930
1033
|
this.dr.clearGuides();
|
|
931
1034
|
}
|
|
932
1035
|
destroy() {
|
|
933
|
-
const { mask, renderer, dr } = this;
|
|
1036
|
+
const { mask, renderer, dr, highlightLayer } = this;
|
|
934
1037
|
renderer.destroy();
|
|
935
1038
|
mask.destroy();
|
|
936
1039
|
dr.destroy();
|
|
1040
|
+
highlightLayer.destroy();
|
|
937
1041
|
this.removeAllListeners();
|
|
1042
|
+
this.container = void 0;
|
|
1043
|
+
}
|
|
1044
|
+
async getTargetElement(idOrEl) {
|
|
1045
|
+
let el;
|
|
1046
|
+
if (typeof idOrEl === "string" || typeof idOrEl === "number") {
|
|
1047
|
+
const runtime = await this.renderer?.getRuntime();
|
|
1048
|
+
el = await runtime?.select?.(`${idOrEl}`);
|
|
1049
|
+
if (!el)
|
|
1050
|
+
throw new Error(`\u4E0D\u5B58\u5728ID\u4E3A${idOrEl}\u7684\u5143\u7D20`);
|
|
1051
|
+
} else {
|
|
1052
|
+
el = idOrEl;
|
|
1053
|
+
}
|
|
1054
|
+
return el;
|
|
938
1055
|
}
|
|
939
1056
|
}
|
|
940
1057
|
|