@tmagic/stage 1.2.0-beta.2 → 1.2.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/README.md +62 -1
- package/dist/tmagic-stage.js +2157 -0
- package/dist/tmagic-stage.js.map +1 -0
- package/dist/{tmagic-stage.umd.js → tmagic-stage.umd.cjs} +1436 -993
- package/dist/tmagic-stage.umd.cjs.map +1 -0
- package/package.json +9 -8
- package/src/ActionManager.ts +534 -0
- package/src/DragResizeHelper.ts +338 -0
- package/src/MoveableOptionsManager.ts +249 -0
- package/src/MoveableSelectParentAble.ts +76 -0
- package/src/Rule.ts +13 -9
- package/src/StageCore.ts +220 -260
- package/src/StageDragResize.ts +83 -339
- package/src/StageHighlight.ts +17 -16
- package/src/StageMask.ts +88 -140
- package/src/StageMultiDragResize.ts +97 -198
- package/src/StageRender.ts +90 -15
- package/src/TargetShadow.ts +120 -0
- package/src/const.ts +1 -1
- package/src/types.ts +97 -19
- package/src/util.ts +24 -11
- package/types/ActionManager.d.ts +141 -0
- package/types/DragResizeHelper.d.ts +70 -0
- package/types/MoveableOptionsManager.d.ts +86 -0
- package/types/MoveableSelectParentAble.d.ts +8 -0
- package/types/Rule.d.ts +4 -3
- package/types/StageCore.d.ts +65 -39
- package/types/StageDragResize.d.ts +11 -40
- package/types/StageHighlight.d.ts +3 -4
- package/types/StageMask.d.ts +23 -22
- package/types/StageMultiDragResize.d.ts +8 -24
- package/types/StageRender.d.ts +24 -6
- package/types/TargetShadow.d.ts +22 -0
- package/types/const.d.ts +1 -1
- package/types/types.d.ts +85 -18
- package/types/util.d.ts +9 -8
- package/dist/tmagic-stage.mjs +0 -1715
- package/dist/tmagic-stage.mjs.map +0 -1
- package/dist/tmagic-stage.umd.js.map +0 -1
- package/src/TargetCalibrate.ts +0 -119
- package/types/TargetCalibrate.d.ts +0 -20
package/src/types.ts
CHANGED
|
@@ -16,25 +16,44 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { MoveableOptions } from 'moveable';
|
|
19
|
+
import type { MoveableOptions } from 'moveable';
|
|
20
20
|
|
|
21
21
|
import Core from '@tmagic/core';
|
|
22
22
|
import type { Id, MApp, MContainer, MNode } from '@tmagic/schema';
|
|
23
23
|
|
|
24
|
-
import { GuidesType } from './const';
|
|
24
|
+
import { GuidesType, ZIndex } from './const';
|
|
25
25
|
import StageCore from './StageCore';
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
|
|
27
|
+
export type TargetElement = HTMLElement | SVGElement;
|
|
28
28
|
|
|
29
29
|
export type CanSelect = (el: HTMLElement, event: MouseEvent, stop: () => boolean) => boolean | Promise<boolean>;
|
|
30
30
|
export type IsContainer = (el: HTMLElement) => boolean | Promise<boolean>;
|
|
31
|
-
|
|
31
|
+
export type CustomizeRender = (renderer: StageCore) => Promise<HTMLElement> | HTMLElement;
|
|
32
|
+
/** 业务方自定义的moveableOptions,可以是配置,也可以是回调函数 */
|
|
33
|
+
export type CustomizeMoveableOptions =
|
|
34
|
+
| ((config?: CustomizeMoveableOptionsCallbackConfig) => MoveableOptions)
|
|
35
|
+
| MoveableOptions
|
|
36
|
+
| undefined;
|
|
37
|
+
/** render提供给的接口,如果是id则转成el,如果是el则直接返回 */
|
|
38
|
+
export type GetTargetElement = (idOrEl: Id | HTMLElement) => HTMLElement;
|
|
39
|
+
/** render提供的接口,通过坐标获得坐标下所有HTML元素数组 */
|
|
40
|
+
export type GetElementsFromPoint = (point: Point) => HTMLElement[];
|
|
41
|
+
export type GetRenderDocument = () => Document | undefined;
|
|
42
|
+
export type DelayedMarkContainer = (event: MouseEvent, exclude: Element[]) => NodeJS.Timeout | undefined;
|
|
43
|
+
export type MarkContainerEnd = () => HTMLElement | null;
|
|
44
|
+
export type GetRootContainer = () => HTMLDivElement | undefined;
|
|
45
|
+
|
|
46
|
+
/** 将组件添加到容器的方式 */
|
|
32
47
|
export enum ContainerHighlightType {
|
|
48
|
+
/** 默认方式:组件在容器上方悬停一段时间后加入 */
|
|
33
49
|
DEFAULT = 'default',
|
|
50
|
+
/** 按住alt键,并在容器上方悬停一段时间后加入 */
|
|
34
51
|
ALT = 'alt',
|
|
35
52
|
}
|
|
36
53
|
|
|
37
|
-
export type
|
|
54
|
+
export type UpdateDragEl = (el: TargetElement, target: TargetElement) => void;
|
|
55
|
+
|
|
56
|
+
export interface StageCoreConfig {
|
|
38
57
|
/** 需要对齐的dom节点的CSS选择器字符串 */
|
|
39
58
|
snapElementQuerySelector?: string;
|
|
40
59
|
/** 放大倍数,默认1倍 */
|
|
@@ -44,17 +63,45 @@ export type StageCoreConfig = {
|
|
|
44
63
|
containerHighlightClassName?: string;
|
|
45
64
|
containerHighlightDuration?: number;
|
|
46
65
|
containerHighlightType?: ContainerHighlightType;
|
|
47
|
-
moveableOptions?:
|
|
48
|
-
multiMoveableOptions?:
|
|
66
|
+
moveableOptions?: CustomizeMoveableOptions;
|
|
67
|
+
multiMoveableOptions?: CustomizeMoveableOptions;
|
|
49
68
|
/** runtime 的HTML地址,可以是一个HTTP地址,如果和编辑器不同域,需要设置跨域,也可以是一个相对或绝对路径 */
|
|
50
69
|
runtimeUrl?: string;
|
|
51
70
|
render?: (renderer: StageCore) => Promise<HTMLElement> | HTMLElement;
|
|
52
71
|
autoScrollIntoView?: boolean;
|
|
53
|
-
updateDragEl?:
|
|
54
|
-
}
|
|
72
|
+
updateDragEl?: UpdateDragEl;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface ActionManagerConfig {
|
|
76
|
+
container: HTMLElement;
|
|
77
|
+
containerHighlightClassName?: string;
|
|
78
|
+
containerHighlightDuration?: number;
|
|
79
|
+
containerHighlightType?: ContainerHighlightType;
|
|
80
|
+
moveableOptions?: CustomizeMoveableOptions;
|
|
81
|
+
multiMoveableOptions?: CustomizeMoveableOptions;
|
|
82
|
+
canSelect?: CanSelect;
|
|
83
|
+
isContainer: IsContainer;
|
|
84
|
+
getRootContainer: GetRootContainer;
|
|
85
|
+
getRenderDocument: GetRenderDocument;
|
|
86
|
+
updateDragEl?: UpdateDragEl;
|
|
87
|
+
getTargetElement: GetTargetElement;
|
|
88
|
+
getElementsFromPoint: GetElementsFromPoint;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface MoveableOptionsManagerConfig {
|
|
92
|
+
container: HTMLElement;
|
|
93
|
+
moveableOptions?: CustomizeMoveableOptions;
|
|
94
|
+
getRootContainer: GetRootContainer;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface CustomizeMoveableOptionsCallbackConfig {
|
|
98
|
+
targetElId?: string;
|
|
99
|
+
}
|
|
55
100
|
|
|
56
101
|
export interface StageRenderConfig {
|
|
57
|
-
|
|
102
|
+
runtimeUrl?: string;
|
|
103
|
+
zoom: number | undefined;
|
|
104
|
+
customizedRender?: () => Promise<HTMLElement | null>;
|
|
58
105
|
}
|
|
59
106
|
|
|
60
107
|
export interface StageMaskConfig {
|
|
@@ -62,9 +109,34 @@ export interface StageMaskConfig {
|
|
|
62
109
|
}
|
|
63
110
|
|
|
64
111
|
export interface StageDragResizeConfig {
|
|
65
|
-
core: StageCore;
|
|
66
112
|
container: HTMLElement;
|
|
67
|
-
|
|
113
|
+
moveableOptions?: CustomizeMoveableOptions;
|
|
114
|
+
getRootContainer: GetRootContainer;
|
|
115
|
+
getRenderDocument: GetRenderDocument;
|
|
116
|
+
markContainerEnd: MarkContainerEnd;
|
|
117
|
+
delayedMarkContainer: DelayedMarkContainer;
|
|
118
|
+
updateDragEl?: UpdateDragEl;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface StageMultiDragResizeConfig {
|
|
122
|
+
container: HTMLElement;
|
|
123
|
+
multiMoveableOptions?: CustomizeMoveableOptions;
|
|
124
|
+
getRootContainer: GetRootContainer;
|
|
125
|
+
getRenderDocument: GetRenderDocument;
|
|
126
|
+
updateDragEl?: UpdateDragEl;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface DragResizeHelperConfig {
|
|
130
|
+
container: HTMLElement;
|
|
131
|
+
updateDragEl?: UpdateDragEl;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** 选择状态 */
|
|
135
|
+
export enum SelectStatus {
|
|
136
|
+
/** 单选 */
|
|
137
|
+
SELECT = 'select',
|
|
138
|
+
/** 多选 */
|
|
139
|
+
MULTI_SELECT = 'multiSelect',
|
|
68
140
|
}
|
|
69
141
|
|
|
70
142
|
/** 拖动状态 */
|
|
@@ -87,6 +159,11 @@ export interface Offset {
|
|
|
87
159
|
top: number;
|
|
88
160
|
}
|
|
89
161
|
|
|
162
|
+
export interface Point {
|
|
163
|
+
clientX: number;
|
|
164
|
+
clientY: number;
|
|
165
|
+
}
|
|
166
|
+
|
|
90
167
|
export interface GuidesEventData {
|
|
91
168
|
type: GuidesType;
|
|
92
169
|
guides: number[];
|
|
@@ -153,13 +230,14 @@ export interface RuntimeWindow extends Window {
|
|
|
153
230
|
}
|
|
154
231
|
|
|
155
232
|
export interface StageHighlightConfig {
|
|
156
|
-
core: StageCore;
|
|
157
233
|
container: HTMLElement;
|
|
234
|
+
updateDragEl?: UpdateDragEl;
|
|
235
|
+
getRootContainer: GetRootContainer;
|
|
158
236
|
}
|
|
159
237
|
|
|
160
|
-
export interface
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
238
|
+
export interface TargetShadowConfig {
|
|
239
|
+
container: HTMLElement;
|
|
240
|
+
zIndex?: ZIndex;
|
|
241
|
+
updateDragEl?: UpdateDragEl;
|
|
242
|
+
idPrefix?: string;
|
|
165
243
|
}
|
package/src/util.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { removeClassName } from '@tmagic/utils';
|
|
19
19
|
|
|
20
20
|
import { GHOST_EL_ID_PREFIX, Mode, SELECTED_CLASS, ZIndex } from './const';
|
|
21
|
-
import type { Offset, SortEventData } from './types';
|
|
21
|
+
import type { Offset, SortEventData, TargetElement } from './types';
|
|
22
22
|
|
|
23
23
|
const getParents = (el: Element, relative: Element) => {
|
|
24
24
|
let cur: Element | null = el.parentElement;
|
|
@@ -30,12 +30,16 @@ const getParents = (el: Element, relative: Element) => {
|
|
|
30
30
|
return parents;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
export const getOffset = (el:
|
|
34
|
-
const
|
|
33
|
+
export const getOffset = (el: TargetElement): Offset => {
|
|
34
|
+
const htmlEl = el as HTMLElement;
|
|
35
|
+
const { offsetParent } = htmlEl;
|
|
35
36
|
|
|
36
|
-
const left =
|
|
37
|
-
const top =
|
|
37
|
+
const left = htmlEl.offsetLeft || 0;
|
|
38
|
+
const top = htmlEl.offsetTop || 0;
|
|
38
39
|
|
|
40
|
+
// 在 Webkit 中,如果元素为隐藏的(该元素或其祖先元素的 style.display 为 "none"),或者该元素的 style.position 被设为 "fixed",则该属性返回 null。
|
|
41
|
+
// 在 IE 9 中,如果该元素的 style.position 被设置为 "fixed",则该属性返回 null。(display:none 无影响。)
|
|
42
|
+
// body offsetParent 为 null
|
|
39
43
|
if (offsetParent) {
|
|
40
44
|
const parentOffset = getOffset(offsetParent as HTMLElement);
|
|
41
45
|
return {
|
|
@@ -51,7 +55,7 @@ export const getOffset = (el: HTMLElement): Offset => {
|
|
|
51
55
|
};
|
|
52
56
|
|
|
53
57
|
// 将蒙层占位节点覆盖在原节点上方
|
|
54
|
-
export const getTargetElStyle = (el:
|
|
58
|
+
export const getTargetElStyle = (el: TargetElement, zIndex?: ZIndex) => {
|
|
55
59
|
const offset = getOffset(el);
|
|
56
60
|
const { transform } = getComputedStyle(el);
|
|
57
61
|
return `
|
|
@@ -61,13 +65,16 @@ export const getTargetElStyle = (el: HTMLElement) => {
|
|
|
61
65
|
top: ${offset.top}px;
|
|
62
66
|
width: ${el.clientWidth}px;
|
|
63
67
|
height: ${el.clientHeight}px;
|
|
64
|
-
z-index: ${
|
|
68
|
+
${typeof zIndex !== 'undefined' ? `z-index: ${zIndex};` : ''}
|
|
65
69
|
`;
|
|
66
70
|
};
|
|
67
71
|
|
|
68
72
|
export const getAbsolutePosition = (el: HTMLElement, { top, left }: Offset) => {
|
|
69
73
|
const { offsetParent } = el;
|
|
70
74
|
|
|
75
|
+
// 在 Webkit 中,如果元素为隐藏的(该元素或其祖先元素的 style.display 为 "none"),或者该元素的 style.position 被设为 "fixed",则该属性返回 null。
|
|
76
|
+
// 在 IE 9 中,如果该元素的 style.position 被设置为 "fixed",则该属性返回 null。(display:none 无影响。)
|
|
77
|
+
// body offsetParent 为 null
|
|
71
78
|
if (offsetParent) {
|
|
72
79
|
const parentOffset = getOffset(offsetParent as HTMLElement);
|
|
73
80
|
return {
|
|
@@ -87,7 +94,7 @@ export const isStatic = (style: CSSStyleDeclaration): boolean => style.position
|
|
|
87
94
|
|
|
88
95
|
export const isFixed = (style: CSSStyleDeclaration): boolean => style.position === 'fixed';
|
|
89
96
|
|
|
90
|
-
export const isFixedParent = (el:
|
|
97
|
+
export const isFixedParent = (el: Element) => {
|
|
91
98
|
let fixed = false;
|
|
92
99
|
let dom = el;
|
|
93
100
|
while (dom) {
|
|
@@ -104,7 +111,7 @@ export const isFixedParent = (el: HTMLElement) => {
|
|
|
104
111
|
return fixed;
|
|
105
112
|
};
|
|
106
113
|
|
|
107
|
-
export const getMode = (el:
|
|
114
|
+
export const getMode = (el: Element): Mode => {
|
|
108
115
|
if (isFixedParent(el)) return Mode.FIXED;
|
|
109
116
|
const style = getComputedStyle(el);
|
|
110
117
|
if (isStatic(style) || isRelative(style)) return Mode.SORTABLE;
|
|
@@ -119,6 +126,9 @@ export const getScrollParent = (element: HTMLElement, includeHidden = false): HT
|
|
|
119
126
|
|
|
120
127
|
for (let parent = element; parent.parentElement; ) {
|
|
121
128
|
parent = parent.parentElement;
|
|
129
|
+
|
|
130
|
+
if (parent.tagName === 'HTML') return parent;
|
|
131
|
+
|
|
122
132
|
style = getComputedStyle(parent);
|
|
123
133
|
|
|
124
134
|
if (isAbsolute(style) && isStatic(style)) continue;
|
|
@@ -165,7 +175,7 @@ export const calcValueByFontsize = (doc: Document, value: number) => {
|
|
|
165
175
|
* @param {number} deltaTop 偏移量
|
|
166
176
|
* @param {Object} detail 当前选中的组件配置
|
|
167
177
|
*/
|
|
168
|
-
export const down = (deltaTop: number, target:
|
|
178
|
+
export const down = (deltaTop: number, target: TargetElement): SortEventData | void => {
|
|
169
179
|
let swapIndex = 0;
|
|
170
180
|
let addUpH = target.clientHeight;
|
|
171
181
|
const brothers = Array.from(target.parentNode?.children || []).filter(
|
|
@@ -201,7 +211,7 @@ export const down = (deltaTop: number, target: HTMLElement | SVGElement): SortEv
|
|
|
201
211
|
* @param {number} deltaTop 偏移量
|
|
202
212
|
* @param {Object} detail 当前选中的组件配置
|
|
203
213
|
*/
|
|
204
|
-
export const up = (deltaTop: number, target:
|
|
214
|
+
export const up = (deltaTop: number, target: TargetElement): SortEventData | void => {
|
|
205
215
|
const brothers = Array.from(target.parentNode?.children || []).filter(
|
|
206
216
|
(node) => !node.id.startsWith(GHOST_EL_ID_PREFIX),
|
|
207
217
|
);
|
|
@@ -229,3 +239,6 @@ export const up = (deltaTop: number, target: HTMLElement | SVGElement): SortEven
|
|
|
229
239
|
dist: upEls.length && swapIndex > -1 ? upEls[swapIndex].id : target.id,
|
|
230
240
|
};
|
|
231
241
|
};
|
|
242
|
+
|
|
243
|
+
export const isMoveableButton = (target: Element) =>
|
|
244
|
+
target.classList.contains('moveable-button') || target.parentElement?.classList.contains('moveable-button');
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import EventEmitter from 'events';
|
|
4
|
+
import { Id } from '@tmagic/schema';
|
|
5
|
+
import { GuidesType } from './const';
|
|
6
|
+
import { ActionManagerConfig, SelectStatus } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* 管理蒙层mask之上的操作:1、监听键盘鼠标事件,判断形成单选、多选、高亮操作;2、管理单选、多选、高亮三个类协同工作。
|
|
9
|
+
* @extends EventEmitter
|
|
10
|
+
*/
|
|
11
|
+
export default class ActionManager extends EventEmitter {
|
|
12
|
+
private dr;
|
|
13
|
+
private multiDr;
|
|
14
|
+
private highlightLayer;
|
|
15
|
+
/** 单选、多选、高亮的容器(蒙层的content) */
|
|
16
|
+
private container;
|
|
17
|
+
/** 当前选中的节点 */
|
|
18
|
+
private selectedEl;
|
|
19
|
+
/** 多选选中的节点组 */
|
|
20
|
+
private selectedElList;
|
|
21
|
+
/** 当前高亮的节点 */
|
|
22
|
+
private highlightedEl;
|
|
23
|
+
/** 当前是否处于多选状态 */
|
|
24
|
+
private isMultiSelectStatus;
|
|
25
|
+
/** 当拖拽组件到容器上方进入可加入容器状态时,给容器添加的一个class名称 */
|
|
26
|
+
private containerHighlightClassName;
|
|
27
|
+
/** 当拖拽组件到容器上方时,需要悬停多久才能将组件加入容器 */
|
|
28
|
+
private containerHighlightDuration;
|
|
29
|
+
/** 将组件加入容器的操作方式 */
|
|
30
|
+
private containerHighlightType?;
|
|
31
|
+
private isAltKeydown;
|
|
32
|
+
private getTargetElement;
|
|
33
|
+
private getElementsFromPoint;
|
|
34
|
+
private canSelect;
|
|
35
|
+
private isContainer;
|
|
36
|
+
private getRenderDocument;
|
|
37
|
+
private mouseMoveHandler;
|
|
38
|
+
constructor(config: ActionManagerConfig);
|
|
39
|
+
/**
|
|
40
|
+
* 设置水平/垂直参考线
|
|
41
|
+
* @param type 参考线类型
|
|
42
|
+
* @param guidelines 参考线坐标数组
|
|
43
|
+
*/
|
|
44
|
+
setGuidelines(type: GuidesType, guidelines: number[]): void;
|
|
45
|
+
/**
|
|
46
|
+
* 清空所有参考线
|
|
47
|
+
*/
|
|
48
|
+
clearGuides(): void;
|
|
49
|
+
/**
|
|
50
|
+
* 更新moveable,外部主要调用场景是元素配置变更、页面大小变更
|
|
51
|
+
* @param el 变更的元素
|
|
52
|
+
*/
|
|
53
|
+
updateMoveable(el?: HTMLElement): void;
|
|
54
|
+
/**
|
|
55
|
+
* 判断是否单选选中的元素
|
|
56
|
+
*/
|
|
57
|
+
isSelectedEl(el: HTMLElement): boolean;
|
|
58
|
+
setSelectedEl(el: HTMLElement): void;
|
|
59
|
+
getSelectedEl(): HTMLElement | undefined;
|
|
60
|
+
getSelectedElList(): HTMLElement[];
|
|
61
|
+
/**
|
|
62
|
+
* 获取鼠标下方第一个可选中元素,如果元素层叠,返回到是最上层元素
|
|
63
|
+
* @param event 鼠标事件
|
|
64
|
+
* @returns 鼠标下方第一个可选中元素
|
|
65
|
+
*/
|
|
66
|
+
getElementFromPoint(event: MouseEvent): Promise<HTMLElement | undefined>;
|
|
67
|
+
/**
|
|
68
|
+
* 判断一个元素能否在当前场景被选中
|
|
69
|
+
* @param el 被判断的元素
|
|
70
|
+
* @param event 鼠标事件
|
|
71
|
+
* @param stop 通过该元素如果得知剩下的元素都不可被选中,通知调用方终止对剩下元素的判断
|
|
72
|
+
* @returns 能否选中
|
|
73
|
+
*/
|
|
74
|
+
isElCanSelect(el: HTMLElement, event: MouseEvent, stop: () => boolean): Promise<boolean>;
|
|
75
|
+
/**
|
|
76
|
+
* 判断一个元素是否可以被多选,如果当前元素是page,则调stop函数告诉调用方不必继续判断其它元素了
|
|
77
|
+
*/
|
|
78
|
+
canMultiSelect(el: HTMLElement, stop: () => boolean): boolean;
|
|
79
|
+
select(el: HTMLElement, event: MouseEvent | undefined): void;
|
|
80
|
+
multiSelect(idOrElList: HTMLElement[] | Id[]): void;
|
|
81
|
+
getHighlightEl(): HTMLElement | undefined;
|
|
82
|
+
setHighlightEl(el: HTMLElement | undefined): void;
|
|
83
|
+
highlight(idOrEl: Id | HTMLElement): void;
|
|
84
|
+
clearHighlight(): void;
|
|
85
|
+
/**
|
|
86
|
+
* 用于在切换选择模式时清除上一次的状态
|
|
87
|
+
* @param selectType 需要清理的选择模式
|
|
88
|
+
*/
|
|
89
|
+
clearSelectStatus(selectType: SelectStatus): void;
|
|
90
|
+
/**
|
|
91
|
+
* 找到鼠标下方的容器,通过添加className对容器进行标记
|
|
92
|
+
* @param event 鼠标事件
|
|
93
|
+
* @param excludeElList 计算鼠标点所在容器时要排除的元素列表
|
|
94
|
+
*/
|
|
95
|
+
addContainerHighlightClassName(event: MouseEvent, excludeElList: Element[]): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* 鼠标拖拽着元素,在容器上方悬停,延迟一段时间后,对容器进行标记,如果悬停时间够长将标记成功,悬停时间短,调用方通过返回的timeoutId取消标记
|
|
98
|
+
* 标记的作用:1、高亮容器,给用户一个加入容器的交互感知;2、释放鼠标后,通过标记的标志找到要加入的容器
|
|
99
|
+
* @param event 鼠标事件
|
|
100
|
+
* @param excludeElList 计算鼠标所在容器时要排除的元素列表
|
|
101
|
+
* @returns timeoutId,调用方在鼠标移走时要取消该timeout,阻止标记
|
|
102
|
+
*/
|
|
103
|
+
delayedMarkContainer(event: MouseEvent, excludeElList?: Element[]): NodeJS.Timeout;
|
|
104
|
+
destroy(): void;
|
|
105
|
+
private changeCallback;
|
|
106
|
+
/**
|
|
107
|
+
* 在执行多选逻辑前,先准备好多选选中元素
|
|
108
|
+
* @param el 新选中的元素
|
|
109
|
+
* @returns 多选选中的元素列表
|
|
110
|
+
*/
|
|
111
|
+
private beforeMultiSelect;
|
|
112
|
+
/**
|
|
113
|
+
* 当前状态下能否将组件加入容器,默认是鼠标悬停一段时间加入,alt模式则是按住alt+鼠标悬停一段时间加入
|
|
114
|
+
*/
|
|
115
|
+
private canAddToContainer;
|
|
116
|
+
/**
|
|
117
|
+
* 结束对container的标记状态
|
|
118
|
+
* @returns 标记的容器元素,没有标记的容器时返回null
|
|
119
|
+
*/
|
|
120
|
+
private markContainerEnd;
|
|
121
|
+
private initMouseEvent;
|
|
122
|
+
/**
|
|
123
|
+
* 初始化键盘事件监听
|
|
124
|
+
*/
|
|
125
|
+
private initKeyEvent;
|
|
126
|
+
/**
|
|
127
|
+
* 处理单选、多选抛出来的事件
|
|
128
|
+
*/
|
|
129
|
+
private initActionEvent;
|
|
130
|
+
/**
|
|
131
|
+
* 在down事件中集中cpu处理画布中选中操作渲染,在up事件中再通知外面的编辑器更新
|
|
132
|
+
*/
|
|
133
|
+
private mouseDownHandler;
|
|
134
|
+
private isStopTriggerSelect;
|
|
135
|
+
/**
|
|
136
|
+
* 在up事件中负责对外通知选中事件,通知画布之外的编辑器更新
|
|
137
|
+
*/
|
|
138
|
+
private mouseUpHandler;
|
|
139
|
+
private mouseLeaveHandler;
|
|
140
|
+
private mouseWheelHandler;
|
|
141
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { OnDrag, OnDragGroup, OnDragGroupStart, OnDragStart, OnResize, OnResizeGroup, OnResizeGroupStart, OnResizeStart, OnRotate, OnRotateStart, OnScale, OnScaleStart } from 'moveable';
|
|
2
|
+
import MoveableHelper from 'moveable-helper';
|
|
3
|
+
import { Mode } from './const';
|
|
4
|
+
import { DragResizeHelperConfig, TargetElement } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* 拖拽/改变大小等操作发生时,moveable会抛出各种状态事件,DragResizeHelper负责响应这些事件,对目标节点target和拖拽节点targetShadow进行修改;
|
|
7
|
+
* 其中目标节点是DragResizeHelper直接改的,targetShadow作为直接被操作的拖拽框,是调用moveableHelper改的;
|
|
8
|
+
* 有个特殊情况是流式布局下,moveableHelper不支持,targetShadow也是DragResizeHelper直接改的
|
|
9
|
+
*/
|
|
10
|
+
export default class DragResizeHelper {
|
|
11
|
+
/** 目标节点在蒙层上的占位节点,用于跟鼠标交互,避免鼠标事件直接作用到目标节点 */
|
|
12
|
+
private targetShadow;
|
|
13
|
+
/** 要操作的原始目标节点 */
|
|
14
|
+
private target;
|
|
15
|
+
/** 多选:目标节点组 */
|
|
16
|
+
private targetList;
|
|
17
|
+
/** 响应拖拽的状态事件,修改绝对定位布局下targetShadow的dom。
|
|
18
|
+
* MoveableHelper里面的方法是成员属性,如果DragResizeHelper用继承的方式将无法通过super去调这些方法 */
|
|
19
|
+
private moveableHelper;
|
|
20
|
+
/** 流式布局下,目标节点的镜像节点 */
|
|
21
|
+
private ghostEl;
|
|
22
|
+
/** 用于记录节点被改变前的位置 */
|
|
23
|
+
private frameSnapShot;
|
|
24
|
+
/** 多选模式下的多个节点 */
|
|
25
|
+
private framesSnapShot;
|
|
26
|
+
/** 布局方式:流式布局、绝对定位、固定定位 */
|
|
27
|
+
private mode;
|
|
28
|
+
constructor(config: DragResizeHelperConfig);
|
|
29
|
+
destroy(): void;
|
|
30
|
+
destroyShadowEl(): void;
|
|
31
|
+
getShadowEl(): TargetElement | undefined;
|
|
32
|
+
updateShadowEl(el: HTMLElement): void;
|
|
33
|
+
setMode(mode: Mode): void;
|
|
34
|
+
/**
|
|
35
|
+
* 改变大小事件开始
|
|
36
|
+
* @param e 包含了拖拽节点的dom,moveableHelper会直接修改拖拽节点
|
|
37
|
+
*/
|
|
38
|
+
onResizeStart(e: OnResizeStart): void;
|
|
39
|
+
onResize(e: OnResize): void;
|
|
40
|
+
onDragStart(e: OnDragStart): void;
|
|
41
|
+
onDrag(e: OnDrag): void;
|
|
42
|
+
onRotateStart(e: OnRotateStart): void;
|
|
43
|
+
onRotate(e: OnRotate): void;
|
|
44
|
+
onScaleStart(e: OnScaleStart): void;
|
|
45
|
+
onScale(e: OnScale): void;
|
|
46
|
+
getGhostEl(): HTMLElement | undefined;
|
|
47
|
+
destroyGhostEl(): void;
|
|
48
|
+
clear(): void;
|
|
49
|
+
getFrame(el: HTMLElement | SVGElement): ReturnType<MoveableHelper['getFrame']>;
|
|
50
|
+
getShadowEls(): TargetElement[];
|
|
51
|
+
updateGroup(els: HTMLElement[]): void;
|
|
52
|
+
setTargetList(targetList: HTMLElement[]): void;
|
|
53
|
+
clearMultiSelectStatus(): void;
|
|
54
|
+
onResizeGroupStart(e: OnResizeGroupStart): void;
|
|
55
|
+
/**
|
|
56
|
+
* 多选状态下通过拖拽边框改变大小,所有选中组件会一起改变大小
|
|
57
|
+
*/
|
|
58
|
+
onResizeGroup(e: OnResizeGroup): void;
|
|
59
|
+
onDragGroupStart(e: OnDragGroupStart): void;
|
|
60
|
+
onDragGroup(e: OnDragGroup): void;
|
|
61
|
+
/**
|
|
62
|
+
* 多选状态设置多个节点的快照
|
|
63
|
+
*/
|
|
64
|
+
private setFramesSnapShot;
|
|
65
|
+
/**
|
|
66
|
+
* 流式布局把目标节点复制一份进行拖拽,在拖拽结束前不影响页面原布局样式
|
|
67
|
+
*/
|
|
68
|
+
private generateGhostEl;
|
|
69
|
+
private setGhostElChildrenId;
|
|
70
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import EventEmitter from 'events';
|
|
3
|
+
import { MoveableOptions } from 'moveable';
|
|
4
|
+
import { GuidesType, Mode } from './const';
|
|
5
|
+
import { MoveableOptionsManagerConfig } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* 单选和多选的父类,用于管理moveableOptions
|
|
8
|
+
* @extends EventEmitter
|
|
9
|
+
*/
|
|
10
|
+
export default class MoveableOptionsManager extends EventEmitter {
|
|
11
|
+
/** 布局方式:流式布局、绝对定位、固定定位 */
|
|
12
|
+
mode: Mode;
|
|
13
|
+
/** 画布容器 */
|
|
14
|
+
protected container: HTMLElement;
|
|
15
|
+
/** 水平参考线 */
|
|
16
|
+
private horizontalGuidelines;
|
|
17
|
+
/** 垂直参考线 */
|
|
18
|
+
private verticalGuidelines;
|
|
19
|
+
/** 对齐元素集合 */
|
|
20
|
+
private elementGuidelines;
|
|
21
|
+
/** 由外部调用方(编辑器)传入进来的moveable默认参数,可以为空,也可以是一个回调函数 */
|
|
22
|
+
private customizedOptions?;
|
|
23
|
+
/** 获取整个画布的根元素(在StageCore的mount函数中挂载的container) */
|
|
24
|
+
private getRootContainer;
|
|
25
|
+
constructor(config: MoveableOptionsManagerConfig);
|
|
26
|
+
/**
|
|
27
|
+
* 设置水平/垂直参考线
|
|
28
|
+
* @param type 参考线类型
|
|
29
|
+
* @param guidelines 参考线坐标数组
|
|
30
|
+
*/
|
|
31
|
+
setGuidelines(type: GuidesType, guidelines: number[]): void;
|
|
32
|
+
/**
|
|
33
|
+
* 清除横向和纵向的参考线
|
|
34
|
+
*/
|
|
35
|
+
clearGuides(): void;
|
|
36
|
+
/**
|
|
37
|
+
* 设置有哪些元素要辅助对齐
|
|
38
|
+
* @param selectedElList 选中的元素列表,需要排除在对齐元素之外
|
|
39
|
+
* @param allElList 全部元素列表
|
|
40
|
+
*/
|
|
41
|
+
protected setElementGuidelines(selectedElList: HTMLElement[], allElList: HTMLElement[]): void;
|
|
42
|
+
/**
|
|
43
|
+
* 获取moveable参数
|
|
44
|
+
* @param isMultiSelect 是否多选模式
|
|
45
|
+
* @param runtimeOptions 调用时实时传进来的的moveable参数
|
|
46
|
+
* @returns moveable所需参数
|
|
47
|
+
*/
|
|
48
|
+
protected getOptions(isMultiSelect: boolean, runtimeOptions?: MoveableOptions): MoveableOptions;
|
|
49
|
+
/**
|
|
50
|
+
* 获取单选和多选的moveable公共参数
|
|
51
|
+
* @returns moveable公共参数
|
|
52
|
+
*/
|
|
53
|
+
private getDefaultOptions;
|
|
54
|
+
/**
|
|
55
|
+
* 获取单选下的差异化参数
|
|
56
|
+
* @returns {MoveableOptions} moveable options参数
|
|
57
|
+
*/
|
|
58
|
+
private getSingleOptions;
|
|
59
|
+
/**
|
|
60
|
+
* 获取多选下的差异化参数
|
|
61
|
+
* @returns {MoveableOptions} moveable options参数
|
|
62
|
+
*/
|
|
63
|
+
private getMultiOptions;
|
|
64
|
+
/**
|
|
65
|
+
* 获取业务方自定义的moveable参数
|
|
66
|
+
*/
|
|
67
|
+
private getCustomizeOptions;
|
|
68
|
+
/**
|
|
69
|
+
* 这是给selectParentAbles的回调函数,用于触发选中父元素事件
|
|
70
|
+
*/
|
|
71
|
+
private selectParentHandler;
|
|
72
|
+
/**
|
|
73
|
+
* 为需要辅助对齐的元素创建div
|
|
74
|
+
* @param selectedElList 选中的元素列表,需要排除在对齐元素之外
|
|
75
|
+
* @param allElList 全部元素列表
|
|
76
|
+
* @returns frame 辅助对齐元素集合的页面片
|
|
77
|
+
*/
|
|
78
|
+
private createGuidelineElements;
|
|
79
|
+
/**
|
|
80
|
+
* 判断一个元素是否在元素列表里面
|
|
81
|
+
* @param ele 元素
|
|
82
|
+
* @param eleList 元素列表
|
|
83
|
+
* @returns 是否在元素列表里面
|
|
84
|
+
*/
|
|
85
|
+
private isInElementList;
|
|
86
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { MoveableManagerInterface, Renderer } from 'moveable';
|
|
2
|
+
declare const _default: (selectParentHandler: () => void) => {
|
|
3
|
+
name: string;
|
|
4
|
+
props: {};
|
|
5
|
+
events: {};
|
|
6
|
+
render(moveable: MoveableManagerInterface<any, any>, React: Renderer): any;
|
|
7
|
+
};
|
|
8
|
+
export default _default;
|
package/types/Rule.d.ts
CHANGED
|
@@ -8,12 +8,13 @@ export default class Rule extends EventEmitter {
|
|
|
8
8
|
verticalGuidelines: number[];
|
|
9
9
|
private container;
|
|
10
10
|
private containerResizeObserver;
|
|
11
|
+
private isShowGuides;
|
|
11
12
|
constructor(container: HTMLDivElement);
|
|
12
13
|
/**
|
|
13
|
-
*
|
|
14
|
-
* @param
|
|
14
|
+
* 是否显示辅助线
|
|
15
|
+
* @param isShowGuides 是否显示
|
|
15
16
|
*/
|
|
16
|
-
showGuides(
|
|
17
|
+
showGuides(isShowGuides?: boolean): void;
|
|
17
18
|
setGuides([hLines, vLines]: [number[], number[]]): void;
|
|
18
19
|
/**
|
|
19
20
|
* 清空所有参考线
|