@tmagic/stage 1.0.0-rc.2 → 1.0.0-rc.5
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 +85 -24
- package/dist/tmagic-stage.es.js.map +1 -1
- package/dist/tmagic-stage.umd.js +85 -24
- package/dist/tmagic-stage.umd.js.map +1 -1
- package/dist/types/src/StageDragResize.d.ts +11 -1
- package/dist/types/src/StageMask.d.ts +2 -1
- package/dist/types/src/const.d.ts +24 -1
- package/dist/types/src/types.d.ts +3 -0
- package/dist/types/src/util.d.ts +2 -1
- package/package.json +5 -4
- package/src/Rule.ts +13 -5
- package/src/StageCore.ts +4 -1
- package/src/StageDragResize.ts +52 -20
- package/src/StageMask.ts +30 -9
- package/src/const.ts +24 -2
- package/src/types.ts +3 -0
- package/src/util.ts +21 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MoveableOptions } from 'react-moveable/declaration/types';
|
|
2
|
+
import Core from '@tmagic/core';
|
|
2
3
|
import { Id, MApp, MNode } from '@tmagic/schema';
|
|
3
4
|
import { GuidesType } from './const';
|
|
4
5
|
import StageCore from './StageCore';
|
|
@@ -15,6 +16,7 @@ export declare type StageCoreConfig = {
|
|
|
15
16
|
/** runtime 的HTML地址,可以是一个HTTP地址,如果和编辑器不同域,需要设置跨域,也可以是一个相对或绝对路径 */
|
|
16
17
|
runtimeUrl?: string;
|
|
17
18
|
render?: (renderer: StageCore) => Promise<HTMLElement> | HTMLElement;
|
|
19
|
+
autoScrollIntoView?: boolean;
|
|
18
20
|
};
|
|
19
21
|
export interface StageRenderConfig {
|
|
20
22
|
core: StageCore;
|
|
@@ -62,6 +64,7 @@ export interface RemoveData {
|
|
|
62
64
|
root: MApp;
|
|
63
65
|
}
|
|
64
66
|
export interface Runtime {
|
|
67
|
+
getApp?: () => Core;
|
|
65
68
|
beforeSelect?: (el: HTMLElement) => Promise<boolean> | boolean;
|
|
66
69
|
getSnapElements?: (el?: HTMLElement) => HTMLElement[];
|
|
67
70
|
updateRootConfig: (config: MApp) => void;
|
package/dist/types/src/util.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Mode } from './const';
|
|
1
|
+
import { GuidesType, Mode } from './const';
|
|
2
2
|
import type { Offset } from './types';
|
|
3
3
|
export declare const getOffset: (el: HTMLElement) => Offset;
|
|
4
4
|
export declare const getAbsolutePosition: (el: HTMLElement, { top, left }: Offset) => {
|
|
@@ -20,3 +20,4 @@ export declare const createDiv: ({ className, cssText }: {
|
|
|
20
20
|
}) => HTMLDivElement;
|
|
21
21
|
export declare const removeSelectedClassName: (doc: Document) => void;
|
|
22
22
|
export declare const addSelectedClassName: (el: Element, doc: Document) => void;
|
|
23
|
+
export declare const getGuideLineFromCache: (type: GuidesType) => number[];
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.0.0-rc.
|
|
2
|
+
"version": "1.0.0-rc.5",
|
|
3
3
|
"name": "@tmagic/stage",
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"dist/*"
|
|
@@ -27,8 +27,9 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@scena/guides": "^0.17.0",
|
|
30
|
-
"@tmagic/
|
|
31
|
-
"@tmagic/
|
|
30
|
+
"@tmagic/core": "^1.0.0-rc.5",
|
|
31
|
+
"@tmagic/schema": "^1.0.0-rc.5",
|
|
32
|
+
"@tmagic/utils": "^1.0.0-rc.5",
|
|
32
33
|
"events": "^3.3.0",
|
|
33
34
|
"lodash-es": "^4.17.21",
|
|
34
35
|
"moveable": "^0.29.4",
|
|
@@ -43,5 +44,5 @@
|
|
|
43
44
|
"vite": "^2.3.7",
|
|
44
45
|
"vite-plugin-dts": "^0.9.6"
|
|
45
46
|
},
|
|
46
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "d147b361d7e6123cda99c6ba68a2ac7e074be37f"
|
|
47
48
|
}
|
package/src/Rule.ts
CHANGED
|
@@ -2,13 +2,14 @@ import EventEmitter from 'events';
|
|
|
2
2
|
|
|
3
3
|
import Guides, { GuidesEvents } from '@scena/guides';
|
|
4
4
|
|
|
5
|
-
import { GuidesType } from './const';
|
|
5
|
+
import { GuidesType, H_GUIDE_LINE_STORAGE_KEY, V_GUIDE_LINE_STORAGE_KEY } from './const';
|
|
6
|
+
import { getGuideLineFromCache } from './util';
|
|
6
7
|
|
|
7
8
|
export default class Rule extends EventEmitter {
|
|
8
9
|
public hGuides: Guides;
|
|
9
10
|
public vGuides: Guides;
|
|
10
|
-
public horizontalGuidelines: number[] =
|
|
11
|
-
public verticalGuidelines: number[] =
|
|
11
|
+
public horizontalGuidelines: number[] = getGuideLineFromCache(GuidesType.HORIZONTAL);
|
|
12
|
+
public verticalGuidelines: number[] = getGuideLineFromCache(GuidesType.VERTICAL);
|
|
12
13
|
|
|
13
14
|
private container: HTMLDivElement;
|
|
14
15
|
private containerResizeObserver: ResizeObserver;
|
|
@@ -17,8 +18,8 @@ export default class Rule extends EventEmitter {
|
|
|
17
18
|
super();
|
|
18
19
|
|
|
19
20
|
this.container = container;
|
|
20
|
-
this.hGuides = this.createGuides(GuidesType.HORIZONTAL);
|
|
21
|
-
this.vGuides = this.createGuides(GuidesType.VERTICAL);
|
|
21
|
+
this.hGuides = this.createGuides(GuidesType.HORIZONTAL, this.horizontalGuidelines);
|
|
22
|
+
this.vGuides = this.createGuides(GuidesType.VERTICAL, this.verticalGuidelines);
|
|
22
23
|
|
|
23
24
|
this.hGuides.on('changeGuides', this.hGuidesChangeGuidesHandler);
|
|
24
25
|
this.vGuides.on('changeGuides', this.vGuidesChangeGuidesHandler);
|
|
@@ -68,6 +69,9 @@ export default class Rule extends EventEmitter {
|
|
|
68
69
|
type: GuidesType.HORIZONTAL,
|
|
69
70
|
guides: [],
|
|
70
71
|
});
|
|
72
|
+
|
|
73
|
+
globalThis.localStorage.setItem(V_GUIDE_LINE_STORAGE_KEY, '[]');
|
|
74
|
+
globalThis.localStorage.setItem(H_GUIDE_LINE_STORAGE_KEY, '[]');
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
/**
|
|
@@ -138,6 +142,8 @@ export default class Rule extends EventEmitter {
|
|
|
138
142
|
type: GuidesType.HORIZONTAL,
|
|
139
143
|
guides: this.horizontalGuidelines,
|
|
140
144
|
});
|
|
145
|
+
|
|
146
|
+
globalThis.localStorage.setItem(H_GUIDE_LINE_STORAGE_KEY, JSON.stringify(e.guides));
|
|
141
147
|
};
|
|
142
148
|
|
|
143
149
|
private vGuidesChangeGuidesHandler = (e: GuidesEvents['changeGuides']) => {
|
|
@@ -146,5 +152,7 @@ export default class Rule extends EventEmitter {
|
|
|
146
152
|
type: GuidesType.VERTICAL,
|
|
147
153
|
guides: this.verticalGuidelines,
|
|
148
154
|
});
|
|
155
|
+
|
|
156
|
+
globalThis.localStorage.setItem(V_GUIDE_LINE_STORAGE_KEY, JSON.stringify(e.guides));
|
|
149
157
|
};
|
|
150
158
|
}
|
package/src/StageCore.ts
CHANGED
|
@@ -155,7 +155,10 @@ export default class StageCore extends EventEmitter {
|
|
|
155
155
|
|
|
156
156
|
this.mask.setLayout(el);
|
|
157
157
|
this.dr.select(el, event);
|
|
158
|
-
|
|
158
|
+
|
|
159
|
+
if (this.config.autoScrollIntoView || el.dataset.autoScrollIntoView) {
|
|
160
|
+
this.mask.intersectionObserver?.observe(el);
|
|
161
|
+
}
|
|
159
162
|
|
|
160
163
|
this.selectedDom = el;
|
|
161
164
|
|
package/src/StageDragResize.ts
CHANGED
|
@@ -23,14 +23,18 @@ import type { MoveableOptions } from 'moveable';
|
|
|
23
23
|
import Moveable from 'moveable';
|
|
24
24
|
import MoveableHelper from 'moveable-helper';
|
|
25
25
|
|
|
26
|
-
import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, Mode } from './const';
|
|
26
|
+
import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, Mode, ZIndex } from './const';
|
|
27
27
|
import StageCore from './StageCore';
|
|
28
|
-
import type { Offset,
|
|
29
|
-
import { getAbsolutePosition, getMode, getOffset } from './util';
|
|
28
|
+
import type { Offset, SortEventData, StageDragResizeConfig } from './types';
|
|
29
|
+
import { getAbsolutePosition, getGuideLineFromCache, getMode, getOffset } from './util';
|
|
30
30
|
|
|
31
|
+
/** 拖动状态 */
|
|
31
32
|
enum ActionStatus {
|
|
33
|
+
/** 开始拖动 */
|
|
32
34
|
START = 'start',
|
|
35
|
+
/** 拖动中 */
|
|
33
36
|
ING = 'ing',
|
|
37
|
+
/** 拖动结束 */
|
|
34
38
|
END = 'end',
|
|
35
39
|
}
|
|
36
40
|
|
|
@@ -39,17 +43,27 @@ enum ActionStatus {
|
|
|
39
43
|
*/
|
|
40
44
|
export default class StageDragResize extends EventEmitter {
|
|
41
45
|
public core: StageCore;
|
|
46
|
+
/** 画布容器 */
|
|
42
47
|
public container: HTMLElement;
|
|
48
|
+
/** 目标节点 */
|
|
43
49
|
public target?: HTMLElement;
|
|
50
|
+
/** 目标节点在蒙层中的占位节点 */
|
|
44
51
|
public dragEl: HTMLElement;
|
|
52
|
+
/** Moveable拖拽类实例 */
|
|
45
53
|
public moveable?: Moveable;
|
|
46
|
-
|
|
47
|
-
public
|
|
54
|
+
/** 水平参考线 */
|
|
55
|
+
public horizontalGuidelines: number[] = getGuideLineFromCache(GuidesType.HORIZONTAL);
|
|
56
|
+
/** 垂直参考线 */
|
|
57
|
+
public verticalGuidelines: number[] = getGuideLineFromCache(GuidesType.VERTICAL);
|
|
58
|
+
/** 对齐元素集合 */
|
|
48
59
|
public elementGuidelines: HTMLElement[] = [];
|
|
60
|
+
/** 布局方式:流式布局、绝对定位、固定定位 */
|
|
49
61
|
public mode: Mode = Mode.ABSOLUTE;
|
|
50
62
|
|
|
51
63
|
private moveableOptions: MoveableOptions = {};
|
|
64
|
+
/** 拖动状态 */
|
|
52
65
|
private dragStatus: ActionStatus = ActionStatus.END;
|
|
66
|
+
/** 流式布局下,目标节点的镜像节点 */
|
|
53
67
|
private ghostEl: HTMLElement | undefined;
|
|
54
68
|
private moveableHelper?: MoveableHelper;
|
|
55
69
|
|
|
@@ -157,6 +171,29 @@ export default class StageDragResize extends EventEmitter {
|
|
|
157
171
|
});
|
|
158
172
|
}
|
|
159
173
|
|
|
174
|
+
private setElementGuidelines(nodes: HTMLElement[]) {
|
|
175
|
+
this.elementGuidelines.forEach((node) => {
|
|
176
|
+
node.remove();
|
|
177
|
+
});
|
|
178
|
+
this.elementGuidelines = [];
|
|
179
|
+
|
|
180
|
+
if (this.mode === Mode.ABSOLUTE) {
|
|
181
|
+
const frame = document.createDocumentFragment();
|
|
182
|
+
|
|
183
|
+
for (const node of nodes) {
|
|
184
|
+
const { width, height } = node.getBoundingClientRect();
|
|
185
|
+
if (node === this.target) continue;
|
|
186
|
+
const { left, top } = getOffset(node as HTMLElement);
|
|
187
|
+
const elementGuideline = document.createElement('div');
|
|
188
|
+
elementGuideline.style.cssText = `position: absolute;width: ${width}px;height: ${height}px;top: ${top}px;left: ${left}px`;
|
|
189
|
+
this.elementGuidelines.push(elementGuideline);
|
|
190
|
+
frame.append(elementGuideline);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
this.container.append(frame);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
160
197
|
private initMoveable() {
|
|
161
198
|
this.moveable?.destroy();
|
|
162
199
|
|
|
@@ -274,19 +311,6 @@ export default class StageDragResize extends EventEmitter {
|
|
|
274
311
|
});
|
|
275
312
|
}
|
|
276
313
|
|
|
277
|
-
private getSnapElements(runtime: Runtime, el?: HTMLElement): HTMLElement[] {
|
|
278
|
-
const { renderer, mask } = this.core;
|
|
279
|
-
const getSnapElements =
|
|
280
|
-
runtime?.getSnapElements ||
|
|
281
|
-
(() => {
|
|
282
|
-
const doc = renderer.contentWindow?.document;
|
|
283
|
-
return doc ? Array.from(doc.querySelectorAll('[id]')) : [];
|
|
284
|
-
});
|
|
285
|
-
return getSnapElements(el).filter(
|
|
286
|
-
(element) => element !== this.target && !this.target?.contains(element) && element !== mask.page,
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
314
|
private sort(): void {
|
|
291
315
|
if (!this.target || !this.ghostEl) throw new Error('未知错误');
|
|
292
316
|
const { top } = this.ghostEl.getBoundingClientRect();
|
|
@@ -330,7 +354,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
330
354
|
const ghostEl = el.cloneNode(true) as HTMLElement;
|
|
331
355
|
const { top, left } = getAbsolutePosition(el, getOffset(el));
|
|
332
356
|
ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
|
|
333
|
-
ghostEl.style.zIndex =
|
|
357
|
+
ghostEl.style.zIndex = ZIndex.GHOST_EL;
|
|
334
358
|
ghostEl.style.opacity = '.5';
|
|
335
359
|
ghostEl.style.position = 'absolute';
|
|
336
360
|
ghostEl.style.left = `${left}px`;
|
|
@@ -354,7 +378,7 @@ export default class StageDragResize extends EventEmitter {
|
|
|
354
378
|
top: ${offset.top}px;
|
|
355
379
|
width: ${width}px;
|
|
356
380
|
height: ${height}px;
|
|
357
|
-
z-index:
|
|
381
|
+
z-index: ${ZIndex.DRAG_EL};
|
|
358
382
|
`;
|
|
359
383
|
|
|
360
384
|
this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
|
|
@@ -376,6 +400,14 @@ export default class StageDragResize extends EventEmitter {
|
|
|
376
400
|
moveableOptions = moveableOptions(this.core);
|
|
377
401
|
}
|
|
378
402
|
|
|
403
|
+
const elementGuidelines: any = moveableOptions.elementGuidelines || this.target.parentElement?.children || [];
|
|
404
|
+
|
|
405
|
+
this.setElementGuidelines(elementGuidelines);
|
|
406
|
+
|
|
407
|
+
if (moveableOptions.elementGuidelines) {
|
|
408
|
+
delete moveableOptions.elementGuidelines;
|
|
409
|
+
}
|
|
410
|
+
|
|
379
411
|
return {
|
|
380
412
|
origin: false,
|
|
381
413
|
rootContainer: this.core.container,
|
package/src/StageMask.ts
CHANGED
|
@@ -83,6 +83,7 @@ export default class StageMask extends Rule {
|
|
|
83
83
|
public wrapperWidth = 0;
|
|
84
84
|
public maxScrollTop = 0;
|
|
85
85
|
public maxScrollLeft = 0;
|
|
86
|
+
public intersectionObserver: IntersectionObserver | null = null;
|
|
86
87
|
|
|
87
88
|
private mode: Mode = Mode.ABSOLUTE;
|
|
88
89
|
private pageResizeObserver: ResizeObserver | null = null;
|
|
@@ -132,6 +133,27 @@ export default class StageMask extends Rule {
|
|
|
132
133
|
this.page = page;
|
|
133
134
|
this.pageScrollParent = getScrollParent(page) || this.core.renderer.contentWindow?.document.documentElement || null;
|
|
134
135
|
this.pageResizeObserver?.disconnect();
|
|
136
|
+
this.wrapperResizeObserver?.disconnect();
|
|
137
|
+
this.intersectionObserver?.disconnect();
|
|
138
|
+
|
|
139
|
+
if (typeof IntersectionObserver !== 'undefined') {
|
|
140
|
+
this.intersectionObserver = new IntersectionObserver(
|
|
141
|
+
(entries) => {
|
|
142
|
+
entries.forEach((entry) => {
|
|
143
|
+
const { target, intersectionRatio } = entry;
|
|
144
|
+
if (intersectionRatio <= 0) {
|
|
145
|
+
this.scrollIntoView(target);
|
|
146
|
+
}
|
|
147
|
+
this.intersectionObserver?.unobserve(target);
|
|
148
|
+
});
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
root: this.pageScrollParent,
|
|
152
|
+
rootMargin: '0px',
|
|
153
|
+
threshold: 1.0,
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
}
|
|
135
157
|
|
|
136
158
|
if (typeof ResizeObserver !== 'undefined') {
|
|
137
159
|
this.pageResizeObserver = new ResizeObserver((entries) => {
|
|
@@ -140,9 +162,10 @@ export default class StageMask extends Rule {
|
|
|
140
162
|
this.setHeight(clientHeight);
|
|
141
163
|
this.setWidth(clientWidth);
|
|
142
164
|
|
|
143
|
-
this.fixScrollValue();
|
|
144
165
|
this.scroll();
|
|
145
|
-
this.core.dr.
|
|
166
|
+
if (this.core.dr.moveable) {
|
|
167
|
+
this.core.dr.updateMoveable();
|
|
168
|
+
}
|
|
146
169
|
});
|
|
147
170
|
|
|
148
171
|
this.pageResizeObserver.observe(page);
|
|
@@ -173,9 +196,7 @@ export default class StageMask extends Rule {
|
|
|
173
196
|
this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
|
|
174
197
|
}
|
|
175
198
|
|
|
176
|
-
public scrollIntoView(el:
|
|
177
|
-
if (this.mode === Mode.FIXED) return;
|
|
178
|
-
|
|
199
|
+
public scrollIntoView(el: Element): void {
|
|
179
200
|
el.scrollIntoView();
|
|
180
201
|
if (!this.pageScrollParent) return;
|
|
181
202
|
this.scrollLeft = this.pageScrollParent.scrollLeft;
|
|
@@ -198,6 +219,8 @@ export default class StageMask extends Rule {
|
|
|
198
219
|
}
|
|
199
220
|
|
|
200
221
|
private scroll() {
|
|
222
|
+
this.fixScrollValue();
|
|
223
|
+
|
|
201
224
|
let { scrollLeft, scrollTop } = this;
|
|
202
225
|
|
|
203
226
|
if (this.pageScrollParent) {
|
|
@@ -244,14 +267,14 @@ export default class StageMask extends Rule {
|
|
|
244
267
|
* 计算并设置最大滚动宽度
|
|
245
268
|
*/
|
|
246
269
|
private setMaxScrollLeft(): void {
|
|
247
|
-
this.maxScrollLeft = this.width - this.wrapperWidth;
|
|
270
|
+
this.maxScrollLeft = Math.max(this.width - this.wrapperWidth, 0);
|
|
248
271
|
}
|
|
249
272
|
|
|
250
273
|
/**
|
|
251
274
|
* 计算并设置最大滚动高度
|
|
252
275
|
*/
|
|
253
276
|
private setMaxScrollTop(): void {
|
|
254
|
-
this.maxScrollTop = this.height - this.wrapperHeight;
|
|
277
|
+
this.maxScrollTop = Math.max(this.height - this.wrapperHeight, 0);
|
|
255
278
|
}
|
|
256
279
|
|
|
257
280
|
/**
|
|
@@ -313,8 +336,6 @@ export default class StageMask extends Rule {
|
|
|
313
336
|
this.scrollLeft = this.scrollLeft + deltaX;
|
|
314
337
|
}
|
|
315
338
|
|
|
316
|
-
this.fixScrollValue();
|
|
317
|
-
|
|
318
339
|
this.scroll();
|
|
319
340
|
|
|
320
341
|
this.emit('scroll', event);
|
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
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import { MoveableOptions } from 'react-moveable/declaration/types';
|
|
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,7 @@ export type StageCoreConfig = {
|
|
|
37
38
|
/** runtime 的HTML地址,可以是一个HTTP地址,如果和编辑器不同域,需要设置跨域,也可以是一个相对或绝对路径 */
|
|
38
39
|
runtimeUrl?: string;
|
|
39
40
|
render?: (renderer: StageCore) => Promise<HTMLElement> | HTMLElement;
|
|
41
|
+
autoScrollIntoView?: boolean;
|
|
40
42
|
};
|
|
41
43
|
|
|
42
44
|
export interface StageRenderConfig {
|
|
@@ -94,6 +96,7 @@ export interface RemoveData {
|
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
export interface Runtime {
|
|
99
|
+
getApp?: () => Core;
|
|
97
100
|
beforeSelect?: (el: HTMLElement) => Promise<boolean> | boolean;
|
|
98
101
|
getSnapElements?: (el?: HTMLElement) => HTMLElement[];
|
|
99
102
|
updateRootConfig: (config: MApp) => void;
|
package/src/util.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
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
22
|
const getParents = (el: Element, relative: Element) => {
|
|
@@ -184,3 +184,23 @@ export const addSelectedClassName = (el: Element, doc: Document) => {
|
|
|
184
184
|
item.classList.add(`${SELECTED_CLASS}-parents`);
|
|
185
185
|
});
|
|
186
186
|
};
|
|
187
|
+
|
|
188
|
+
export const getGuideLineFromCache = (type: GuidesType): number[] => {
|
|
189
|
+
const key = {
|
|
190
|
+
[GuidesType.HORIZONTAL]: H_GUIDE_LINE_STORAGE_KEY,
|
|
191
|
+
[GuidesType.VERTICAL]: V_GUIDE_LINE_STORAGE_KEY,
|
|
192
|
+
}[type];
|
|
193
|
+
|
|
194
|
+
if (!key) return [];
|
|
195
|
+
|
|
196
|
+
const guideLineCacheData = globalThis.localStorage.getItem(key);
|
|
197
|
+
if (guideLineCacheData) {
|
|
198
|
+
try {
|
|
199
|
+
return JSON.parse(guideLineCacheData) || [];
|
|
200
|
+
} catch (e) {
|
|
201
|
+
console.error(e);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return [];
|
|
206
|
+
};
|