@tmagic/stage 1.0.0-rc.1 → 1.0.0-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tmagic-stage.es.js +215 -115
- package/dist/tmagic-stage.es.js.map +1 -1
- package/dist/tmagic-stage.umd.js +215 -115
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/dist/types/src/StageDragResize.d.ts +14 -2
- package/dist/types/src/StageMask.d.ts +2 -0
- package/dist/types/src/TargetCalibrate.d.ts +3 -1
- package/dist/types/src/const.d.ts +24 -1
- package/dist/types/src/types.d.ts +12 -3
- package/dist/types/src/util.d.ts +3 -2
- package/package.json +5 -5
- package/src/Rule.ts +13 -5
- package/src/StageCore.ts +6 -1
- package/src/StageDragResize.ts +150 -61
- package/src/StageHighlight.ts +1 -0
- package/src/StageMask.ts +37 -6
- package/src/StageRender.ts +0 -12
- package/src/TargetCalibrate.ts +15 -31
- package/src/const.ts +24 -2
- package/src/types.ts +13 -3
- package/src/util.ts +40 -29
- package/LICENSE +0 -5432
package/src/StageRender.ts
CHANGED
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
|
|
19
19
|
import { EventEmitter } from 'events';
|
|
20
20
|
|
|
21
|
-
import { SELECTED_CLASS, ZIndex } from './const';
|
|
22
21
|
import StageCore from './StageCore';
|
|
23
22
|
import type { Runtime, RuntimeWindow, StageRenderConfig } from './types';
|
|
24
23
|
import { getHost, isSameDomain } from './util';
|
|
@@ -122,16 +121,5 @@ export default class StageRender extends EventEmitter {
|
|
|
122
121
|
this.iframe?.contentDocument?.body?.appendChild(el);
|
|
123
122
|
}
|
|
124
123
|
}
|
|
125
|
-
|
|
126
|
-
if (this.contentWindow) {
|
|
127
|
-
const style = this.contentWindow.document.createElement('style');
|
|
128
|
-
style.id = 'tmagic-stage-render';
|
|
129
|
-
style.innerHTML = `
|
|
130
|
-
.${SELECTED_CLASS}, .${SELECTED_CLASS}-parent {
|
|
131
|
-
z-index: ${ZIndex.SELECTED_EL};
|
|
132
|
-
}
|
|
133
|
-
`;
|
|
134
|
-
this.contentWindow.document.head.appendChild(style);
|
|
135
|
-
}
|
|
136
124
|
};
|
|
137
125
|
}
|
package/src/TargetCalibrate.ts
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import { EventEmitter } from 'events';
|
|
21
21
|
|
|
22
22
|
import { Mode } from './const';
|
|
23
|
+
import StageCore from './StageCore';
|
|
23
24
|
import StageDragResize from './StageDragResize';
|
|
24
25
|
import StageMask from './StageMask';
|
|
25
26
|
import type { Offset, TargetCalibrateConfig } from './types';
|
|
@@ -32,7 +33,8 @@ export default class TargetCalibrate extends EventEmitter {
|
|
|
32
33
|
public parent: HTMLElement;
|
|
33
34
|
public mask: StageMask;
|
|
34
35
|
public dr: StageDragResize;
|
|
35
|
-
public
|
|
36
|
+
public core: StageCore;
|
|
37
|
+
public operationEl: HTMLDivElement;
|
|
36
38
|
|
|
37
39
|
constructor(config: TargetCalibrateConfig) {
|
|
38
40
|
super();
|
|
@@ -40,23 +42,30 @@ export default class TargetCalibrate extends EventEmitter {
|
|
|
40
42
|
this.parent = config.parent;
|
|
41
43
|
this.mask = config.mask;
|
|
42
44
|
this.dr = config.dr;
|
|
45
|
+
this.core = config.core;
|
|
43
46
|
|
|
44
47
|
this.operationEl = globalThis.document.createElement('div');
|
|
45
48
|
this.parent.append(this.operationEl);
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
public update(el: HTMLElement, prefix: String): HTMLElement {
|
|
49
|
-
const { width, height } = el.getBoundingClientRect();
|
|
50
52
|
const { left, top } = this.getOffset(el);
|
|
53
|
+
const { transform } = getComputedStyle(el);
|
|
51
54
|
this.operationEl.style.cssText = `
|
|
52
55
|
position: absolute;
|
|
56
|
+
transform: ${transform};
|
|
53
57
|
left: ${left}px;
|
|
54
58
|
top: ${top}px;
|
|
55
|
-
width: ${
|
|
56
|
-
height: ${
|
|
59
|
+
width: ${el.clientWidth}px;
|
|
60
|
+
height: ${el.clientHeight}px;
|
|
57
61
|
`;
|
|
58
62
|
|
|
59
63
|
this.operationEl.id = `${prefix}${el.id}`;
|
|
64
|
+
|
|
65
|
+
if (typeof this.core.config.updateDragEl === 'function') {
|
|
66
|
+
this.core.config.updateDragEl(this.operationEl, el);
|
|
67
|
+
}
|
|
68
|
+
|
|
60
69
|
return this.operationEl;
|
|
61
70
|
}
|
|
62
71
|
|
|
@@ -65,35 +74,10 @@ export default class TargetCalibrate extends EventEmitter {
|
|
|
65
74
|
}
|
|
66
75
|
|
|
67
76
|
private getOffset(el: HTMLElement): Offset {
|
|
68
|
-
const { transform } = getComputedStyle(el);
|
|
69
77
|
const { offsetParent } = el;
|
|
70
78
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (transform.indexOf('matrix') > -1) {
|
|
75
|
-
let a = 1;
|
|
76
|
-
let b = 1;
|
|
77
|
-
let c = 1;
|
|
78
|
-
let d = 1;
|
|
79
|
-
let e = 0;
|
|
80
|
-
let f = 0;
|
|
81
|
-
transform.replace(
|
|
82
|
-
/matrix\((.+), (.+), (.+), (.+), (.+), (.+)\)/,
|
|
83
|
-
($0: string, $1: string, $2: string, $3: string, $4: string, $5: string, $6: string): string => {
|
|
84
|
-
a = +$1;
|
|
85
|
-
b = +$2;
|
|
86
|
-
c = +$3;
|
|
87
|
-
d = +$4;
|
|
88
|
-
e = +$5;
|
|
89
|
-
f = +$6;
|
|
90
|
-
return transform;
|
|
91
|
-
},
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
left = a * left + c * top + e;
|
|
95
|
-
top = b * left + d * top + f;
|
|
96
|
-
}
|
|
79
|
+
const left = el.offsetLeft;
|
|
80
|
+
const top = el.offsetTop;
|
|
97
81
|
|
|
98
82
|
if (offsetParent) {
|
|
99
83
|
const parentOffset = this.getOffset(offsetParent as HTMLElement);
|
package/src/const.ts
CHANGED
|
@@ -16,36 +16,58 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
/** 流式布局下拖动时需要clone一个镜像节点,镜像节点的id前缀 */
|
|
20
20
|
export const GHOST_EL_ID_PREFIX = 'ghost_el_';
|
|
21
21
|
|
|
22
|
+
/** 拖动的时候需要在蒙层中创建一个占位节点,该节点的id前缀 */
|
|
22
23
|
export const DRAG_EL_ID_PREFIX = 'drag_el_';
|
|
23
24
|
|
|
25
|
+
/** 高亮事需要在蒙层中创建一个占位节点,该节点的id前缀 */
|
|
24
26
|
export const HIGHLIGHT_EL_ID_PREFIX = 'highlight_el_';
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
/** 默认放到缩小倍数 */
|
|
27
29
|
export const DEFAULT_ZOOM = 1;
|
|
28
30
|
|
|
31
|
+
/** 参考线类型 */
|
|
29
32
|
export enum GuidesType {
|
|
33
|
+
/** 水平 */
|
|
30
34
|
HORIZONTAL = 'horizontal',
|
|
35
|
+
/** 垂直 */
|
|
31
36
|
VERTICAL = 'vertical',
|
|
32
37
|
}
|
|
33
38
|
|
|
39
|
+
/** css z-index */
|
|
34
40
|
export enum ZIndex {
|
|
41
|
+
/** 蒙层,用于监听用户操作,需要置于顶层 */
|
|
35
42
|
MASK = '99999',
|
|
43
|
+
/** 选中的节点 */
|
|
36
44
|
SELECTED_EL = '666',
|
|
45
|
+
GHOST_EL = '700',
|
|
46
|
+
DRAG_EL = '9',
|
|
37
47
|
}
|
|
38
48
|
|
|
49
|
+
/** 鼠标按键 */
|
|
39
50
|
export enum MouseButton {
|
|
51
|
+
/** 左键 */
|
|
40
52
|
LEFT = 0,
|
|
53
|
+
/** z中健 */
|
|
41
54
|
MIDDLE = 1,
|
|
55
|
+
/** 右键 */
|
|
42
56
|
RIGHT = 2,
|
|
43
57
|
}
|
|
44
58
|
|
|
59
|
+
/** 布局方式 */
|
|
45
60
|
export enum Mode {
|
|
61
|
+
/** 绝对定位布局 */
|
|
46
62
|
ABSOLUTE = 'absolute',
|
|
63
|
+
/** 固定定位布局 */
|
|
47
64
|
FIXED = 'fixed',
|
|
65
|
+
/** 流式布局 */
|
|
48
66
|
SORTABLE = 'sortable',
|
|
49
67
|
}
|
|
50
68
|
|
|
69
|
+
/** 选中节点的class name */
|
|
51
70
|
export const SELECTED_CLASS = 'tmagic-stage-selected-area';
|
|
71
|
+
|
|
72
|
+
export const H_GUIDE_LINE_STORAGE_KEY = '$MagicStageHorizontalGuidelinesData';
|
|
73
|
+
export const V_GUIDE_LINE_STORAGE_KEY = '$MagicStageVerticalGuidelinesData';
|
package/src/types.ts
CHANGED
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { MoveableOptions } from '
|
|
19
|
+
import { MoveableOptions } from 'moveable';
|
|
20
20
|
|
|
21
|
+
import Core from '@tmagic/core';
|
|
21
22
|
import { Id, MApp, MNode } from '@tmagic/schema';
|
|
22
23
|
|
|
23
24
|
import { GuidesType } from './const';
|
|
@@ -37,6 +38,8 @@ export type StageCoreConfig = {
|
|
|
37
38
|
/** runtime 的HTML地址,可以是一个HTTP地址,如果和编辑器不同域,需要设置跨域,也可以是一个相对或绝对路径 */
|
|
38
39
|
runtimeUrl?: string;
|
|
39
40
|
render?: (renderer: StageCore) => Promise<HTMLElement> | HTMLElement;
|
|
41
|
+
autoScrollIntoView?: boolean;
|
|
42
|
+
updateDragEl?: (el: HTMLDivElement, target: HTMLElement) => void;
|
|
40
43
|
};
|
|
41
44
|
|
|
42
45
|
export interface StageRenderConfig {
|
|
@@ -56,6 +59,7 @@ export type Rect = {
|
|
|
56
59
|
width: number;
|
|
57
60
|
height: number;
|
|
58
61
|
} & Offset;
|
|
62
|
+
|
|
59
63
|
export interface Offset {
|
|
60
64
|
left: number;
|
|
61
65
|
top: number;
|
|
@@ -70,10 +74,14 @@ export interface UpdateEventData {
|
|
|
70
74
|
el: HTMLElement;
|
|
71
75
|
ghostEl: HTMLElement;
|
|
72
76
|
style: {
|
|
73
|
-
width
|
|
74
|
-
height
|
|
77
|
+
width?: number;
|
|
78
|
+
height?: number;
|
|
75
79
|
left?: number;
|
|
76
80
|
top?: number;
|
|
81
|
+
transform?: {
|
|
82
|
+
rotate?: string;
|
|
83
|
+
scale?: string;
|
|
84
|
+
};
|
|
77
85
|
};
|
|
78
86
|
}
|
|
79
87
|
|
|
@@ -94,6 +102,7 @@ export interface RemoveData {
|
|
|
94
102
|
}
|
|
95
103
|
|
|
96
104
|
export interface Runtime {
|
|
105
|
+
getApp?: () => Core;
|
|
97
106
|
beforeSelect?: (el: HTMLElement) => Promise<boolean> | boolean;
|
|
98
107
|
getSnapElements?: (el?: HTMLElement) => HTMLElement[];
|
|
99
108
|
updateRootConfig: (config: MApp) => void;
|
|
@@ -125,4 +134,5 @@ export interface TargetCalibrateConfig {
|
|
|
125
134
|
parent: HTMLElement;
|
|
126
135
|
mask: StageMask;
|
|
127
136
|
dr: StageDragResize;
|
|
137
|
+
core: StageCore;
|
|
128
138
|
}
|
package/src/util.ts
CHANGED
|
@@ -16,39 +16,24 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { Mode, SELECTED_CLASS } from './const';
|
|
19
|
+
import { GuidesType, H_GUIDE_LINE_STORAGE_KEY, Mode, SELECTED_CLASS, V_GUIDE_LINE_STORAGE_KEY } from './const';
|
|
20
20
|
import type { Offset } from './types';
|
|
21
21
|
|
|
22
|
+
const getParents = (el: Element, relative: Element) => {
|
|
23
|
+
let cur: Element | null = el.parentElement;
|
|
24
|
+
const parents: Element[] = [];
|
|
25
|
+
while (cur && cur !== relative) {
|
|
26
|
+
parents.push(cur);
|
|
27
|
+
cur = cur.parentElement;
|
|
28
|
+
}
|
|
29
|
+
return parents;
|
|
30
|
+
};
|
|
31
|
+
|
|
22
32
|
export const getOffset = (el: HTMLElement): Offset => {
|
|
23
|
-
const { transform } = getComputedStyle(el);
|
|
24
33
|
const { offsetParent } = el;
|
|
25
34
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (transform.indexOf('matrix') > -1) {
|
|
30
|
-
let a = 1;
|
|
31
|
-
let b = 1;
|
|
32
|
-
let c = 1;
|
|
33
|
-
let d = 1;
|
|
34
|
-
let e = 0;
|
|
35
|
-
let f = 0;
|
|
36
|
-
transform.replace(
|
|
37
|
-
/matrix\((.+), (.+), (.+), (.+), (.+), (.+)\)/,
|
|
38
|
-
($0: string, $1: string, $2: string, $3: string, $4: string, $5: string, $6: string): string => {
|
|
39
|
-
a = +$1;
|
|
40
|
-
b = +$2;
|
|
41
|
-
c = +$3;
|
|
42
|
-
d = +$4;
|
|
43
|
-
e = +$5;
|
|
44
|
-
f = +$6;
|
|
45
|
-
return transform;
|
|
46
|
-
},
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
left = a * left + c * top + e;
|
|
50
|
-
top = b * left + d * top + f;
|
|
51
|
-
}
|
|
35
|
+
const left = el.offsetLeft;
|
|
36
|
+
const top = el.offsetTop;
|
|
52
37
|
|
|
53
38
|
if (offsetParent) {
|
|
54
39
|
const parentOffset = getOffset(offsetParent as HTMLElement);
|
|
@@ -161,10 +146,36 @@ export const removeSelectedClassName = (doc: Document) => {
|
|
|
161
146
|
if (oldEl) {
|
|
162
147
|
oldEl.classList.remove(SELECTED_CLASS);
|
|
163
148
|
(oldEl.parentNode as HTMLDivElement)?.classList.remove(`${SELECTED_CLASS}-parent`);
|
|
149
|
+
doc.querySelectorAll(`.${SELECTED_CLASS}-parents`).forEach((item) => {
|
|
150
|
+
item.classList.remove(`${SELECTED_CLASS}-parents`);
|
|
151
|
+
});
|
|
164
152
|
}
|
|
165
153
|
};
|
|
166
154
|
|
|
167
|
-
export const addSelectedClassName = (el: Element) => {
|
|
155
|
+
export const addSelectedClassName = (el: Element, doc: Document) => {
|
|
168
156
|
el.classList.add(SELECTED_CLASS);
|
|
169
157
|
(el.parentNode as Element)?.classList.add(`${SELECTED_CLASS}-parent`);
|
|
158
|
+
getParents(el, doc.body).forEach((item) => {
|
|
159
|
+
item.classList.add(`${SELECTED_CLASS}-parents`);
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export const getGuideLineFromCache = (type: GuidesType): number[] => {
|
|
164
|
+
const key = {
|
|
165
|
+
[GuidesType.HORIZONTAL]: H_GUIDE_LINE_STORAGE_KEY,
|
|
166
|
+
[GuidesType.VERTICAL]: V_GUIDE_LINE_STORAGE_KEY,
|
|
167
|
+
}[type];
|
|
168
|
+
|
|
169
|
+
if (!key) return [];
|
|
170
|
+
|
|
171
|
+
const guideLineCacheData = globalThis.localStorage.getItem(key);
|
|
172
|
+
if (guideLineCacheData) {
|
|
173
|
+
try {
|
|
174
|
+
return JSON.parse(guideLineCacheData) || [];
|
|
175
|
+
} catch (e) {
|
|
176
|
+
console.error(e);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return [];
|
|
170
181
|
};
|