@tmagic/stage 1.2.13 → 1.2.14
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.js +347 -14
- package/dist/tmagic-stage.js.map +1 -1
- package/dist/tmagic-stage.umd.cjs +360 -35
- package/dist/tmagic-stage.umd.cjs.map +1 -1
- package/package.json +6 -6
- package/types/types.d.ts +13 -13
package/dist/tmagic-stage.js
CHANGED
|
@@ -289,16 +289,25 @@ class TargetShadow {
|
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
class DragResizeHelper {
|
|
292
|
+
/** 目标节点在蒙层上的占位节点,用于跟鼠标交互,避免鼠标事件直接作用到目标节点 */
|
|
292
293
|
targetShadow;
|
|
294
|
+
/** 要操作的原始目标节点 */
|
|
293
295
|
target;
|
|
296
|
+
/** 多选:目标节点组 */
|
|
294
297
|
targetList = [];
|
|
298
|
+
/** 响应拖拽的状态事件,修改绝对定位布局下targetShadow的dom。
|
|
299
|
+
* MoveableHelper里面的方法是成员属性,如果DragResizeHelper用继承的方式将无法通过super去调这些方法 */
|
|
295
300
|
moveableHelper;
|
|
301
|
+
/** 流式布局下,目标节点的镜像节点 */
|
|
296
302
|
ghostEl;
|
|
303
|
+
/** 用于记录节点被改变前的位置 */
|
|
297
304
|
frameSnapShot = {
|
|
298
305
|
left: 0,
|
|
299
306
|
top: 0
|
|
300
307
|
};
|
|
308
|
+
/** 多选模式下的多个节点 */
|
|
301
309
|
framesSnapShot = [];
|
|
310
|
+
/** 布局方式:流式布局、绝对定位、固定定位 */
|
|
302
311
|
mode = Mode.ABSOLUTE;
|
|
303
312
|
constructor(config) {
|
|
304
313
|
this.moveableHelper = MoveableHelper.create({
|
|
@@ -332,6 +341,10 @@ class DragResizeHelper {
|
|
|
332
341
|
setMode(mode) {
|
|
333
342
|
this.mode = mode;
|
|
334
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* 改变大小事件开始
|
|
346
|
+
* @param e 包含了拖拽节点的dom,moveableHelper会直接修改拖拽节点
|
|
347
|
+
*/
|
|
335
348
|
onResizeStart(e) {
|
|
336
349
|
this.moveableHelper.onResizeStart(e);
|
|
337
350
|
this.frameSnapShot.top = this.target.offsetTop;
|
|
@@ -420,6 +433,9 @@ class DragResizeHelper {
|
|
|
420
433
|
this.moveableHelper.onResizeGroupStart(e);
|
|
421
434
|
this.setFramesSnapShot(events);
|
|
422
435
|
}
|
|
436
|
+
/**
|
|
437
|
+
* 多选状态下通过拖拽边框改变大小,所有选中组件会一起改变大小
|
|
438
|
+
*/
|
|
423
439
|
onResizeGroup(e) {
|
|
424
440
|
const { events } = e;
|
|
425
441
|
events.forEach((ev) => {
|
|
@@ -493,6 +509,9 @@ class DragResizeHelper {
|
|
|
493
509
|
}
|
|
494
510
|
return { width, height, left, top };
|
|
495
511
|
}
|
|
512
|
+
/**
|
|
513
|
+
* 多选状态设置多个节点的快照
|
|
514
|
+
*/
|
|
496
515
|
setFramesSnapShot(events) {
|
|
497
516
|
if (this.framesSnapShot.length > 0)
|
|
498
517
|
return;
|
|
@@ -509,6 +528,9 @@ class DragResizeHelper {
|
|
|
509
528
|
});
|
|
510
529
|
});
|
|
511
530
|
}
|
|
531
|
+
/**
|
|
532
|
+
* 流式布局把目标节点复制一份进行拖拽,在拖拽结束前不影响页面原布局样式
|
|
533
|
+
*/
|
|
512
534
|
generateGhostEl(el) {
|
|
513
535
|
if (this.ghostEl) {
|
|
514
536
|
this.destroyGhostEl();
|
|
@@ -622,7 +644,7 @@ const MoveableActionsAble = (handler) => ({
|
|
|
622
644
|
"button",
|
|
623
645
|
{
|
|
624
646
|
className: "moveable-button",
|
|
625
|
-
title: "
|
|
647
|
+
title: "选中父组件",
|
|
626
648
|
onClick: () => {
|
|
627
649
|
handler(AbleActionEventType.SELECT_PARENT);
|
|
628
650
|
}
|
|
@@ -651,7 +673,7 @@ const MoveableActionsAble = (handler) => ({
|
|
|
651
673
|
),
|
|
652
674
|
React.createElement("button", {
|
|
653
675
|
className: "moveable-button moveable-remove-button",
|
|
654
|
-
title: "
|
|
676
|
+
title: "删除",
|
|
655
677
|
onClick: () => {
|
|
656
678
|
handler(AbleActionEventType.REMOVE);
|
|
657
679
|
}
|
|
@@ -662,12 +684,19 @@ const MoveableActionsAble = (handler) => ({
|
|
|
662
684
|
});
|
|
663
685
|
|
|
664
686
|
class MoveableOptionsManager extends EventEmitter {
|
|
687
|
+
/** 布局方式:流式布局、绝对定位、固定定位 */
|
|
665
688
|
mode = Mode.ABSOLUTE;
|
|
689
|
+
/** 画布容器 */
|
|
666
690
|
container;
|
|
691
|
+
/** 水平参考线 */
|
|
667
692
|
horizontalGuidelines = [];
|
|
693
|
+
/** 垂直参考线 */
|
|
668
694
|
verticalGuidelines = [];
|
|
695
|
+
/** 对齐元素集合 */
|
|
669
696
|
elementGuidelines = [];
|
|
697
|
+
/** 由外部调用方(编辑器)传入进来的moveable默认参数,可以为空,也可以是一个回调函数 */
|
|
670
698
|
customizedOptions;
|
|
699
|
+
/** 获取整个画布的根元素(在StageCore的mount函数中挂载的container) */
|
|
671
700
|
getRootContainer;
|
|
672
701
|
constructor(config) {
|
|
673
702
|
super();
|
|
@@ -675,6 +704,11 @@ class MoveableOptionsManager extends EventEmitter {
|
|
|
675
704
|
this.container = config.container;
|
|
676
705
|
this.getRootContainer = config.getRootContainer;
|
|
677
706
|
}
|
|
707
|
+
/**
|
|
708
|
+
* 设置水平/垂直参考线
|
|
709
|
+
* @param type 参考线类型
|
|
710
|
+
* @param guidelines 参考线坐标数组
|
|
711
|
+
*/
|
|
678
712
|
setGuidelines(type, guidelines) {
|
|
679
713
|
if (type === GuidesType.HORIZONTAL) {
|
|
680
714
|
this.horizontalGuidelines = guidelines;
|
|
@@ -683,11 +717,19 @@ class MoveableOptionsManager extends EventEmitter {
|
|
|
683
717
|
}
|
|
684
718
|
this.emit("update-moveable");
|
|
685
719
|
}
|
|
720
|
+
/**
|
|
721
|
+
* 清除横向和纵向的参考线
|
|
722
|
+
*/
|
|
686
723
|
clearGuides() {
|
|
687
724
|
this.horizontalGuidelines = [];
|
|
688
725
|
this.verticalGuidelines = [];
|
|
689
726
|
this.emit("update-moveable");
|
|
690
727
|
}
|
|
728
|
+
/**
|
|
729
|
+
* 设置有哪些元素要辅助对齐
|
|
730
|
+
* @param selectedElList 选中的元素列表,需要排除在对齐元素之外
|
|
731
|
+
* @param allElList 全部元素列表
|
|
732
|
+
*/
|
|
691
733
|
setElementGuidelines(selectedElList, allElList) {
|
|
692
734
|
this.elementGuidelines.forEach((node) => {
|
|
693
735
|
node.remove();
|
|
@@ -697,11 +739,21 @@ class MoveableOptionsManager extends EventEmitter {
|
|
|
697
739
|
this.container.append(this.createGuidelineElements(selectedElList, allElList));
|
|
698
740
|
}
|
|
699
741
|
}
|
|
742
|
+
/**
|
|
743
|
+
* 获取moveable参数
|
|
744
|
+
* @param isMultiSelect 是否多选模式
|
|
745
|
+
* @param runtimeOptions 调用时实时传进来的的moveable参数
|
|
746
|
+
* @returns moveable所需参数
|
|
747
|
+
*/
|
|
700
748
|
getOptions(isMultiSelect, runtimeOptions = {}) {
|
|
701
749
|
const defaultOptions = this.getDefaultOptions(isMultiSelect);
|
|
702
750
|
const customizedOptions = this.getCustomizeOptions();
|
|
703
751
|
return merge(defaultOptions, customizedOptions, runtimeOptions);
|
|
704
752
|
}
|
|
753
|
+
/**
|
|
754
|
+
* 获取单选和多选的moveable公共参数
|
|
755
|
+
* @returns moveable公共参数
|
|
756
|
+
*/
|
|
705
757
|
getDefaultOptions(isMultiSelect) {
|
|
706
758
|
const isSortable = this.mode === Mode.SORTABLE;
|
|
707
759
|
const commonOptions = {
|
|
@@ -716,6 +768,7 @@ class MoveableOptionsManager extends EventEmitter {
|
|
|
716
768
|
elementGuidelines: this.elementGuidelines,
|
|
717
769
|
bounds: {
|
|
718
770
|
top: 0,
|
|
771
|
+
// 设置0的话无法移动到left为0,所以只能设置为-1
|
|
719
772
|
left: -1,
|
|
720
773
|
right: this.container.clientWidth - 1,
|
|
721
774
|
bottom: isSortable ? void 0 : this.container.clientHeight
|
|
@@ -724,6 +777,10 @@ class MoveableOptionsManager extends EventEmitter {
|
|
|
724
777
|
const differenceOptions = isMultiSelect ? this.getMultiOptions() : this.getSingleOptions();
|
|
725
778
|
return merge(commonOptions, differenceOptions);
|
|
726
779
|
}
|
|
780
|
+
/**
|
|
781
|
+
* 获取单选下的差异化参数
|
|
782
|
+
* @returns {MoveableOptions} moveable options参数
|
|
783
|
+
*/
|
|
727
784
|
getSingleOptions() {
|
|
728
785
|
const isAbsolute = this.mode === Mode.ABSOLUTE;
|
|
729
786
|
const isFixed = this.mode === Mode.FIXED;
|
|
@@ -757,6 +814,10 @@ class MoveableOptionsManager extends EventEmitter {
|
|
|
757
814
|
ables: [MoveableActionsAble(this.actionHandler.bind(this))]
|
|
758
815
|
};
|
|
759
816
|
}
|
|
817
|
+
/**
|
|
818
|
+
* 获取多选下的差异化参数
|
|
819
|
+
* @returns {MoveableOptions} moveable options参数
|
|
820
|
+
*/
|
|
760
821
|
getMultiOptions() {
|
|
761
822
|
return {
|
|
762
823
|
defaultGroupRotate: 0,
|
|
@@ -767,15 +828,27 @@ class MoveableOptionsManager extends EventEmitter {
|
|
|
767
828
|
padding: { left: 0, top: 0, right: 0, bottom: 0 }
|
|
768
829
|
};
|
|
769
830
|
}
|
|
831
|
+
/**
|
|
832
|
+
* 获取业务方自定义的moveable参数
|
|
833
|
+
*/
|
|
770
834
|
getCustomizeOptions() {
|
|
771
835
|
if (typeof this.customizedOptions === "function") {
|
|
772
836
|
return this.customizedOptions();
|
|
773
837
|
}
|
|
774
838
|
return this.customizedOptions;
|
|
775
839
|
}
|
|
840
|
+
/**
|
|
841
|
+
* 这是给selectParentAbles的回调函数,用于触发选中父元素事件
|
|
842
|
+
*/
|
|
776
843
|
actionHandler(type) {
|
|
777
844
|
this.emit(type);
|
|
778
845
|
}
|
|
846
|
+
/**
|
|
847
|
+
* 为需要辅助对齐的元素创建div
|
|
848
|
+
* @param selectedElList 选中的元素列表,需要排除在对齐元素之外
|
|
849
|
+
* @param allElList 全部元素列表
|
|
850
|
+
* @returns frame 辅助对齐元素集合的页面片
|
|
851
|
+
*/
|
|
779
852
|
createGuidelineElements(selectedElList, allElList) {
|
|
780
853
|
const frame = globalThis.document.createDocumentFragment();
|
|
781
854
|
for (const node of allElList) {
|
|
@@ -790,6 +863,12 @@ class MoveableOptionsManager extends EventEmitter {
|
|
|
790
863
|
}
|
|
791
864
|
return frame;
|
|
792
865
|
}
|
|
866
|
+
/**
|
|
867
|
+
* 判断一个元素是否在元素列表里面
|
|
868
|
+
* @param ele 元素
|
|
869
|
+
* @param eleList 元素列表
|
|
870
|
+
* @returns 是否在元素列表里面
|
|
871
|
+
*/
|
|
793
872
|
isInElementList(ele, eleList) {
|
|
794
873
|
for (const eleItem of eleList) {
|
|
795
874
|
if (ele === eleItem)
|
|
@@ -800,8 +879,11 @@ class MoveableOptionsManager extends EventEmitter {
|
|
|
800
879
|
}
|
|
801
880
|
|
|
802
881
|
class StageDragResize extends MoveableOptionsManager {
|
|
882
|
+
/** 目标节点 */
|
|
803
883
|
target;
|
|
884
|
+
/** Moveable拖拽类实例 */
|
|
804
885
|
moveable;
|
|
886
|
+
/** 拖动状态 */
|
|
805
887
|
dragStatus = StageDragStatus.END;
|
|
806
888
|
dragResizeHelper;
|
|
807
889
|
disabledDragStart;
|
|
@@ -824,6 +906,12 @@ class StageDragResize extends MoveableOptionsManager {
|
|
|
824
906
|
getTarget() {
|
|
825
907
|
return this.target;
|
|
826
908
|
}
|
|
909
|
+
/**
|
|
910
|
+
* 将选中框渲染并覆盖到选中的组件Dom节点上方
|
|
911
|
+
* 当选中的节点不是absolute时,会创建一个新的节点出来作为拖拽目标
|
|
912
|
+
* @param el 选中组件的Dom节点元素
|
|
913
|
+
* @param event 鼠标事件
|
|
914
|
+
*/
|
|
827
915
|
select(el, event) {
|
|
828
916
|
if (!this.moveable || el !== this.target) {
|
|
829
917
|
this.initMoveable(el);
|
|
@@ -834,11 +922,14 @@ class StageDragResize extends MoveableOptionsManager {
|
|
|
834
922
|
this.moveable?.dragStart(event);
|
|
835
923
|
}
|
|
836
924
|
}
|
|
925
|
+
/**
|
|
926
|
+
* 初始化选中框并渲染出来
|
|
927
|
+
*/
|
|
837
928
|
updateMoveable(el = this.target) {
|
|
838
929
|
if (!this.moveable)
|
|
839
930
|
return;
|
|
840
931
|
if (!el)
|
|
841
|
-
throw new Error("
|
|
932
|
+
throw new Error("未选中任何节点");
|
|
842
933
|
const options = this.init(el);
|
|
843
934
|
Object.entries(options).forEach(([key, value]) => {
|
|
844
935
|
this.moveable[key] = value;
|
|
@@ -852,6 +943,9 @@ class StageDragResize extends MoveableOptionsManager {
|
|
|
852
943
|
this.moveable.target = null;
|
|
853
944
|
this.moveable.updateTarget();
|
|
854
945
|
}
|
|
946
|
+
/**
|
|
947
|
+
* 销毁实例
|
|
948
|
+
*/
|
|
855
949
|
destroy() {
|
|
856
950
|
this.moveable?.destroy();
|
|
857
951
|
this.dragResizeHelper.destroy();
|
|
@@ -886,7 +980,7 @@ class StageDragResize extends MoveableOptionsManager {
|
|
|
886
980
|
}
|
|
887
981
|
bindResizeEvent() {
|
|
888
982
|
if (!this.moveable)
|
|
889
|
-
throw new Error("moveable
|
|
983
|
+
throw new Error("moveable 未初始化");
|
|
890
984
|
this.moveable.on("resizeStart", (e) => {
|
|
891
985
|
if (!this.target)
|
|
892
986
|
return;
|
|
@@ -904,11 +998,11 @@ class StageDragResize extends MoveableOptionsManager {
|
|
|
904
998
|
}
|
|
905
999
|
bindDragEvent() {
|
|
906
1000
|
if (!this.moveable)
|
|
907
|
-
throw new Error("moveable
|
|
1001
|
+
throw new Error("moveable 未初始化");
|
|
908
1002
|
let timeout;
|
|
909
1003
|
this.moveable.on("dragStart", (e) => {
|
|
910
1004
|
if (!this.target)
|
|
911
|
-
throw new Error("
|
|
1005
|
+
throw new Error("未选中组件");
|
|
912
1006
|
this.dragStatus = StageDragStatus.START;
|
|
913
1007
|
this.dragResizeHelper.onDragStart(e);
|
|
914
1008
|
}).on("drag", (e) => {
|
|
@@ -946,7 +1040,7 @@ class StageDragResize extends MoveableOptionsManager {
|
|
|
946
1040
|
}
|
|
947
1041
|
bindRotateEvent() {
|
|
948
1042
|
if (!this.moveable)
|
|
949
|
-
throw new Error("moveable
|
|
1043
|
+
throw new Error("moveable 未初始化");
|
|
950
1044
|
this.moveable.on("rotateStart", (e) => {
|
|
951
1045
|
this.dragStatus = StageDragStatus.START;
|
|
952
1046
|
this.dragResizeHelper.onRotateStart(e);
|
|
@@ -972,7 +1066,7 @@ class StageDragResize extends MoveableOptionsManager {
|
|
|
972
1066
|
}
|
|
973
1067
|
bindScaleEvent() {
|
|
974
1068
|
if (!this.moveable)
|
|
975
|
-
throw new Error("moveable
|
|
1069
|
+
throw new Error("moveable 未初始化");
|
|
976
1070
|
this.moveable.on("scaleStart", (e) => {
|
|
977
1071
|
this.dragStatus = StageDragStatus.START;
|
|
978
1072
|
this.dragResizeHelper.onScaleStart(e);
|
|
@@ -998,7 +1092,7 @@ class StageDragResize extends MoveableOptionsManager {
|
|
|
998
1092
|
}
|
|
999
1093
|
sort() {
|
|
1000
1094
|
if (!this.target || !this.dragResizeHelper.getGhostEl())
|
|
1001
|
-
throw new Error("
|
|
1095
|
+
throw new Error("未知错误");
|
|
1002
1096
|
const { top } = this.dragResizeHelper.getGhostEl().getBoundingClientRect();
|
|
1003
1097
|
const { top: oriTop } = this.target.getBoundingClientRect();
|
|
1004
1098
|
const deltaTop = top - oriTop;
|
|
@@ -1051,6 +1145,10 @@ class StageHighlight extends EventEmitter$1 {
|
|
|
1051
1145
|
idPrefix: HIGHLIGHT_EL_ID_PREFIX
|
|
1052
1146
|
});
|
|
1053
1147
|
}
|
|
1148
|
+
/**
|
|
1149
|
+
* 高亮鼠标悬停的组件
|
|
1150
|
+
* @param el 选中组件的Dom节点元素
|
|
1151
|
+
*/
|
|
1054
1152
|
highlight(el) {
|
|
1055
1153
|
if (!el || el === this.target)
|
|
1056
1154
|
return;
|
|
@@ -1063,6 +1161,9 @@ class StageHighlight extends EventEmitter$1 {
|
|
|
1063
1161
|
zoom: 2
|
|
1064
1162
|
});
|
|
1065
1163
|
}
|
|
1164
|
+
/**
|
|
1165
|
+
* 清空高亮
|
|
1166
|
+
*/
|
|
1066
1167
|
clearHighlight() {
|
|
1067
1168
|
if (!this.moveable || !this.target)
|
|
1068
1169
|
return;
|
|
@@ -1070,6 +1171,9 @@ class StageHighlight extends EventEmitter$1 {
|
|
|
1070
1171
|
this.moveable.target = null;
|
|
1071
1172
|
this.moveable.updateTarget();
|
|
1072
1173
|
}
|
|
1174
|
+
/**
|
|
1175
|
+
* 销毁实例
|
|
1176
|
+
*/
|
|
1073
1177
|
destroy() {
|
|
1074
1178
|
this.moveable?.destroy();
|
|
1075
1179
|
this.targetShadow.destroy();
|
|
@@ -1077,8 +1181,11 @@ class StageHighlight extends EventEmitter$1 {
|
|
|
1077
1181
|
}
|
|
1078
1182
|
|
|
1079
1183
|
class StageMultiDragResize extends MoveableOptionsManager {
|
|
1184
|
+
/** 画布容器 */
|
|
1080
1185
|
container;
|
|
1186
|
+
/** 多选:目标节点组 */
|
|
1081
1187
|
targetList = [];
|
|
1188
|
+
/** Moveable多选拖拽类实例 */
|
|
1082
1189
|
moveableForMulti;
|
|
1083
1190
|
dragStatus = StageDragStatus.END;
|
|
1084
1191
|
dragResizeHelper;
|
|
@@ -1103,6 +1210,10 @@ class StageMultiDragResize extends MoveableOptionsManager {
|
|
|
1103
1210
|
}
|
|
1104
1211
|
});
|
|
1105
1212
|
}
|
|
1213
|
+
/**
|
|
1214
|
+
* 多选
|
|
1215
|
+
* @param els
|
|
1216
|
+
*/
|
|
1106
1217
|
multiSelect(els) {
|
|
1107
1218
|
if (els.length === 0) {
|
|
1108
1219
|
return;
|
|
@@ -1172,7 +1283,7 @@ class StageMultiDragResize extends MoveableOptionsManager {
|
|
|
1172
1283
|
if (!this.moveableForMulti)
|
|
1173
1284
|
return;
|
|
1174
1285
|
if (!eleList)
|
|
1175
|
-
throw new Error("
|
|
1286
|
+
throw new Error("未选中任何节点");
|
|
1176
1287
|
this.targetList = eleList;
|
|
1177
1288
|
this.dragResizeHelper.setTargetList(eleList);
|
|
1178
1289
|
const options = this.getOptions(true, {
|
|
@@ -1183,6 +1294,9 @@ class StageMultiDragResize extends MoveableOptionsManager {
|
|
|
1183
1294
|
});
|
|
1184
1295
|
this.moveableForMulti.updateTarget();
|
|
1185
1296
|
}
|
|
1297
|
+
/**
|
|
1298
|
+
* 清除多选状态
|
|
1299
|
+
*/
|
|
1186
1300
|
clearSelectStatus() {
|
|
1187
1301
|
if (!this.moveableForMulti)
|
|
1188
1302
|
return;
|
|
@@ -1191,10 +1305,17 @@ class StageMultiDragResize extends MoveableOptionsManager {
|
|
|
1191
1305
|
this.moveableForMulti.updateTarget();
|
|
1192
1306
|
this.targetList = [];
|
|
1193
1307
|
}
|
|
1308
|
+
/**
|
|
1309
|
+
* 销毁实例
|
|
1310
|
+
*/
|
|
1194
1311
|
destroy() {
|
|
1195
1312
|
this.moveableForMulti?.destroy();
|
|
1196
1313
|
this.dragResizeHelper.destroy();
|
|
1197
1314
|
}
|
|
1315
|
+
/**
|
|
1316
|
+
* 拖拽完成后将更新的位置信息暴露给上层业务方,业务方可以接收事件进行保存
|
|
1317
|
+
* @param isResize 是否进行大小缩放
|
|
1318
|
+
*/
|
|
1198
1319
|
update(isResize = false, parentEl = null) {
|
|
1199
1320
|
if (this.targetList.length === 0)
|
|
1200
1321
|
return;
|
|
@@ -1218,13 +1339,21 @@ class ActionManager extends EventEmitter {
|
|
|
1218
1339
|
dr;
|
|
1219
1340
|
multiDr;
|
|
1220
1341
|
highlightLayer;
|
|
1342
|
+
/** 单选、多选、高亮的容器(蒙层的content) */
|
|
1221
1343
|
container;
|
|
1344
|
+
/** 当前选中的节点 */
|
|
1222
1345
|
selectedEl;
|
|
1346
|
+
/** 多选选中的节点组 */
|
|
1223
1347
|
selectedElList = [];
|
|
1348
|
+
/** 当前高亮的节点 */
|
|
1224
1349
|
highlightedEl;
|
|
1350
|
+
/** 当前是否处于多选状态 */
|
|
1225
1351
|
isMultiSelectStatus = false;
|
|
1352
|
+
/** 当拖拽组件到容器上方进入可加入容器状态时,给容器添加的一个class名称 */
|
|
1226
1353
|
containerHighlightClassName;
|
|
1354
|
+
/** 当拖拽组件到容器上方时,需要悬停多久才能将组件加入容器 */
|
|
1227
1355
|
containerHighlightDuration;
|
|
1356
|
+
/** 将组件加入容器的操作方式 */
|
|
1228
1357
|
containerHighlightType;
|
|
1229
1358
|
isAltKeydown = false;
|
|
1230
1359
|
getTargetElement;
|
|
@@ -1283,18 +1412,33 @@ class ActionManager extends EventEmitter {
|
|
|
1283
1412
|
this.initKeyEvent();
|
|
1284
1413
|
this.initActionEvent();
|
|
1285
1414
|
}
|
|
1415
|
+
/**
|
|
1416
|
+
* 设置水平/垂直参考线
|
|
1417
|
+
* @param type 参考线类型
|
|
1418
|
+
* @param guidelines 参考线坐标数组
|
|
1419
|
+
*/
|
|
1286
1420
|
setGuidelines(type, guidelines) {
|
|
1287
1421
|
this.dr.setGuidelines(type, guidelines);
|
|
1288
1422
|
this.multiDr.setGuidelines(type, guidelines);
|
|
1289
1423
|
}
|
|
1424
|
+
/**
|
|
1425
|
+
* 清空所有参考线
|
|
1426
|
+
*/
|
|
1290
1427
|
clearGuides() {
|
|
1291
1428
|
this.dr.clearGuides();
|
|
1292
1429
|
this.multiDr.clearGuides();
|
|
1293
1430
|
}
|
|
1431
|
+
/**
|
|
1432
|
+
* 更新moveable,外部主要调用场景是元素配置变更、页面大小变更
|
|
1433
|
+
* @param el 变更的元素
|
|
1434
|
+
*/
|
|
1294
1435
|
updateMoveable(el) {
|
|
1295
1436
|
this.dr.updateMoveable(el);
|
|
1296
1437
|
this.multiDr.updateMoveable();
|
|
1297
1438
|
}
|
|
1439
|
+
/**
|
|
1440
|
+
* 判断是否单选选中的元素
|
|
1441
|
+
*/
|
|
1298
1442
|
isSelectedEl(el) {
|
|
1299
1443
|
return el.id === this.selectedEl?.id;
|
|
1300
1444
|
}
|
|
@@ -1307,6 +1451,11 @@ class ActionManager extends EventEmitter {
|
|
|
1307
1451
|
getSelectedElList() {
|
|
1308
1452
|
return this.selectedElList;
|
|
1309
1453
|
}
|
|
1454
|
+
/**
|
|
1455
|
+
* 获取鼠标下方第一个可选中元素,如果元素层叠,返回到是最上层元素
|
|
1456
|
+
* @param event 鼠标事件
|
|
1457
|
+
* @returns 鼠标下方第一个可选中元素
|
|
1458
|
+
*/
|
|
1310
1459
|
async getElementFromPoint(event) {
|
|
1311
1460
|
const els = this.getElementsFromPoint(event);
|
|
1312
1461
|
let stopped = false;
|
|
@@ -1319,6 +1468,13 @@ class ActionManager extends EventEmitter {
|
|
|
1319
1468
|
}
|
|
1320
1469
|
}
|
|
1321
1470
|
}
|
|
1471
|
+
/**
|
|
1472
|
+
* 判断一个元素能否在当前场景被选中
|
|
1473
|
+
* @param el 被判断的元素
|
|
1474
|
+
* @param event 鼠标事件
|
|
1475
|
+
* @param stop 通过该元素如果得知剩下的元素都不可被选中,通知调用方终止对剩下元素的判断
|
|
1476
|
+
* @returns 能否选中
|
|
1477
|
+
*/
|
|
1322
1478
|
async isElCanSelect(el, event, stop) {
|
|
1323
1479
|
const canSelectByProp = await this.canSelect(el, event, stop);
|
|
1324
1480
|
if (!canSelectByProp)
|
|
@@ -1328,6 +1484,9 @@ class ActionManager extends EventEmitter {
|
|
|
1328
1484
|
}
|
|
1329
1485
|
return true;
|
|
1330
1486
|
}
|
|
1487
|
+
/**
|
|
1488
|
+
* 判断一个元素是否可以被多选,如果当前元素是page,则调stop函数告诉调用方不必继续判断其它元素了
|
|
1489
|
+
*/
|
|
1331
1490
|
canMultiSelect(el, stop) {
|
|
1332
1491
|
if (el.className.includes(PAGE_CLASS)) {
|
|
1333
1492
|
stop();
|
|
@@ -1377,6 +1536,10 @@ class ActionManager extends EventEmitter {
|
|
|
1377
1536
|
this.setHighlightEl(void 0);
|
|
1378
1537
|
this.highlightLayer.clearHighlight();
|
|
1379
1538
|
}
|
|
1539
|
+
/**
|
|
1540
|
+
* 用于在切换选择模式时清除上一次的状态
|
|
1541
|
+
* @param selectType 需要清理的选择模式
|
|
1542
|
+
*/
|
|
1380
1543
|
clearSelectStatus(selectType) {
|
|
1381
1544
|
if (selectType === SelectStatus.MULTI_SELECT) {
|
|
1382
1545
|
this.multiDr.clearSelectStatus();
|
|
@@ -1385,6 +1548,11 @@ class ActionManager extends EventEmitter {
|
|
|
1385
1548
|
this.dr.clearSelectStatus();
|
|
1386
1549
|
}
|
|
1387
1550
|
}
|
|
1551
|
+
/**
|
|
1552
|
+
* 找到鼠标下方的容器,通过添加className对容器进行标记
|
|
1553
|
+
* @param event 鼠标事件
|
|
1554
|
+
* @param excludeElList 计算鼠标点所在容器时要排除的元素列表
|
|
1555
|
+
*/
|
|
1388
1556
|
async addContainerHighlightClassName(event, excludeElList) {
|
|
1389
1557
|
const doc = this.getRenderDocument();
|
|
1390
1558
|
if (!doc)
|
|
@@ -1397,6 +1565,13 @@ class ActionManager extends EventEmitter {
|
|
|
1397
1565
|
}
|
|
1398
1566
|
}
|
|
1399
1567
|
}
|
|
1568
|
+
/**
|
|
1569
|
+
* 鼠标拖拽着元素,在容器上方悬停,延迟一段时间后,对容器进行标记,如果悬停时间够长将标记成功,悬停时间短,调用方通过返回的timeoutId取消标记
|
|
1570
|
+
* 标记的作用:1、高亮容器,给用户一个加入容器的交互感知;2、释放鼠标后,通过标记的标志找到要加入的容器
|
|
1571
|
+
* @param event 鼠标事件
|
|
1572
|
+
* @param excludeElList 计算鼠标所在容器时要排除的元素列表
|
|
1573
|
+
* @returns timeoutId,调用方在鼠标移走时要取消该timeout,阻止标记
|
|
1574
|
+
*/
|
|
1400
1575
|
delayedMarkContainer(event, excludeElList = []) {
|
|
1401
1576
|
if (this.canAddToContainer()) {
|
|
1402
1577
|
return globalThis.setTimeout(() => {
|
|
@@ -1428,6 +1603,11 @@ class ActionManager extends EventEmitter {
|
|
|
1428
1603
|
}
|
|
1429
1604
|
return options;
|
|
1430
1605
|
}
|
|
1606
|
+
/**
|
|
1607
|
+
* 在执行多选逻辑前,先准备好多选选中元素
|
|
1608
|
+
* @param el 新选中的元素
|
|
1609
|
+
* @returns 多选选中的元素列表
|
|
1610
|
+
*/
|
|
1431
1611
|
async beforeMultiSelect(event) {
|
|
1432
1612
|
const el = await this.getElementFromPoint(event);
|
|
1433
1613
|
if (!el)
|
|
@@ -1443,9 +1623,16 @@ class ActionManager extends EventEmitter {
|
|
|
1443
1623
|
this.selectedElList.push(el);
|
|
1444
1624
|
}
|
|
1445
1625
|
}
|
|
1626
|
+
/**
|
|
1627
|
+
* 当前状态下能否将组件加入容器,默认是鼠标悬停一段时间加入,alt模式则是按住alt+鼠标悬停一段时间加入
|
|
1628
|
+
*/
|
|
1446
1629
|
canAddToContainer() {
|
|
1447
1630
|
return this.containerHighlightType === ContainerHighlightType.DEFAULT || this.containerHighlightType === ContainerHighlightType.ALT && this.isAltKeydown;
|
|
1448
1631
|
}
|
|
1632
|
+
/**
|
|
1633
|
+
* 结束对container的标记状态
|
|
1634
|
+
* @returns 标记的容器元素,没有标记的容器时返回null
|
|
1635
|
+
*/
|
|
1449
1636
|
markContainerEnd() {
|
|
1450
1637
|
const doc = this.getRenderDocument();
|
|
1451
1638
|
if (doc && this.canAddToContainer()) {
|
|
@@ -1459,6 +1646,9 @@ class ActionManager extends EventEmitter {
|
|
|
1459
1646
|
this.container.addEventListener("mouseleave", this.mouseLeaveHandler);
|
|
1460
1647
|
this.container.addEventListener("wheel", this.mouseWheelHandler);
|
|
1461
1648
|
}
|
|
1649
|
+
/**
|
|
1650
|
+
* 初始化键盘事件监听
|
|
1651
|
+
*/
|
|
1462
1652
|
initKeyEvent() {
|
|
1463
1653
|
const { isMac } = new Env();
|
|
1464
1654
|
const ctrl = isMac ? "meta" : "ctrl";
|
|
@@ -1483,6 +1673,9 @@ class ActionManager extends EventEmitter {
|
|
|
1483
1673
|
this.isAltKeydown = false;
|
|
1484
1674
|
});
|
|
1485
1675
|
}
|
|
1676
|
+
/**
|
|
1677
|
+
* 处理单选、多选抛出来的事件
|
|
1678
|
+
*/
|
|
1486
1679
|
initActionEvent() {
|
|
1487
1680
|
this.dr.on("update", (data) => {
|
|
1488
1681
|
setTimeout(() => this.emit("update", data));
|
|
@@ -1508,6 +1701,9 @@ class ActionManager extends EventEmitter {
|
|
|
1508
1701
|
this.emit("change-to-select", el);
|
|
1509
1702
|
});
|
|
1510
1703
|
}
|
|
1704
|
+
/**
|
|
1705
|
+
* 在down事件中集中cpu处理画布中选中操作渲染,在up事件中再通知外面的编辑器更新
|
|
1706
|
+
*/
|
|
1511
1707
|
mouseDownHandler = async (event) => {
|
|
1512
1708
|
this.clearHighlight();
|
|
1513
1709
|
event.stopImmediatePropagation();
|
|
@@ -1542,6 +1738,9 @@ class ActionManager extends EventEmitter {
|
|
|
1542
1738
|
}
|
|
1543
1739
|
return false;
|
|
1544
1740
|
}
|
|
1741
|
+
/**
|
|
1742
|
+
* 在up事件中负责对外通知选中事件,通知画布之外的编辑器更新
|
|
1743
|
+
*/
|
|
1545
1744
|
mouseUpHandler = () => {
|
|
1546
1745
|
getDocument().removeEventListener("mouseup", this.mouseUpHandler);
|
|
1547
1746
|
this.container.addEventListener("mousemove", this.mouseMoveHandler);
|
|
@@ -1580,6 +1779,10 @@ class Rule extends EventEmitter {
|
|
|
1580
1779
|
});
|
|
1581
1780
|
this.containerResizeObserver.observe(this.container);
|
|
1582
1781
|
}
|
|
1782
|
+
/**
|
|
1783
|
+
* 是否显示辅助线
|
|
1784
|
+
* @param isShowGuides 是否显示
|
|
1785
|
+
*/
|
|
1583
1786
|
showGuides(isShowGuides = true) {
|
|
1584
1787
|
this.isShowGuides = isShowGuides;
|
|
1585
1788
|
this.hGuides.setState({
|
|
@@ -1607,9 +1810,16 @@ class Rule extends EventEmitter {
|
|
|
1607
1810
|
guides: vLines
|
|
1608
1811
|
});
|
|
1609
1812
|
}
|
|
1813
|
+
/**
|
|
1814
|
+
* 清空所有参考线
|
|
1815
|
+
*/
|
|
1610
1816
|
clearGuides() {
|
|
1611
1817
|
this.setGuides([[], []]);
|
|
1612
1818
|
}
|
|
1819
|
+
/**
|
|
1820
|
+
* 是否显示标尺
|
|
1821
|
+
* @param show 是否显示
|
|
1822
|
+
*/
|
|
1613
1823
|
showRule(show = true) {
|
|
1614
1824
|
if (show) {
|
|
1615
1825
|
this.hGuides.destroy();
|
|
@@ -1739,6 +1949,11 @@ class StageMask extends Rule {
|
|
|
1739
1949
|
this.content.style.height = `${this.height}px`;
|
|
1740
1950
|
}
|
|
1741
1951
|
}
|
|
1952
|
+
/**
|
|
1953
|
+
* 初始化视窗和蒙层监听,监听元素是否在视窗区域、监听mask蒙层所在的wrapper大小变化
|
|
1954
|
+
* @description 初始化视窗和蒙层监听
|
|
1955
|
+
* @param page 页面Dom节点
|
|
1956
|
+
*/
|
|
1742
1957
|
observe(page) {
|
|
1743
1958
|
if (!page)
|
|
1744
1959
|
return;
|
|
@@ -1746,6 +1961,10 @@ class StageMask extends Rule {
|
|
|
1746
1961
|
this.initObserverIntersection();
|
|
1747
1962
|
this.initObserverWrapper();
|
|
1748
1963
|
}
|
|
1964
|
+
/**
|
|
1965
|
+
* 处理页面大小变更,同步页面和mask大小
|
|
1966
|
+
* @param entries ResizeObserverEntry,获取页面最新大小
|
|
1967
|
+
*/
|
|
1749
1968
|
pageResize(entries) {
|
|
1750
1969
|
const [entry] = entries;
|
|
1751
1970
|
const { clientHeight, clientWidth } = entry.target;
|
|
@@ -1753,12 +1972,20 @@ class StageMask extends Rule {
|
|
|
1753
1972
|
this.setWidth(clientWidth);
|
|
1754
1973
|
this.scroll();
|
|
1755
1974
|
}
|
|
1975
|
+
/**
|
|
1976
|
+
* 监听一个组件是否在画布可视区域内
|
|
1977
|
+
* @param el 被选中的组件,可能是左侧目录树中选中的
|
|
1978
|
+
*/
|
|
1756
1979
|
observerIntersection(el) {
|
|
1757
1980
|
this.intersectionObserver?.observe(el);
|
|
1758
1981
|
}
|
|
1982
|
+
/**
|
|
1983
|
+
* 挂载Dom节点
|
|
1984
|
+
* @param el 将蒙层挂载到该Dom节点上
|
|
1985
|
+
*/
|
|
1759
1986
|
mount(el) {
|
|
1760
1987
|
if (!this.content)
|
|
1761
|
-
throw new Error("content
|
|
1988
|
+
throw new Error("content 不存在");
|
|
1762
1989
|
el.appendChild(this.wrapper);
|
|
1763
1990
|
}
|
|
1764
1991
|
setLayout(el) {
|
|
@@ -1772,6 +1999,9 @@ class StageMask extends Rule {
|
|
|
1772
1999
|
this.scrollTop = this.pageScrollParent.scrollTop;
|
|
1773
2000
|
this.scroll();
|
|
1774
2001
|
}
|
|
2002
|
+
/**
|
|
2003
|
+
* 销毁实例
|
|
2004
|
+
*/
|
|
1775
2005
|
destroy() {
|
|
1776
2006
|
this.content?.remove();
|
|
1777
2007
|
this.page = null;
|
|
@@ -1779,6 +2009,9 @@ class StageMask extends Rule {
|
|
|
1779
2009
|
this.wrapperResizeObserver?.disconnect();
|
|
1780
2010
|
super.destroy();
|
|
1781
2011
|
}
|
|
2012
|
+
/**
|
|
2013
|
+
* 监听选中元素是否在画布可视区域内,如果目标元素不在可视区域内,通过滚动使该元素出现在可视区域
|
|
2014
|
+
*/
|
|
1782
2015
|
initObserverIntersection() {
|
|
1783
2016
|
this.pageScrollParent = getScrollParent(this.page) || null;
|
|
1784
2017
|
this.intersectionObserver?.disconnect();
|
|
@@ -1801,6 +2034,9 @@ class StageMask extends Rule {
|
|
|
1801
2034
|
);
|
|
1802
2035
|
}
|
|
1803
2036
|
}
|
|
2037
|
+
/**
|
|
2038
|
+
* 监听mask的容器大小变化
|
|
2039
|
+
*/
|
|
1804
2040
|
initObserverWrapper() {
|
|
1805
2041
|
this.wrapperResizeObserver?.disconnect();
|
|
1806
2042
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -1841,22 +2077,40 @@ class StageMask extends Rule {
|
|
|
1841
2077
|
});
|
|
1842
2078
|
this.content.dispatchEvent(event);
|
|
1843
2079
|
}
|
|
2080
|
+
/**
|
|
2081
|
+
* 设置蒙层高度
|
|
2082
|
+
* @param height 高度
|
|
2083
|
+
*/
|
|
1844
2084
|
setHeight(height) {
|
|
1845
2085
|
this.height = height;
|
|
1846
2086
|
this.setMaxScrollTop();
|
|
1847
2087
|
this.content.style.height = `${height}px`;
|
|
1848
2088
|
}
|
|
2089
|
+
/**
|
|
2090
|
+
* 设置蒙层宽度
|
|
2091
|
+
* @param width 宽度
|
|
2092
|
+
*/
|
|
1849
2093
|
setWidth(width) {
|
|
1850
2094
|
this.width = width;
|
|
1851
2095
|
this.setMaxScrollLeft();
|
|
1852
2096
|
this.content.style.width = `${width}px`;
|
|
1853
2097
|
}
|
|
2098
|
+
/**
|
|
2099
|
+
* 计算并设置最大滚动宽度
|
|
2100
|
+
*/
|
|
1854
2101
|
setMaxScrollLeft() {
|
|
1855
2102
|
this.maxScrollLeft = Math.max(this.width - this.wrapperWidth, 0);
|
|
1856
2103
|
}
|
|
2104
|
+
/**
|
|
2105
|
+
* 计算并设置最大滚动高度
|
|
2106
|
+
*/
|
|
1857
2107
|
setMaxScrollTop() {
|
|
1858
2108
|
this.maxScrollTop = Math.max(this.height - this.wrapperHeight, 0);
|
|
1859
2109
|
}
|
|
2110
|
+
/**
|
|
2111
|
+
* 修复滚动距离
|
|
2112
|
+
* 由于滚动容器变化等因素,会导致当前滚动的距离不正确
|
|
2113
|
+
*/
|
|
1860
2114
|
fixScrollValue() {
|
|
1861
2115
|
if (this.scrollTop < 0)
|
|
1862
2116
|
this.scrollTop = 0;
|
|
@@ -1869,7 +2123,7 @@ class StageMask extends Rule {
|
|
|
1869
2123
|
}
|
|
1870
2124
|
mouseWheelHandler = (event) => {
|
|
1871
2125
|
if (!this.page)
|
|
1872
|
-
throw new Error("page
|
|
2126
|
+
throw new Error("page 未初始化");
|
|
1873
2127
|
const { deltaY, deltaX } = event;
|
|
1874
2128
|
if (this.page.clientHeight < this.wrapperHeight && deltaY)
|
|
1875
2129
|
return;
|
|
@@ -1889,6 +2143,7 @@ class StageMask extends Rule {
|
|
|
1889
2143
|
const style = ".tmagic-stage-container-highlight::after {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background-color: #000;\n opacity: .1;\n pointer-events: none;\n}\n\n.magic-ui-container.magic-layout-relative {\n min-height: 50px;\n}\n";
|
|
1890
2144
|
|
|
1891
2145
|
class StageRender extends EventEmitter$1 {
|
|
2146
|
+
/** 组件的js、css执行的环境,直接渲染为当前window,iframe渲染则为iframe.contentWindow */
|
|
1892
2147
|
contentWindow = null;
|
|
1893
2148
|
runtime = null;
|
|
1894
2149
|
iframe;
|
|
@@ -1942,9 +2197,13 @@ class StageRender extends EventEmitter$1 {
|
|
|
1942
2197
|
setZoom(zoom = DEFAULT_ZOOM) {
|
|
1943
2198
|
this.zoom = zoom;
|
|
1944
2199
|
}
|
|
2200
|
+
/**
|
|
2201
|
+
* 挂载Dom节点
|
|
2202
|
+
* @param el 将页面挂载到该Dom节点上
|
|
2203
|
+
*/
|
|
1945
2204
|
async mount(el) {
|
|
1946
2205
|
if (!this.iframe) {
|
|
1947
|
-
throw Error("mount
|
|
2206
|
+
throw Error("mount 失败");
|
|
1948
2207
|
}
|
|
1949
2208
|
if (!isSameDomain(this.runtimeUrl) && this.runtimeUrl) {
|
|
1950
2209
|
let html = await fetch(this.runtimeUrl).then((res) => res.text());
|
|
@@ -1970,6 +2229,11 @@ class StageRender extends EventEmitter$1 {
|
|
|
1970
2229
|
getDocument() {
|
|
1971
2230
|
return this.contentWindow?.document;
|
|
1972
2231
|
}
|
|
2232
|
+
/**
|
|
2233
|
+
* 通过坐标获得坐标下所有HTML元素数组
|
|
2234
|
+
* @param point 坐标
|
|
2235
|
+
* @returns 坐标下方所有HTML元素数组,会包含父元素直至html,元素层叠时返回顺序是从上到下
|
|
2236
|
+
*/
|
|
1973
2237
|
getElementsFromPoint(point) {
|
|
1974
2238
|
let x = point.clientX;
|
|
1975
2239
|
let y = point.clientY;
|
|
@@ -1986,11 +2250,14 @@ class StageRender extends EventEmitter$1 {
|
|
|
1986
2250
|
if (typeof idOrEl === "string" || typeof idOrEl === "number") {
|
|
1987
2251
|
const el = this.getDocument()?.getElementById(`${idOrEl}`);
|
|
1988
2252
|
if (!el)
|
|
1989
|
-
throw new Error(
|
|
2253
|
+
throw new Error(`不存在ID为${idOrEl}的元素`);
|
|
1990
2254
|
return el;
|
|
1991
2255
|
}
|
|
1992
2256
|
return idOrEl;
|
|
1993
2257
|
}
|
|
2258
|
+
/**
|
|
2259
|
+
* 销毁实例
|
|
2260
|
+
*/
|
|
1994
2261
|
destroy() {
|
|
1995
2262
|
this.iframe?.removeEventListener("load", this.loadHandler);
|
|
1996
2263
|
this.contentWindow = null;
|
|
@@ -1998,6 +2265,10 @@ class StageRender extends EventEmitter$1 {
|
|
|
1998
2265
|
this.iframe = void 0;
|
|
1999
2266
|
this.removeAllListeners();
|
|
2000
2267
|
}
|
|
2268
|
+
/**
|
|
2269
|
+
* 在runtime中对被选中的元素进行标记,部分组件有对选中态进行特殊显示的需求
|
|
2270
|
+
* @param el 被选中的元素
|
|
2271
|
+
*/
|
|
2001
2272
|
flagSelectedEl(el) {
|
|
2002
2273
|
const doc = this.getDocument();
|
|
2003
2274
|
if (doc) {
|
|
@@ -2060,6 +2331,10 @@ class StageCore extends EventEmitter$1 {
|
|
|
2060
2331
|
this.initActionEvent();
|
|
2061
2332
|
this.initMaskEvent();
|
|
2062
2333
|
}
|
|
2334
|
+
/**
|
|
2335
|
+
* 单选选中元素
|
|
2336
|
+
* @param idOrEl 选中的id或者元素
|
|
2337
|
+
*/
|
|
2063
2338
|
async select(idOrEl, event) {
|
|
2064
2339
|
const el = this.renderer.getTargetElement(idOrEl);
|
|
2065
2340
|
if (el === this.actionManager.getSelectedEl())
|
|
@@ -2071,6 +2346,10 @@ class StageCore extends EventEmitter$1 {
|
|
|
2071
2346
|
this.mask.observerIntersection(el);
|
|
2072
2347
|
}
|
|
2073
2348
|
}
|
|
2349
|
+
/**
|
|
2350
|
+
* 多选选中多个元素
|
|
2351
|
+
* @param idOrElList 选中元素的id或元素列表
|
|
2352
|
+
*/
|
|
2074
2353
|
async multiSelect(idOrElList) {
|
|
2075
2354
|
const els = idOrElList.map((idOrEl) => this.renderer.getTargetElement(idOrEl));
|
|
2076
2355
|
if (els.length === 0)
|
|
@@ -2084,9 +2363,17 @@ class StageCore extends EventEmitter$1 {
|
|
|
2084
2363
|
this.mask.observerIntersection(lastEl);
|
|
2085
2364
|
}
|
|
2086
2365
|
}
|
|
2366
|
+
/**
|
|
2367
|
+
* 高亮选中元素
|
|
2368
|
+
* @param el 要高亮的元素
|
|
2369
|
+
*/
|
|
2087
2370
|
highlight(idOrEl) {
|
|
2088
2371
|
this.actionManager.highlight(idOrEl);
|
|
2089
2372
|
}
|
|
2373
|
+
/**
|
|
2374
|
+
* 更新组件
|
|
2375
|
+
* @param data 更新组件的数据
|
|
2376
|
+
*/
|
|
2090
2377
|
async update(data) {
|
|
2091
2378
|
const { config } = data;
|
|
2092
2379
|
await this.renderer.update(data);
|
|
@@ -2099,15 +2386,27 @@ class StageCore extends EventEmitter$1 {
|
|
|
2099
2386
|
}
|
|
2100
2387
|
});
|
|
2101
2388
|
}
|
|
2389
|
+
/**
|
|
2390
|
+
* 往画布增加一个组件
|
|
2391
|
+
* @param data 组件信息数据
|
|
2392
|
+
*/
|
|
2102
2393
|
async add(data) {
|
|
2103
2394
|
return await this.renderer.add(data);
|
|
2104
2395
|
}
|
|
2396
|
+
/**
|
|
2397
|
+
* 从画布删除一个组件
|
|
2398
|
+
* @param data 组件信息数据
|
|
2399
|
+
*/
|
|
2105
2400
|
async remove(data) {
|
|
2106
2401
|
return await this.renderer.remove(data);
|
|
2107
2402
|
}
|
|
2108
2403
|
setZoom(zoom = DEFAULT_ZOOM) {
|
|
2109
2404
|
this.renderer.setZoom(zoom);
|
|
2110
2405
|
}
|
|
2406
|
+
/**
|
|
2407
|
+
* 挂载Dom节点
|
|
2408
|
+
* @param el 将stage挂载到该Dom节点上
|
|
2409
|
+
*/
|
|
2111
2410
|
async mount(el) {
|
|
2112
2411
|
this.container = el;
|
|
2113
2412
|
const { mask, renderer } = this;
|
|
@@ -2115,16 +2414,32 @@ class StageCore extends EventEmitter$1 {
|
|
|
2115
2414
|
mask.mount(el);
|
|
2116
2415
|
this.emit("mounted");
|
|
2117
2416
|
}
|
|
2417
|
+
/**
|
|
2418
|
+
* 清空所有参考线
|
|
2419
|
+
*/
|
|
2118
2420
|
clearGuides() {
|
|
2119
2421
|
this.mask.clearGuides();
|
|
2120
2422
|
this.actionManager.clearGuides();
|
|
2121
2423
|
}
|
|
2424
|
+
/**
|
|
2425
|
+
* @deprecated 废弃接口,建议用delayedMarkContainer代替
|
|
2426
|
+
*/
|
|
2122
2427
|
getAddContainerHighlightClassNameTimeout(event, excludeElList = []) {
|
|
2123
2428
|
return this.delayedMarkContainer(event, excludeElList);
|
|
2124
2429
|
}
|
|
2430
|
+
/**
|
|
2431
|
+
* 鼠标拖拽着元素,在容器上方悬停,延迟一段时间后,对容器进行标记,如果悬停时间够长将标记成功,悬停时间短,调用方通过返回的timeoutId取消标记
|
|
2432
|
+
* 标记的作用:1、高亮容器,给用户一个加入容器的交互感知;2、释放鼠标后,通过标记的标志找到要加入的容器
|
|
2433
|
+
* @param event 鼠标事件
|
|
2434
|
+
* @param excludeElList 计算鼠标所在容器时要排除的元素列表
|
|
2435
|
+
* @returns timeoutId,调用方在鼠标移走时要取消该timeout,阻止标记
|
|
2436
|
+
*/
|
|
2125
2437
|
delayedMarkContainer(event, excludeElList = []) {
|
|
2126
2438
|
return this.actionManager.delayedMarkContainer(event, excludeElList);
|
|
2127
2439
|
}
|
|
2440
|
+
/**
|
|
2441
|
+
* 销毁实例
|
|
2442
|
+
*/
|
|
2128
2443
|
destroy() {
|
|
2129
2444
|
const { mask, renderer, actionManager, pageResizeObserver } = this;
|
|
2130
2445
|
renderer.destroy();
|
|
@@ -2134,6 +2449,9 @@ class StageCore extends EventEmitter$1 {
|
|
|
2134
2449
|
this.removeAllListeners();
|
|
2135
2450
|
this.container = void 0;
|
|
2136
2451
|
}
|
|
2452
|
+
/**
|
|
2453
|
+
* 监听页面大小变化
|
|
2454
|
+
*/
|
|
2137
2455
|
observePageResize(page) {
|
|
2138
2456
|
if (typeof ResizeObserver !== "undefined") {
|
|
2139
2457
|
this.pageResizeObserver = new ResizeObserver((entries) => {
|
|
@@ -2177,12 +2495,18 @@ class StageCore extends EventEmitter$1 {
|
|
|
2177
2495
|
this.emit("change-guides", data);
|
|
2178
2496
|
});
|
|
2179
2497
|
}
|
|
2498
|
+
/**
|
|
2499
|
+
* 初始化操作相关事件监听
|
|
2500
|
+
*/
|
|
2180
2501
|
initActionEvent() {
|
|
2181
2502
|
this.initActionManagerEvent();
|
|
2182
2503
|
this.initDrEvent();
|
|
2183
2504
|
this.initMulDrEvent();
|
|
2184
2505
|
this.initHighlightEvent();
|
|
2185
2506
|
}
|
|
2507
|
+
/**
|
|
2508
|
+
* 初始化ActionManager类本身抛出来的事件监听
|
|
2509
|
+
*/
|
|
2186
2510
|
initActionManagerEvent() {
|
|
2187
2511
|
this.actionManager.on("before-select", (idOrEl, event) => {
|
|
2188
2512
|
this.select(idOrEl, event);
|
|
@@ -2194,6 +2518,9 @@ class StageCore extends EventEmitter$1 {
|
|
|
2194
2518
|
this.emit("multi-select", selectedElList);
|
|
2195
2519
|
});
|
|
2196
2520
|
}
|
|
2521
|
+
/**
|
|
2522
|
+
* 初始化DragResize类通过ActionManager抛出来的事件监听
|
|
2523
|
+
*/
|
|
2197
2524
|
initDrEvent() {
|
|
2198
2525
|
this.actionManager.on("update", (data) => {
|
|
2199
2526
|
this.emit("update", data);
|
|
@@ -2205,6 +2532,9 @@ class StageCore extends EventEmitter$1 {
|
|
|
2205
2532
|
this.emit("remove", data);
|
|
2206
2533
|
});
|
|
2207
2534
|
}
|
|
2535
|
+
/**
|
|
2536
|
+
* 初始化MultiDragResize类通过ActionManager抛出来的事件监听
|
|
2537
|
+
*/
|
|
2208
2538
|
initMulDrEvent() {
|
|
2209
2539
|
this.actionManager.on("change-to-select", (el) => {
|
|
2210
2540
|
this.select(el);
|
|
@@ -2213,6 +2543,9 @@ class StageCore extends EventEmitter$1 {
|
|
|
2213
2543
|
this.emit("update", data);
|
|
2214
2544
|
});
|
|
2215
2545
|
}
|
|
2546
|
+
/**
|
|
2547
|
+
* 初始化Highlight类通过ActionManager抛出来的事件监听
|
|
2548
|
+
*/
|
|
2216
2549
|
initHighlightEvent() {
|
|
2217
2550
|
this.actionManager.on("highlight", async (highlightEl) => {
|
|
2218
2551
|
this.emit("highlight", highlightEl);
|