@tmagic/stage 1.8.0-beta.2 → 1.8.0-beta.21
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/es/ActionManager.js +14 -6
- package/dist/es/StageCore.js +19 -4
- package/dist/es/StageFlashHighlight.js +102 -0
- package/dist/es/StageMask.js +2 -2
- package/dist/es/const.js +3 -1
- package/dist/es/index.js +3 -3
- package/dist/es/moveable-able.js +1 -1
- package/dist/es/util.js +28 -1
- package/dist/tmagic-stage.umd.cjs +203 -21
- package/package.json +2 -2
- package/src/ActionManager.ts +20 -8
- package/src/StageCore.ts +29 -5
- package/src/StageFlashHighlight.ts +135 -0
- package/src/StageMask.ts +5 -3
- package/src/const.ts +3 -0
- package/src/moveable-able.css +1 -1
- package/src/types.ts +22 -1
- package/src/util.ts +43 -1
- package/types/index.d.ts +74 -6
|
@@ -107,7 +107,8 @@
|
|
|
107
107
|
//#endregion
|
|
108
108
|
//#region node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseGetTag.js
|
|
109
109
|
/** `Object#toString` result references. */
|
|
110
|
-
var nullTag = "[object Null]"
|
|
110
|
+
var nullTag = "[object Null]";
|
|
111
|
+
var undefinedTag = "[object Undefined]";
|
|
111
112
|
/** Built-in value references. */
|
|
112
113
|
var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : void 0;
|
|
113
114
|
/**
|
|
@@ -333,7 +334,10 @@
|
|
|
333
334
|
//#endregion
|
|
334
335
|
//#region node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isFunction.js
|
|
335
336
|
/** `Object#toString` result references. */
|
|
336
|
-
var asyncTag = "[object AsyncFunction]"
|
|
337
|
+
var asyncTag = "[object AsyncFunction]";
|
|
338
|
+
var funcTag$1 = "[object Function]";
|
|
339
|
+
var genTag = "[object GeneratorFunction]";
|
|
340
|
+
var proxyTag = "[object Proxy]";
|
|
337
341
|
/**
|
|
338
342
|
* Checks if `value` is classified as a `Function` object.
|
|
339
343
|
*
|
|
@@ -409,7 +413,8 @@
|
|
|
409
413
|
/** Used to detect host constructors (Safari). */
|
|
410
414
|
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
411
415
|
/** Used for built-in method references. */
|
|
412
|
-
var funcProto$1 = Function.prototype
|
|
416
|
+
var funcProto$1 = Function.prototype;
|
|
417
|
+
var objectProto$3 = Object.prototype;
|
|
413
418
|
/** Used to resolve the decompiled source of functions. */
|
|
414
419
|
var funcToString$1 = funcProto$1.toString;
|
|
415
420
|
/** Used to check objects for own properties. */
|
|
@@ -518,7 +523,8 @@
|
|
|
518
523
|
//#endregion
|
|
519
524
|
//#region node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_shortOut.js
|
|
520
525
|
/** Used to detect hot functions by number of calls within a span of milliseconds. */
|
|
521
|
-
var HOT_COUNT = 800
|
|
526
|
+
var HOT_COUNT = 800;
|
|
527
|
+
var HOT_SPAN = 16;
|
|
522
528
|
var nativeNow = Date.now;
|
|
523
529
|
/**
|
|
524
530
|
* Creates a function that'll short out and invoke `identity` instead
|
|
@@ -978,8 +984,30 @@
|
|
|
978
984
|
//#endregion
|
|
979
985
|
//#region node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseIsTypedArray.js
|
|
980
986
|
/** `Object#toString` result references. */
|
|
981
|
-
var argsTag = "[object Arguments]"
|
|
982
|
-
var
|
|
987
|
+
var argsTag = "[object Arguments]";
|
|
988
|
+
var arrayTag = "[object Array]";
|
|
989
|
+
var boolTag = "[object Boolean]";
|
|
990
|
+
var dateTag = "[object Date]";
|
|
991
|
+
var errorTag = "[object Error]";
|
|
992
|
+
var funcTag = "[object Function]";
|
|
993
|
+
var mapTag = "[object Map]";
|
|
994
|
+
var numberTag = "[object Number]";
|
|
995
|
+
var objectTag$1 = "[object Object]";
|
|
996
|
+
var regexpTag = "[object RegExp]";
|
|
997
|
+
var setTag = "[object Set]";
|
|
998
|
+
var stringTag = "[object String]";
|
|
999
|
+
var weakMapTag = "[object WeakMap]";
|
|
1000
|
+
var arrayBufferTag = "[object ArrayBuffer]";
|
|
1001
|
+
var dataViewTag = "[object DataView]";
|
|
1002
|
+
var float32Tag = "[object Float32Array]";
|
|
1003
|
+
var float64Tag = "[object Float64Array]";
|
|
1004
|
+
var int8Tag = "[object Int8Array]";
|
|
1005
|
+
var int16Tag = "[object Int16Array]";
|
|
1006
|
+
var int32Tag = "[object Int32Array]";
|
|
1007
|
+
var uint8Tag = "[object Uint8Array]";
|
|
1008
|
+
var uint8ClampedTag = "[object Uint8ClampedArray]";
|
|
1009
|
+
var uint16Tag = "[object Uint16Array]";
|
|
1010
|
+
var uint32Tag = "[object Uint32Array]";
|
|
983
1011
|
/** Used to identify `toStringTag` values of typed arrays. */
|
|
984
1012
|
var typedArrayTags = {};
|
|
985
1013
|
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true;
|
|
@@ -1513,7 +1541,8 @@
|
|
|
1513
1541
|
/** `Object#toString` result references. */
|
|
1514
1542
|
var objectTag = "[object Object]";
|
|
1515
1543
|
/** Used for built-in method references. */
|
|
1516
|
-
var funcProto = Function.prototype
|
|
1544
|
+
var funcProto = Function.prototype;
|
|
1545
|
+
var objectProto = Object.prototype;
|
|
1517
1546
|
/** Used to resolve the decompiled source of functions. */
|
|
1518
1547
|
var funcToString = funcProto.toString;
|
|
1519
1548
|
/** Used to check objects for own properties. */
|
|
@@ -1666,7 +1695,8 @@
|
|
|
1666
1695
|
/** Detect free variable `module`. */
|
|
1667
1696
|
var freeModule = freeExports && typeof module == "object" && module && !module.nodeType && module;
|
|
1668
1697
|
/** Built-in value references. */
|
|
1669
|
-
var Buffer$1 = freeModule && freeModule.exports === freeExports ? root.Buffer : void 0
|
|
1698
|
+
var Buffer$1 = freeModule && freeModule.exports === freeExports ? root.Buffer : void 0;
|
|
1699
|
+
var allocUnsafe = Buffer$1 ? Buffer$1.allocUnsafe : void 0;
|
|
1670
1700
|
/**
|
|
1671
1701
|
* Creates a clone of `buffer`.
|
|
1672
1702
|
*
|
|
@@ -1783,7 +1813,8 @@
|
|
|
1783
1813
|
//#region node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/debounce.js
|
|
1784
1814
|
/** Error message constants. */
|
|
1785
1815
|
var FUNC_ERROR_TEXT$1 = "Expected a function";
|
|
1786
|
-
var nativeMax = Math.max
|
|
1816
|
+
var nativeMax = Math.max;
|
|
1817
|
+
var nativeMin = Math.min;
|
|
1787
1818
|
/**
|
|
1788
1819
|
* Creates a debounced function that delays invoking `func` until after `wait`
|
|
1789
1820
|
* milliseconds have elapsed since the last time the debounced function was
|
|
@@ -2175,6 +2206,8 @@
|
|
|
2175
2206
|
var DRAG_EL_ID_PREFIX = "drag_el_";
|
|
2176
2207
|
/** 高亮时需要在蒙层中创建一个占位节点,该节点的id前缀 */
|
|
2177
2208
|
var HIGHLIGHT_EL_ID_PREFIX = "highlight_el_";
|
|
2209
|
+
/** 闪烁提示时需要在蒙层中创建一个占位节点,该节点的id前缀 */
|
|
2210
|
+
var FLASH_EL_ID_PREFIX = "flash_el_";
|
|
2178
2211
|
var CONTAINER_HIGHLIGHT_CLASS_NAME = "tmagic-stage-container-highlight";
|
|
2179
2212
|
var PAGE_CLASS = "magic-ui-page";
|
|
2180
2213
|
/** 默认放到缩小倍数 */
|
|
@@ -2349,6 +2382,33 @@
|
|
|
2349
2382
|
}
|
|
2350
2383
|
return null;
|
|
2351
2384
|
};
|
|
2385
|
+
/**
|
|
2386
|
+
* 将元素滚动到指定滚动容器的可视区域内(仅垂直方向,滚动最小距离)
|
|
2387
|
+
* @description 与原生 scrollIntoView 不同,只滚动指定的容器自身,不会连带滚动外层祖先滚动容器,
|
|
2388
|
+
* 避免编辑器画布外层容器(如 stage 外层使用 transform 模拟滚动的容器)被浏览器自动滚动导致整个画布位移
|
|
2389
|
+
* @param el 目标元素
|
|
2390
|
+
* @param container 滚动容器
|
|
2391
|
+
*/
|
|
2392
|
+
var scrollElementIntoView = (el, container) => {
|
|
2393
|
+
const { ownerDocument } = container;
|
|
2394
|
+
const win = ownerDocument?.defaultView;
|
|
2395
|
+
if (!ownerDocument || !win) return;
|
|
2396
|
+
const elRect = el.getBoundingClientRect();
|
|
2397
|
+
let viewTop = 0;
|
|
2398
|
+
let viewHeight = 0;
|
|
2399
|
+
if (container === ownerDocument.documentElement || container === ownerDocument.body) {
|
|
2400
|
+
viewTop = 0;
|
|
2401
|
+
viewHeight = win.innerHeight;
|
|
2402
|
+
} else {
|
|
2403
|
+
viewTop = container.getBoundingClientRect().top + container.clientTop;
|
|
2404
|
+
viewHeight = container.clientHeight;
|
|
2405
|
+
}
|
|
2406
|
+
const viewBottom = viewTop + viewHeight;
|
|
2407
|
+
let delta = 0;
|
|
2408
|
+
if (elRect.top < viewTop) delta = elRect.top - viewTop;
|
|
2409
|
+
else if (elRect.bottom > viewBottom) delta = Math.min(elRect.bottom - viewBottom, elRect.top - viewTop);
|
|
2410
|
+
if (delta !== 0) container.scrollTop += delta;
|
|
2411
|
+
};
|
|
2352
2412
|
var removeSelectedClassName = (doc) => {
|
|
2353
2413
|
const oldEl = doc.querySelector(`.${SELECTED_CLASS}`);
|
|
2354
2414
|
if (oldEl) {
|
|
@@ -2786,7 +2846,7 @@
|
|
|
2786
2846
|
};
|
|
2787
2847
|
//#endregion
|
|
2788
2848
|
//#region packages/stage/src/moveable-able.css?raw
|
|
2789
|
-
var moveable_able_default = ".moveable-button {\n width: 20px;\n height: 20px;\n background:
|
|
2849
|
+
var moveable_able_default = ".moveable-button {\n width: 20px;\n height: 20px;\n background: var(--el-color-primary,#4af);\n border-radius: 4px;\n appearance: none;\n border: 0;\n color: white;\n font-size: 12px;\n font-weight: bold;\n margin-left: 2px;\n position: relative;\n cursor: pointer;\n}\n.moveable-remove-button:before, .moveable-remove-button:after {\n content: \"\";\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%) rotate(45deg);\n width: 14px;\n height: 2px;\n background: #fff;\n border-radius: 1px;\n cursor: pointer;\n}\n.moveable-remove-button:after {\n transform: translate(-50%, -50%) rotate(-45deg);\n}\n\n.moveable-select-parent-arrow-top-icon {\n transform: rotateZ(-45deg);\n width: 4px;\n height: 4px;\n border-color: #fff;\n border-width: 2px 2px 0 0;\n border-style: solid;\n position: absolute;\n left: 4px;\n top: 4px;\n}\n\n.moveable-select-parent-arrow-body-icon {\n width: 7px;\n height: 11px;\n border-color: #fff;\n border-width: 0 0 2px 2px;\n border-style: solid;\n}\n\n.moveable-drag-area-button {\n cursor: move;\n}\n\n.moveable-drag-area-button .moveable-select-parent-arrow-top-icon {\n width: 2px;\n height: 2px;\n}\n\n.moveable-drag-area-button .moveable-select-parent-arrow-top-icon-top {\n transform: rotateZ(-45deg) translateX(-50%);\n left: 50%;\n top: 3px;\n transform-origin: left;\n}\n\n.moveable-drag-area-button .moveable-select-parent-arrow-top-icon-bottom {\n transform: rotateZ(135deg) translateX(-50%);\n transform-origin: left;\n left: 50%;\n top: auto;\n bottom: 3px;\n}\n\n.moveable-drag-area-button .moveable-select-parent-arrow-top-icon-right {\n transform: rotateZ(45deg) translateY(-50%);\n transform-origin: top;\n right: 3px;\n left: auto;\n top: 50%;\n}\n\n.moveable-drag-area-button .moveable-select-parent-arrow-top-icon-left {\n transform: rotateZ(235deg) translateY(-50%);\n transform-origin: top;\n left: 3px;\n top: 50%;\n}\n\n.moveable-drag-area-button .moveable-select-parent-arrow-body-icon-horizontal {\n width: 2px;\n height: 11px;\n background-color: #fff;\n position: absolute;\n transform: translateX(-50%);\n left: 50%;\n top: 4px;\n}\n\n.moveable-drag-area-button .moveable-select-parent-arrow-body-icon-vertical {\n width: 11px;\n height: 2px;\n background-color: #fff;\n position: absolute;\n transform: translateY(-50%);\n left: 4px;\n top: 50%;;\n}\n\n.moveable-rerender-button img {\n position: absolute;\n left: 2px;\n top: 2px;\n}\n";
|
|
2790
2850
|
//#endregion
|
|
2791
2851
|
//#region packages/stage/src/MoveableActionsAble.ts
|
|
2792
2852
|
var MoveableActionsAble_default = (handler, customizedButton = []) => ({
|
|
@@ -3507,6 +3567,8 @@
|
|
|
3507
3567
|
containerHighlightDuration;
|
|
3508
3568
|
/** 将组件加入容器的操作方式 */
|
|
3509
3569
|
containerHighlightType;
|
|
3570
|
+
/** 是否仅在新增组件时才启用将组件加入容器 */
|
|
3571
|
+
containerHighlightAddOnly = false;
|
|
3510
3572
|
isAltKeydown = false;
|
|
3511
3573
|
getTargetElement;
|
|
3512
3574
|
getElementsFromPoint;
|
|
@@ -3540,6 +3602,7 @@
|
|
|
3540
3602
|
this.containerHighlightClassName = config.containerHighlightClassName || "tmagic-stage-container-highlight";
|
|
3541
3603
|
this.containerHighlightDuration = config.containerHighlightDuration || defaultContainerHighlightDuration;
|
|
3542
3604
|
this.containerHighlightType = config.containerHighlightType;
|
|
3605
|
+
this.containerHighlightAddOnly = config.containerHighlightAddOnly ?? false;
|
|
3543
3606
|
this.disabledMultiSelect = config.disabledMultiSelect ?? false;
|
|
3544
3607
|
this.alwaysMultiSelect = config.alwaysMultiSelect ?? false;
|
|
3545
3608
|
this.getTargetElement = config.getTargetElement;
|
|
@@ -3771,10 +3834,11 @@
|
|
|
3771
3834
|
* 标记的作用:1、高亮容器,给用户一个加入容器的交互感知;2、释放鼠标后,通过标记的标志找到要加入的容器
|
|
3772
3835
|
* @param event 鼠标事件
|
|
3773
3836
|
* @param excludeElList 计算鼠标所在容器时要排除的元素列表
|
|
3837
|
+
* @param isAdd 当前操作是否为新增组件(从组件列表拖入),开启 containerHighlightAddOnly 时只有新增才会标记
|
|
3774
3838
|
* @returns timeoutId,调用方在鼠标移走时要取消该timeout,阻止标记
|
|
3775
3839
|
*/
|
|
3776
|
-
delayedMarkContainer(event, excludeElList = []) {
|
|
3777
|
-
if (this.canAddToContainer()) return globalThis.setTimeout(() => {
|
|
3840
|
+
delayedMarkContainer(event, excludeElList = [], isAdd = false) {
|
|
3841
|
+
if (this.canAddToContainer(isAdd)) return globalThis.setTimeout(() => {
|
|
3778
3842
|
this.addContainerHighlightClassName(event, excludeElList);
|
|
3779
3843
|
}, this.containerHighlightDuration);
|
|
3780
3844
|
}
|
|
@@ -3893,9 +3957,12 @@
|
|
|
3893
3957
|
} else this.selectedElList.push(el);
|
|
3894
3958
|
}
|
|
3895
3959
|
/**
|
|
3896
|
-
* 当前状态下能否将组件加入容器,默认是鼠标悬停一段时间加入,alt模式则是按住alt
|
|
3960
|
+
* 当前状态下能否将组件加入容器,默认是鼠标悬停一段时间加入,alt模式则是按住alt+鼠标悬停一段时间加入;
|
|
3961
|
+
* 开启containerHighlightAddOnly时,画布中拖动已有组件不能加入容器
|
|
3962
|
+
* @param isAdd 当前操作是否为新增组件
|
|
3897
3963
|
*/
|
|
3898
|
-
canAddToContainer() {
|
|
3964
|
+
canAddToContainer(isAdd = false) {
|
|
3965
|
+
if (this.containerHighlightAddOnly && !isAdd) return false;
|
|
3899
3966
|
return this.containerHighlightType === ContainerHighlightType.DEFAULT || this.containerHighlightType === ContainerHighlightType.ALT && this.isAltKeydown;
|
|
3900
3967
|
}
|
|
3901
3968
|
/**
|
|
@@ -3904,8 +3971,9 @@
|
|
|
3904
3971
|
*/
|
|
3905
3972
|
markContainerEnd() {
|
|
3906
3973
|
const doc = this.getRenderDocument();
|
|
3907
|
-
if (doc
|
|
3908
|
-
|
|
3974
|
+
if (!doc) return null;
|
|
3975
|
+
const markedContainer = (0, _tmagic_core.removeClassNameByClassName)(doc, this.containerHighlightClassName);
|
|
3976
|
+
return this.canAddToContainer() ? markedContainer : null;
|
|
3909
3977
|
}
|
|
3910
3978
|
initMouseEvent() {
|
|
3911
3979
|
this.container.addEventListener("mousedown", this.mouseDownHandler);
|
|
@@ -3993,6 +4061,104 @@
|
|
|
3993
4061
|
};
|
|
3994
4062
|
};
|
|
3995
4063
|
//#endregion
|
|
4064
|
+
//#region packages/stage/src/StageFlashHighlight.ts
|
|
4065
|
+
/** 闪烁提示节点的 class name */
|
|
4066
|
+
var FLASH_TIP_CLASS_NAME = "tmagic-stage-flash-tip";
|
|
4067
|
+
/** 闪烁动画名称 */
|
|
4068
|
+
var FLASH_ANIMATION_NAME = "tmagic-stage-flash";
|
|
4069
|
+
/** 闪烁动画时长(ms) */
|
|
4070
|
+
var FLASH_DURATION = 1500;
|
|
4071
|
+
/**
|
|
4072
|
+
* 选中区域闪烁提示
|
|
4073
|
+
* @description 当组件不是通过点击画布选中(如从图层树、面包屑等外部选中)时,在画布上对选中区域做一次高亮闪烁,
|
|
4074
|
+
* 帮助用户快速定位组件在画布中的位置。
|
|
4075
|
+
*/
|
|
4076
|
+
var StageFlashHighlight = class {
|
|
4077
|
+
/** 复用 TargetShadow 负责节点的定位校准(updateDragEl、fixed、滚动偏移等) */
|
|
4078
|
+
targetShadow;
|
|
4079
|
+
timer;
|
|
4080
|
+
styleEl;
|
|
4081
|
+
constructor(config) {
|
|
4082
|
+
this.targetShadow = new TargetShadow({
|
|
4083
|
+
container: config.container,
|
|
4084
|
+
updateDragEl: config.updateDragEl,
|
|
4085
|
+
zIndex: ZIndex.SELECTED_EL,
|
|
4086
|
+
idPrefix: FLASH_EL_ID_PREFIX
|
|
4087
|
+
});
|
|
4088
|
+
}
|
|
4089
|
+
/**
|
|
4090
|
+
* 在目标元素所在区域做一次高亮闪烁
|
|
4091
|
+
* @param el 选中组件的Dom节点元素
|
|
4092
|
+
*/
|
|
4093
|
+
flash(el) {
|
|
4094
|
+
if (!el) return;
|
|
4095
|
+
this.injectStyle();
|
|
4096
|
+
this.clear();
|
|
4097
|
+
const flashEl = this.targetShadow.update(el);
|
|
4098
|
+
flashEl.classList.add(FLASH_TIP_CLASS_NAME);
|
|
4099
|
+
flashEl.style.boxSizing = "border-box";
|
|
4100
|
+
flashEl.style.pointerEvents = "none";
|
|
4101
|
+
flashEl.style.border = "";
|
|
4102
|
+
this.timer = globalThis.setTimeout(() => {
|
|
4103
|
+
this.clear();
|
|
4104
|
+
}, FLASH_DURATION);
|
|
4105
|
+
}
|
|
4106
|
+
/**
|
|
4107
|
+
* 清除闪烁节点
|
|
4108
|
+
*/
|
|
4109
|
+
clear() {
|
|
4110
|
+
if (this.timer) {
|
|
4111
|
+
globalThis.clearTimeout(this.timer);
|
|
4112
|
+
this.timer = void 0;
|
|
4113
|
+
}
|
|
4114
|
+
this.targetShadow.destroyEl();
|
|
4115
|
+
}
|
|
4116
|
+
/**
|
|
4117
|
+
* 销毁实例
|
|
4118
|
+
*/
|
|
4119
|
+
destroy() {
|
|
4120
|
+
this.clear();
|
|
4121
|
+
this.targetShadow.destroy();
|
|
4122
|
+
this.styleEl?.remove();
|
|
4123
|
+
this.styleEl = void 0;
|
|
4124
|
+
}
|
|
4125
|
+
/**
|
|
4126
|
+
* 注入闪烁动画样式(仅注入一次)
|
|
4127
|
+
*/
|
|
4128
|
+
injectStyle() {
|
|
4129
|
+
if (this.styleEl) return;
|
|
4130
|
+
this.styleEl = (0, _tmagic_core.injectStyle)((0, _tmagic_core.getDocument)(), `
|
|
4131
|
+
@keyframes ${FLASH_ANIMATION_NAME} {
|
|
4132
|
+
0% {
|
|
4133
|
+
opacity: 0;
|
|
4134
|
+
background-color: rgba(146, 84, 222, 0);
|
|
4135
|
+
}
|
|
4136
|
+
20% {
|
|
4137
|
+
opacity: 1;
|
|
4138
|
+
background-color: rgba(146, 84, 222, 0.7);
|
|
4139
|
+
}
|
|
4140
|
+
45% {
|
|
4141
|
+
opacity: 0.6;
|
|
4142
|
+
background-color: rgba(146, 84, 222, 0.4);
|
|
4143
|
+
}
|
|
4144
|
+
70% {
|
|
4145
|
+
opacity: 1;
|
|
4146
|
+
background-color: rgba(146, 84, 222, 0.7);
|
|
4147
|
+
}
|
|
4148
|
+
100% {
|
|
4149
|
+
opacity: 0;
|
|
4150
|
+
background-color: rgba(146, 84, 222, 0);
|
|
4151
|
+
}
|
|
4152
|
+
}
|
|
4153
|
+
.${FLASH_TIP_CLASS_NAME} {
|
|
4154
|
+
border: 2px solid #9254de;
|
|
4155
|
+
border-radius: 2px;
|
|
4156
|
+
animation: ${FLASH_ANIMATION_NAME} ${FLASH_DURATION}ms cubic-bezier(0.4, 0, 0.2, 1) both;
|
|
4157
|
+
}
|
|
4158
|
+
`);
|
|
4159
|
+
}
|
|
4160
|
+
};
|
|
4161
|
+
//#endregion
|
|
3996
4162
|
//#region packages/stage/src/Rule.ts
|
|
3997
4163
|
var guidesClass = "tmagic-stage-guides";
|
|
3998
4164
|
var Rule = class extends events.default {
|
|
@@ -4244,8 +4410,8 @@
|
|
|
4244
4410
|
this.scrollIntoView(scrollParent);
|
|
4245
4411
|
return;
|
|
4246
4412
|
}
|
|
4247
|
-
el.scrollIntoView();
|
|
4248
4413
|
if (!this.pageScrollParent) return;
|
|
4414
|
+
scrollElementIntoView(el, this.pageScrollParent);
|
|
4249
4415
|
this.scrollLeft = this.pageScrollParent.scrollLeft;
|
|
4250
4416
|
this.scrollTop = this.pageScrollParent.scrollTop;
|
|
4251
4417
|
this.scroll();
|
|
@@ -4586,13 +4752,17 @@
|
|
|
4586
4752
|
renderer = null;
|
|
4587
4753
|
mask = null;
|
|
4588
4754
|
actionManager = null;
|
|
4755
|
+
flashHighlight = null;
|
|
4589
4756
|
pageResizeObserver = null;
|
|
4590
4757
|
autoScrollIntoView;
|
|
4591
4758
|
customizedRender;
|
|
4759
|
+
/** 非点击画布选中组件时,是否对选中区域做高亮闪烁提示,默认开启 */
|
|
4760
|
+
disabledFlashTip;
|
|
4592
4761
|
constructor(config) {
|
|
4593
4762
|
super();
|
|
4594
4763
|
this.autoScrollIntoView = config.autoScrollIntoView;
|
|
4595
4764
|
this.customizedRender = config.render;
|
|
4765
|
+
this.disabledFlashTip = config.disabledFlashTip ?? false;
|
|
4596
4766
|
this.renderer = new StageRender({
|
|
4597
4767
|
runtimeUrl: config.runtimeUrl,
|
|
4598
4768
|
zoom: config.zoom,
|
|
@@ -4607,6 +4777,10 @@
|
|
|
4607
4777
|
disabledRule: config.disabledRule
|
|
4608
4778
|
});
|
|
4609
4779
|
this.actionManager = new ActionManager(this.getActionManagerConfig(config));
|
|
4780
|
+
this.flashHighlight = new StageFlashHighlight({
|
|
4781
|
+
container: this.mask.content,
|
|
4782
|
+
updateDragEl: config.updateDragEl
|
|
4783
|
+
});
|
|
4610
4784
|
this.initRenderEvent();
|
|
4611
4785
|
this.initActionEvent();
|
|
4612
4786
|
this.initMaskEvent();
|
|
@@ -4615,7 +4789,7 @@
|
|
|
4615
4789
|
* 单选选中元素
|
|
4616
4790
|
* @param id 选中的id
|
|
4617
4791
|
*/
|
|
4618
|
-
async select(id, event) {
|
|
4792
|
+
async select(id, event, options = {}) {
|
|
4619
4793
|
if (!this.renderer) return;
|
|
4620
4794
|
let el = this.renderer.getTargetElement(id) || null;
|
|
4621
4795
|
if (!el) el = await new Promise((resolve) => {
|
|
@@ -4646,6 +4820,8 @@
|
|
|
4646
4820
|
if (el) this.mask?.setLayout(el);
|
|
4647
4821
|
this.actionManager?.select(el, event);
|
|
4648
4822
|
if (el && (this.autoScrollIntoView || el.dataset.autoScrollIntoView)) this.mask?.observerIntersection(el);
|
|
4823
|
+
const isPage = el === this.mask?.page || el?.className.includes("magic-ui-page");
|
|
4824
|
+
if (el && !event && options.flash !== false && !this.disabledFlashTip && !isPage) this.flashHighlight?.flash(el);
|
|
4649
4825
|
}
|
|
4650
4826
|
/**
|
|
4651
4827
|
* 多选选中多个元素
|
|
@@ -4733,10 +4909,11 @@
|
|
|
4733
4909
|
* 标记的作用:1、高亮容器,给用户一个加入容器的交互感知;2、释放鼠标后,通过标记的标志找到要加入的容器
|
|
4734
4910
|
* @param event 鼠标事件
|
|
4735
4911
|
* @param excludeElList 计算鼠标所在容器时要排除的元素列表
|
|
4912
|
+
* @param isAdd 当前操作是否为新增组件(从组件列表拖入),开启 containerHighlightAddOnly 时只有新增才会标记
|
|
4736
4913
|
* @returns timeoutId,调用方在鼠标移走时要取消该timeout,阻止标记
|
|
4737
4914
|
*/
|
|
4738
|
-
delayedMarkContainer(event, excludeElList = []) {
|
|
4739
|
-
return this.actionManager?.delayedMarkContainer(event, excludeElList);
|
|
4915
|
+
delayedMarkContainer(event, excludeElList = [], isAdd = false) {
|
|
4916
|
+
return this.actionManager?.delayedMarkContainer(event, excludeElList, isAdd);
|
|
4740
4917
|
}
|
|
4741
4918
|
getMoveableOption(key) {
|
|
4742
4919
|
return this.actionManager?.getMoveableOption(key);
|
|
@@ -4771,16 +4948,18 @@
|
|
|
4771
4948
|
* 销毁实例
|
|
4772
4949
|
*/
|
|
4773
4950
|
destroy() {
|
|
4774
|
-
const { mask, renderer, actionManager, pageResizeObserver } = this;
|
|
4951
|
+
const { mask, renderer, actionManager, flashHighlight, pageResizeObserver } = this;
|
|
4775
4952
|
renderer?.destroy();
|
|
4776
4953
|
mask?.destroy();
|
|
4777
4954
|
actionManager?.destroy();
|
|
4955
|
+
flashHighlight?.destroy();
|
|
4778
4956
|
pageResizeObserver?.disconnect();
|
|
4779
4957
|
this.removeAllListeners();
|
|
4780
4958
|
this.container = void 0;
|
|
4781
4959
|
this.renderer = null;
|
|
4782
4960
|
this.mask = null;
|
|
4783
4961
|
this.actionManager = null;
|
|
4962
|
+
this.flashHighlight = null;
|
|
4784
4963
|
this.pageResizeObserver = null;
|
|
4785
4964
|
}
|
|
4786
4965
|
on(eventName, listener) {
|
|
@@ -4807,6 +4986,7 @@
|
|
|
4807
4986
|
containerHighlightClassName: config.containerHighlightClassName,
|
|
4808
4987
|
containerHighlightDuration: config.containerHighlightDuration,
|
|
4809
4988
|
containerHighlightType: config.containerHighlightType,
|
|
4989
|
+
containerHighlightAddOnly: config.containerHighlightAddOnly,
|
|
4810
4990
|
moveableOptions: config.moveableOptions,
|
|
4811
4991
|
container: this.mask.content,
|
|
4812
4992
|
disabledDragStart: config.disabledDragStart,
|
|
@@ -4925,6 +5105,7 @@
|
|
|
4925
5105
|
exports.ContainerHighlightType = ContainerHighlightType;
|
|
4926
5106
|
exports.DEFAULT_ZOOM = DEFAULT_ZOOM;
|
|
4927
5107
|
exports.DRAG_EL_ID_PREFIX = DRAG_EL_ID_PREFIX;
|
|
5108
|
+
exports.FLASH_EL_ID_PREFIX = FLASH_EL_ID_PREFIX;
|
|
4928
5109
|
exports.GHOST_EL_ID_PREFIX = GHOST_EL_ID_PREFIX;
|
|
4929
5110
|
exports.GuidesType = GuidesType;
|
|
4930
5111
|
exports.HIGHLIGHT_EL_ID_PREFIX = HIGHLIGHT_EL_ID_PREFIX;
|
|
@@ -4957,6 +5138,7 @@
|
|
|
4957
5138
|
exports.isRelative = isRelative;
|
|
4958
5139
|
exports.isStatic = isStatic;
|
|
4959
5140
|
exports.removeSelectedClassName = removeSelectedClassName;
|
|
5141
|
+
exports.scrollElementIntoView = scrollElementIntoView;
|
|
4960
5142
|
exports.up = up;
|
|
4961
5143
|
Object.keys(moveable).forEach(function(k) {
|
|
4962
5144
|
if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.8.0-beta.
|
|
2
|
+
"version": "1.8.0-beta.21",
|
|
3
3
|
"name": "@tmagic/stage",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"typescript": "^6.0.3",
|
|
47
|
-
"@tmagic/core": "1.8.0-beta.
|
|
47
|
+
"@tmagic/core": "1.8.0-beta.21"
|
|
48
48
|
},
|
|
49
49
|
"peerDependenciesMeta": {
|
|
50
50
|
"typescript": {
|
package/src/ActionManager.ts
CHANGED
|
@@ -84,6 +84,8 @@ export default class ActionManager extends EventEmitter {
|
|
|
84
84
|
private containerHighlightDuration: number;
|
|
85
85
|
/** 将组件加入容器的操作方式 */
|
|
86
86
|
private containerHighlightType?: ContainerHighlightType;
|
|
87
|
+
/** 是否仅在新增组件时才启用将组件加入容器 */
|
|
88
|
+
private containerHighlightAddOnly = false;
|
|
87
89
|
private isAltKeydown = false;
|
|
88
90
|
private getTargetElement: GetTargetElement;
|
|
89
91
|
private getElementsFromPoint: GetElementsFromPoint;
|
|
@@ -124,6 +126,7 @@ export default class ActionManager extends EventEmitter {
|
|
|
124
126
|
this.containerHighlightClassName = config.containerHighlightClassName || CONTAINER_HIGHLIGHT_CLASS_NAME;
|
|
125
127
|
this.containerHighlightDuration = config.containerHighlightDuration || defaultContainerHighlightDuration;
|
|
126
128
|
this.containerHighlightType = config.containerHighlightType;
|
|
129
|
+
this.containerHighlightAddOnly = config.containerHighlightAddOnly ?? false;
|
|
127
130
|
this.disabledMultiSelect = config.disabledMultiSelect ?? false;
|
|
128
131
|
this.alwaysMultiSelect = config.alwaysMultiSelect ?? false;
|
|
129
132
|
this.getTargetElement = config.getTargetElement;
|
|
@@ -428,10 +431,15 @@ export default class ActionManager extends EventEmitter {
|
|
|
428
431
|
* 标记的作用:1、高亮容器,给用户一个加入容器的交互感知;2、释放鼠标后,通过标记的标志找到要加入的容器
|
|
429
432
|
* @param event 鼠标事件
|
|
430
433
|
* @param excludeElList 计算鼠标所在容器时要排除的元素列表
|
|
434
|
+
* @param isAdd 当前操作是否为新增组件(从组件列表拖入),开启 containerHighlightAddOnly 时只有新增才会标记
|
|
431
435
|
* @returns timeoutId,调用方在鼠标移走时要取消该timeout,阻止标记
|
|
432
436
|
*/
|
|
433
|
-
public delayedMarkContainer(
|
|
434
|
-
|
|
437
|
+
public delayedMarkContainer(
|
|
438
|
+
event: MouseEvent,
|
|
439
|
+
excludeElList: Element[] = [],
|
|
440
|
+
isAdd = false,
|
|
441
|
+
): NodeJS.Timeout | undefined {
|
|
442
|
+
if (this.canAddToContainer(isAdd)) {
|
|
435
443
|
return globalThis.setTimeout(() => {
|
|
436
444
|
this.addContainerHighlightClassName(event, excludeElList);
|
|
437
445
|
}, this.containerHighlightDuration);
|
|
@@ -609,9 +617,13 @@ export default class ActionManager extends EventEmitter {
|
|
|
609
617
|
}
|
|
610
618
|
|
|
611
619
|
/**
|
|
612
|
-
* 当前状态下能否将组件加入容器,默认是鼠标悬停一段时间加入,alt模式则是按住alt
|
|
620
|
+
* 当前状态下能否将组件加入容器,默认是鼠标悬停一段时间加入,alt模式则是按住alt+鼠标悬停一段时间加入;
|
|
621
|
+
* 开启containerHighlightAddOnly时,画布中拖动已有组件不能加入容器
|
|
622
|
+
* @param isAdd 当前操作是否为新增组件
|
|
613
623
|
*/
|
|
614
|
-
private canAddToContainer(): boolean {
|
|
624
|
+
private canAddToContainer(isAdd = false): boolean {
|
|
625
|
+
if (this.containerHighlightAddOnly && !isAdd) return false;
|
|
626
|
+
|
|
615
627
|
return (
|
|
616
628
|
this.containerHighlightType === ContainerHighlightType.DEFAULT ||
|
|
617
629
|
(this.containerHighlightType === ContainerHighlightType.ALT && this.isAltKeydown)
|
|
@@ -624,10 +636,10 @@ export default class ActionManager extends EventEmitter {
|
|
|
624
636
|
*/
|
|
625
637
|
private markContainerEnd(): HTMLElement | null {
|
|
626
638
|
const doc = this.getRenderDocument();
|
|
627
|
-
if (doc
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
return null;
|
|
639
|
+
if (!doc) return null;
|
|
640
|
+
|
|
641
|
+
const markedContainer = removeClassNameByClassName(doc, this.containerHighlightClassName);
|
|
642
|
+
return this.canAddToContainer() ? markedContainer : null;
|
|
631
643
|
}
|
|
632
644
|
|
|
633
645
|
private initMouseEvent(): void {
|
package/src/StageCore.ts
CHANGED
|
@@ -25,7 +25,8 @@ import type { Id } from '@tmagic/core';
|
|
|
25
25
|
import { getIdFromEl } from '@tmagic/core';
|
|
26
26
|
|
|
27
27
|
import ActionManager from './ActionManager';
|
|
28
|
-
import { DEFAULT_ZOOM } from './const';
|
|
28
|
+
import { DEFAULT_ZOOM, PAGE_CLASS } from './const';
|
|
29
|
+
import StageFlashHighlight from './StageFlashHighlight';
|
|
29
30
|
import StageMask from './StageMask';
|
|
30
31
|
import StageRender from './StageRender';
|
|
31
32
|
import type {
|
|
@@ -51,16 +52,20 @@ export default class StageCore extends EventEmitter {
|
|
|
51
52
|
public renderer: StageRender | null = null;
|
|
52
53
|
public mask: StageMask | null = null;
|
|
53
54
|
public actionManager: ActionManager | null = null;
|
|
55
|
+
public flashHighlight: StageFlashHighlight | null = null;
|
|
54
56
|
|
|
55
57
|
private pageResizeObserver: ResizeObserver | null = null;
|
|
56
58
|
private autoScrollIntoView: boolean | undefined;
|
|
57
59
|
private customizedRender?: CustomizeRender;
|
|
60
|
+
/** 非点击画布选中组件时,是否对选中区域做高亮闪烁提示,默认开启 */
|
|
61
|
+
private disabledFlashTip: boolean;
|
|
58
62
|
|
|
59
63
|
constructor(config: StageCoreConfig) {
|
|
60
64
|
super();
|
|
61
65
|
|
|
62
66
|
this.autoScrollIntoView = config.autoScrollIntoView;
|
|
63
67
|
this.customizedRender = config.render;
|
|
68
|
+
this.disabledFlashTip = config.disabledFlashTip ?? false;
|
|
64
69
|
|
|
65
70
|
this.renderer = new StageRender({
|
|
66
71
|
runtimeUrl: config.runtimeUrl,
|
|
@@ -78,6 +83,10 @@ export default class StageCore extends EventEmitter {
|
|
|
78
83
|
disabledRule: config.disabledRule,
|
|
79
84
|
});
|
|
80
85
|
this.actionManager = new ActionManager(this.getActionManagerConfig(config));
|
|
86
|
+
this.flashHighlight = new StageFlashHighlight({
|
|
87
|
+
container: this.mask.content,
|
|
88
|
+
updateDragEl: config.updateDragEl,
|
|
89
|
+
});
|
|
81
90
|
|
|
82
91
|
this.initRenderEvent();
|
|
83
92
|
this.initActionEvent();
|
|
@@ -88,7 +97,7 @@ export default class StageCore extends EventEmitter {
|
|
|
88
97
|
* 单选选中元素
|
|
89
98
|
* @param id 选中的id
|
|
90
99
|
*/
|
|
91
|
-
public async select(id: Id, event?: MouseEvent): Promise<void> {
|
|
100
|
+
public async select(id: Id, event?: MouseEvent, options: { flash?: boolean } = {}): Promise<void> {
|
|
92
101
|
if (!this.renderer) {
|
|
93
102
|
return;
|
|
94
103
|
}
|
|
@@ -133,6 +142,13 @@ export default class StageCore extends EventEmitter {
|
|
|
133
142
|
if (el && (this.autoScrollIntoView || el.dataset.autoScrollIntoView)) {
|
|
134
143
|
this.mask?.observerIntersection(el);
|
|
135
144
|
}
|
|
145
|
+
|
|
146
|
+
// 非点击画布选中(如从图层树、面包屑等外部选中,此时没有鼠标事件)时,对选中区域做一次高亮闪烁,帮助用户定位组件
|
|
147
|
+
// 选中页面(mask.page 或带有 magic-ui-page class 的节点)时不做闪烁提示
|
|
148
|
+
const isPage = el === this.mask?.page || el?.className.includes(PAGE_CLASS);
|
|
149
|
+
if (el && !event && options.flash !== false && !this.disabledFlashTip && !isPage) {
|
|
150
|
+
this.flashHighlight?.flash(el);
|
|
151
|
+
}
|
|
136
152
|
}
|
|
137
153
|
|
|
138
154
|
/**
|
|
@@ -247,10 +263,15 @@ export default class StageCore extends EventEmitter {
|
|
|
247
263
|
* 标记的作用:1、高亮容器,给用户一个加入容器的交互感知;2、释放鼠标后,通过标记的标志找到要加入的容器
|
|
248
264
|
* @param event 鼠标事件
|
|
249
265
|
* @param excludeElList 计算鼠标所在容器时要排除的元素列表
|
|
266
|
+
* @param isAdd 当前操作是否为新增组件(从组件列表拖入),开启 containerHighlightAddOnly 时只有新增才会标记
|
|
250
267
|
* @returns timeoutId,调用方在鼠标移走时要取消该timeout,阻止标记
|
|
251
268
|
*/
|
|
252
|
-
public delayedMarkContainer(
|
|
253
|
-
|
|
269
|
+
public delayedMarkContainer(
|
|
270
|
+
event: MouseEvent,
|
|
271
|
+
excludeElList: Element[] = [],
|
|
272
|
+
isAdd = false,
|
|
273
|
+
): NodeJS.Timeout | undefined {
|
|
274
|
+
return this.actionManager?.delayedMarkContainer(event, excludeElList, isAdd);
|
|
254
275
|
}
|
|
255
276
|
|
|
256
277
|
public getMoveableOption<K extends keyof MoveableOptions>(key: K): MoveableOptions[K] | undefined {
|
|
@@ -300,11 +321,12 @@ export default class StageCore extends EventEmitter {
|
|
|
300
321
|
* 销毁实例
|
|
301
322
|
*/
|
|
302
323
|
public destroy(): void {
|
|
303
|
-
const { mask, renderer, actionManager, pageResizeObserver } = this;
|
|
324
|
+
const { mask, renderer, actionManager, flashHighlight, pageResizeObserver } = this;
|
|
304
325
|
|
|
305
326
|
renderer?.destroy();
|
|
306
327
|
mask?.destroy();
|
|
307
328
|
actionManager?.destroy();
|
|
329
|
+
flashHighlight?.destroy();
|
|
308
330
|
pageResizeObserver?.disconnect();
|
|
309
331
|
|
|
310
332
|
this.removeAllListeners();
|
|
@@ -313,6 +335,7 @@ export default class StageCore extends EventEmitter {
|
|
|
313
335
|
this.renderer = null;
|
|
314
336
|
this.mask = null;
|
|
315
337
|
this.actionManager = null;
|
|
338
|
+
this.flashHighlight = null;
|
|
316
339
|
this.pageResizeObserver = null;
|
|
317
340
|
}
|
|
318
341
|
|
|
@@ -350,6 +373,7 @@ export default class StageCore extends EventEmitter {
|
|
|
350
373
|
containerHighlightClassName: config.containerHighlightClassName,
|
|
351
374
|
containerHighlightDuration: config.containerHighlightDuration,
|
|
352
375
|
containerHighlightType: config.containerHighlightType,
|
|
376
|
+
containerHighlightAddOnly: config.containerHighlightAddOnly,
|
|
353
377
|
moveableOptions: config.moveableOptions,
|
|
354
378
|
container: this.mask!.content,
|
|
355
379
|
disabledDragStart: config.disabledDragStart,
|