@tmagic/editor 1.1.0-beta.10 → 1.1.0-beta.13
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/style.css +46 -0
- package/dist/tmagic-editor.mjs +862 -740
- package/dist/tmagic-editor.mjs.map +1 -1
- package/dist/tmagic-editor.umd.js +864 -739
- package/dist/tmagic-editor.umd.js.map +1 -1
- package/package.json +10 -10
- package/src/Editor.vue +4 -3
- package/src/components/ContentMenu.vue +4 -4
- package/src/components/Icon.vue +6 -20
- package/src/components/ScrollBar.vue +147 -0
- package/src/components/ScrollViewer.vue +89 -44
- package/src/components/ToolButton.vue +40 -138
- package/src/fields/UISelect.vue +2 -2
- package/src/index.ts +2 -0
- package/src/layouts/NavMenu.vue +156 -23
- package/src/layouts/sidebar/LayerMenu.vue +3 -3
- package/src/layouts/sidebar/LayerPanel.vue +39 -8
- package/src/layouts/workspace/PageBar.vue +1 -1
- package/src/layouts/workspace/Stage.vue +8 -90
- package/src/layouts/workspace/ViewerMenu.vue +3 -3
- package/src/layouts/workspace/Workspace.vue +133 -138
- package/src/services/editor.ts +17 -6
- package/src/services/props.ts +26 -53
- package/src/services/ui.ts +16 -20
- package/src/theme/nav-menu.scss +6 -0
- package/src/type.ts +26 -10
- package/src/utils/index.ts +1 -0
- package/src/utils/operator.ts +1 -1
- package/src/utils/props.ts +0 -3
- package/src/utils/scroll-viewer.ts +90 -158
- package/src/utils/stage.ts +91 -0
- package/types/Editor.vue.d.ts +7 -7
- package/types/components/ContentMenu.vue.d.ts +8 -8
- package/types/components/Icon.vue.d.ts +62 -12
- package/types/components/ScrollBar.vue.d.ts +83 -0
- package/types/components/ScrollViewer.vue.d.ts +131 -19
- package/types/components/ToolButton.vue.d.ts +56 -59
- package/types/index.d.ts +2 -0
- package/types/layouts/NavMenu.vue.d.ts +92 -23
- package/types/layouts/sidebar/LayerMenu.vue.d.ts +7 -7
- package/types/layouts/sidebar/LayerPanel.vue.d.ts +17 -15
- package/types/layouts/workspace/Workspace.vue.d.ts +54 -4
- package/types/services/editor.d.ts +1 -0
- package/types/services/props.d.ts +40 -9
- package/types/services/ui.d.ts +1 -1
- package/types/type.d.ts +23 -10
- package/types/utils/index.d.ts +1 -0
- package/types/utils/props.d.ts +0 -1
- package/types/utils/scroll-viewer.d.ts +16 -18
- package/types/utils/stage.d.ts +3 -0
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-workspace" tabindex="1" ref="workspace">
|
|
3
|
-
<
|
|
3
|
+
<slot name="stage">
|
|
4
|
+
<MagicStage :key="page?.id"></MagicStage>
|
|
5
|
+
</slot>
|
|
4
6
|
|
|
5
7
|
<slot name="workspace-content"></slot>
|
|
6
8
|
|
|
7
|
-
<
|
|
9
|
+
<PageBar>
|
|
8
10
|
<template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
|
|
9
11
|
<template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
|
|
10
|
-
</
|
|
12
|
+
</PageBar>
|
|
11
13
|
</div>
|
|
12
14
|
</template>
|
|
13
15
|
|
|
14
|
-
<script lang="ts">
|
|
15
|
-
import { computed,
|
|
16
|
+
<script lang="ts" setup>
|
|
17
|
+
import { computed, inject, onMounted, onUnmounted, ref } from 'vue';
|
|
16
18
|
import KeyController from 'keycon';
|
|
17
19
|
|
|
18
20
|
import type { MNode, MPage } from '@tmagic/schema';
|
|
@@ -23,140 +25,133 @@ import type { Services } from '../../type';
|
|
|
23
25
|
import PageBar from './PageBar.vue';
|
|
24
26
|
import MagicStage from './Stage.vue';
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
28
|
+
const services = inject<Services>('services');
|
|
29
|
+
const workspace = ref<HTMLDivElement>();
|
|
30
|
+
const nodes = computed(() => services?.editorService.get<MNode[]>('nodes'));
|
|
31
|
+
const page = computed(() => services?.editorService.get<MPage>('page'));
|
|
32
|
+
|
|
33
|
+
const mouseenterHandler = () => {
|
|
34
|
+
workspace.value?.focus();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const mouseleaveHandler = () => {
|
|
38
|
+
workspace.value?.blur();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
let keycon: KeyController;
|
|
42
|
+
|
|
43
|
+
onMounted(() => {
|
|
44
|
+
workspace.value?.addEventListener('mouseenter', mouseenterHandler);
|
|
45
|
+
workspace.value?.addEventListener('mouseleave', mouseleaveHandler);
|
|
46
|
+
|
|
47
|
+
keycon = new KeyController(workspace.value);
|
|
48
|
+
|
|
49
|
+
const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
|
|
50
|
+
|
|
51
|
+
const ctrl = isMac ? 'meta' : 'ctrl';
|
|
52
|
+
|
|
53
|
+
keycon
|
|
54
|
+
.keyup('delete', (e) => {
|
|
55
|
+
e.inputEvent.preventDefault();
|
|
56
|
+
if (!nodes.value || isPage(nodes.value[0])) return;
|
|
57
|
+
services?.editorService.remove(nodes.value);
|
|
58
|
+
})
|
|
59
|
+
.keyup('backspace', (e) => {
|
|
60
|
+
e.inputEvent.preventDefault();
|
|
61
|
+
if (!nodes.value || isPage(nodes.value[0])) return;
|
|
62
|
+
services?.editorService.remove(nodes.value);
|
|
63
|
+
})
|
|
64
|
+
.keydown([ctrl, 'c'], (e) => {
|
|
65
|
+
e.inputEvent.preventDefault();
|
|
66
|
+
nodes.value && services?.editorService.copy(nodes.value);
|
|
67
|
+
})
|
|
68
|
+
.keydown([ctrl, 'v'], (e) => {
|
|
69
|
+
e.inputEvent.preventDefault();
|
|
70
|
+
nodes.value && services?.editorService.paste({ offsetX: 10, offsetY: 10 });
|
|
71
|
+
})
|
|
72
|
+
.keydown([ctrl, 'x'], (e) => {
|
|
73
|
+
e.inputEvent.preventDefault();
|
|
74
|
+
if (!nodes.value || isPage(nodes.value[0])) return;
|
|
75
|
+
services?.editorService.copy(nodes.value);
|
|
76
|
+
services?.editorService.remove(nodes.value);
|
|
77
|
+
})
|
|
78
|
+
.keydown([ctrl, 'z'], (e) => {
|
|
79
|
+
e.inputEvent.preventDefault();
|
|
80
|
+
services?.editorService.undo();
|
|
81
|
+
})
|
|
82
|
+
.keydown([ctrl, 'shift', 'z'], (e) => {
|
|
83
|
+
e.inputEvent.preventDefault();
|
|
84
|
+
services?.editorService.redo();
|
|
85
|
+
})
|
|
86
|
+
.keydown('up', (e) => {
|
|
87
|
+
e.inputEvent.preventDefault();
|
|
88
|
+
services?.editorService.move(0, -1);
|
|
89
|
+
})
|
|
90
|
+
.keydown('down', (e) => {
|
|
91
|
+
e.inputEvent.preventDefault();
|
|
92
|
+
services?.editorService.move(0, 1);
|
|
93
|
+
})
|
|
94
|
+
.keydown('left', (e) => {
|
|
95
|
+
e.inputEvent.preventDefault();
|
|
96
|
+
services?.editorService.move(-1, 0);
|
|
97
|
+
})
|
|
98
|
+
.keydown('right', (e) => {
|
|
99
|
+
e.inputEvent.preventDefault();
|
|
100
|
+
services?.editorService.move(1, 0);
|
|
101
|
+
})
|
|
102
|
+
.keydown([ctrl, 'up'], (e) => {
|
|
103
|
+
e.inputEvent.preventDefault();
|
|
104
|
+
services?.editorService.move(0, -10);
|
|
105
|
+
})
|
|
106
|
+
.keydown([ctrl, 'down'], (e) => {
|
|
107
|
+
e.inputEvent.preventDefault();
|
|
108
|
+
services?.editorService.move(0, 10);
|
|
109
|
+
})
|
|
110
|
+
.keydown([ctrl, 'left'], (e) => {
|
|
111
|
+
e.inputEvent.preventDefault();
|
|
112
|
+
services?.editorService.move(-10, 0);
|
|
113
|
+
})
|
|
114
|
+
.keydown([ctrl, 'right'], (e) => {
|
|
115
|
+
e.inputEvent.preventDefault();
|
|
116
|
+
services?.editorService.move(10, 0);
|
|
117
|
+
})
|
|
118
|
+
.keydown('tab', (e) => {
|
|
119
|
+
e.inputEvent.preventDefault();
|
|
120
|
+
services?.editorService.selectNextNode();
|
|
121
|
+
})
|
|
122
|
+
.keydown([ctrl, 'tab'], (e) => {
|
|
123
|
+
e.inputEvent.preventDefault();
|
|
124
|
+
services?.editorService.selectNextPage();
|
|
125
|
+
})
|
|
126
|
+
.keydown([ctrl, '='], (e) => {
|
|
127
|
+
e.inputEvent.preventDefault();
|
|
128
|
+
services?.uiService.zoom(0.1);
|
|
129
|
+
})
|
|
130
|
+
.keydown([ctrl, 'numpadplus'], (e) => {
|
|
131
|
+
e.inputEvent.preventDefault();
|
|
132
|
+
services?.uiService.zoom(0.1);
|
|
133
|
+
})
|
|
134
|
+
.keydown([ctrl, '-'], (e) => {
|
|
135
|
+
e.inputEvent.preventDefault();
|
|
136
|
+
services?.uiService.zoom(-0.1);
|
|
137
|
+
})
|
|
138
|
+
.keydown([ctrl, 'numpad-'], (e) => {
|
|
139
|
+
e.inputEvent.preventDefault();
|
|
140
|
+
services?.uiService.zoom(-0.1);
|
|
141
|
+
})
|
|
142
|
+
.keydown([ctrl, '0'], (e) => {
|
|
143
|
+
e.inputEvent.preventDefault();
|
|
144
|
+
services?.uiService.set('zoom', services.uiService.calcZoom());
|
|
145
|
+
})
|
|
146
|
+
.keydown([ctrl, '1'], (e) => {
|
|
147
|
+
e.inputEvent.preventDefault();
|
|
148
|
+
services?.uiService.set('zoom', 1);
|
|
147
149
|
});
|
|
150
|
+
});
|
|
148
151
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
return {
|
|
156
|
-
workspace,
|
|
157
|
-
|
|
158
|
-
page: computed(() => services?.editorService.get<MPage>('page')),
|
|
159
|
-
};
|
|
160
|
-
},
|
|
152
|
+
onUnmounted(() => {
|
|
153
|
+
workspace.value?.removeEventListener('mouseenter', mouseenterHandler);
|
|
154
|
+
workspace.value?.removeEventListener('mouseleave', mouseleaveHandler);
|
|
155
|
+
keycon.destroy();
|
|
161
156
|
});
|
|
162
157
|
</script>
|
package/src/services/editor.ts
CHANGED
|
@@ -71,6 +71,7 @@ class Editor extends BaseService {
|
|
|
71
71
|
'sort',
|
|
72
72
|
'copy',
|
|
73
73
|
'paste',
|
|
74
|
+
'doPaste',
|
|
74
75
|
'duAlignCenter',
|
|
75
76
|
'alignCenter',
|
|
76
77
|
'moveLayer',
|
|
@@ -367,7 +368,7 @@ class Editor extends BaseService {
|
|
|
367
368
|
|
|
368
369
|
this.emit('add', newNodes);
|
|
369
370
|
|
|
370
|
-
return
|
|
371
|
+
return Array.isArray(addNode) ? newNodes : newNodes[0];
|
|
371
372
|
}
|
|
372
373
|
|
|
373
374
|
public async doRemove(node: MNode): Promise<void> {
|
|
@@ -503,7 +504,7 @@ class Editor extends BaseService {
|
|
|
503
504
|
|
|
504
505
|
this.emit('update', newNodes);
|
|
505
506
|
|
|
506
|
-
return
|
|
507
|
+
return Array.isArray(config) ? newNodes : newNodes[0];
|
|
507
508
|
}
|
|
508
509
|
|
|
509
510
|
/**
|
|
@@ -556,11 +557,16 @@ class Editor extends BaseService {
|
|
|
556
557
|
|
|
557
558
|
if (!Array.isArray(config)) return;
|
|
558
559
|
|
|
559
|
-
const pasteConfigs = await
|
|
560
|
+
const pasteConfigs = await this.doPaste(config, position);
|
|
560
561
|
|
|
561
562
|
return this.add(pasteConfigs);
|
|
562
563
|
}
|
|
563
564
|
|
|
565
|
+
public async doPaste(config: MNode[], position: PastePosition = {}): Promise<MNode[]> {
|
|
566
|
+
const pasteConfigs = await beforePaste(position, cloneDeep(config));
|
|
567
|
+
return pasteConfigs;
|
|
568
|
+
}
|
|
569
|
+
|
|
564
570
|
public async doAlignCenter(config: MNode): Promise<MNode> {
|
|
565
571
|
const parent = this.getParentById(config.id);
|
|
566
572
|
|
|
@@ -614,7 +620,7 @@ class Editor extends BaseService {
|
|
|
614
620
|
*/
|
|
615
621
|
public async moveLayer(offset: number | LayerOffset): Promise<void> {
|
|
616
622
|
const parent = this.get<MContainer>('parent');
|
|
617
|
-
const node = this.get('node');
|
|
623
|
+
const node = this.get<MNode>('node');
|
|
618
624
|
const brothers: MNode[] = parent?.items || [];
|
|
619
625
|
const index = brothers.findIndex((item) => `${item.id}` === `${node?.id}`);
|
|
620
626
|
|
|
@@ -626,11 +632,15 @@ class Editor extends BaseService {
|
|
|
626
632
|
brothers.splice(index + parseInt(`${offset}`, 10), 0, brothers.splice(index, 1)[0]);
|
|
627
633
|
}
|
|
628
634
|
|
|
635
|
+
const grandparent = this.getParentById(parent.id);
|
|
629
636
|
this.get<StageCore | null>('stage')?.update({
|
|
630
637
|
config: cloneDeep(toRaw(parent)),
|
|
631
|
-
parentId:
|
|
638
|
+
parentId: grandparent?.id,
|
|
632
639
|
root: cloneDeep(this.get<MApp>('root')),
|
|
633
640
|
});
|
|
641
|
+
|
|
642
|
+
this.addModifiedNodeId(parent.id);
|
|
643
|
+
this.pushHistoryState();
|
|
634
644
|
}
|
|
635
645
|
|
|
636
646
|
/**
|
|
@@ -664,7 +674,8 @@ class Editor extends BaseService {
|
|
|
664
674
|
|
|
665
675
|
await stage.select(targetId);
|
|
666
676
|
|
|
667
|
-
|
|
677
|
+
const targetParent = this.getParentById(target.id);
|
|
678
|
+
await stage.update({ config: cloneDeep(target), parentId: targetParent?.id, root });
|
|
668
679
|
|
|
669
680
|
await this.select(newConfig);
|
|
670
681
|
stage.select(newConfig.id);
|
package/src/services/props.ts
CHANGED
|
@@ -20,12 +20,11 @@ import { reactive } from 'vue';
|
|
|
20
20
|
import { cloneDeep, mergeWith } from 'lodash-es';
|
|
21
21
|
|
|
22
22
|
import type { FormConfig } from '@tmagic/form';
|
|
23
|
-
import type {
|
|
24
|
-
import {
|
|
25
|
-
import { isPop, toLine } from '@tmagic/utils';
|
|
23
|
+
import type { MComponent, MNode } from '@tmagic/schema';
|
|
24
|
+
import { toLine } from '@tmagic/utils';
|
|
26
25
|
|
|
27
26
|
import type { PropsState } from '../type';
|
|
28
|
-
import {
|
|
27
|
+
import { fillConfig } from '../utils/props';
|
|
29
28
|
|
|
30
29
|
import BaseService from './BaseService';
|
|
31
30
|
|
|
@@ -43,6 +42,7 @@ class Props extends BaseService {
|
|
|
43
42
|
'getPropsValue',
|
|
44
43
|
'createId',
|
|
45
44
|
'setNewItemId',
|
|
45
|
+
'fillConfig',
|
|
46
46
|
'getDefaultPropsValue',
|
|
47
47
|
]);
|
|
48
48
|
}
|
|
@@ -54,13 +54,17 @@ class Props extends BaseService {
|
|
|
54
54
|
this.emit('props-configs-change');
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
public async fillConfig(config: FormConfig) {
|
|
58
|
+
return fillConfig(config);
|
|
59
|
+
}
|
|
60
|
+
|
|
57
61
|
/**
|
|
58
62
|
* 为指定类型组件设置组件属性表单配置
|
|
59
63
|
* @param type 组件类型
|
|
60
64
|
* @param config 组件属性表单配置
|
|
61
65
|
*/
|
|
62
|
-
public setPropsConfig(type: string, config: FormConfig) {
|
|
63
|
-
this.state.propsConfigMap[type] = fillConfig(Array.isArray(config) ? config : [config]);
|
|
66
|
+
public async setPropsConfig(type: string, config: FormConfig) {
|
|
67
|
+
this.state.propsConfigMap[type] = await this.fillConfig(Array.isArray(config) ? config : [config]);
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
/**
|
|
@@ -73,7 +77,7 @@ class Props extends BaseService {
|
|
|
73
77
|
return await this.getPropsConfig('button');
|
|
74
78
|
}
|
|
75
79
|
|
|
76
|
-
return cloneDeep(this.state.propsConfigMap[type] ||
|
|
80
|
+
return cloneDeep(this.state.propsConfigMap[type] || (await this.fillConfig([])));
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
public setPropsValues(values: Record<string, MNode>) {
|
|
@@ -125,19 +129,6 @@ class Props extends BaseService {
|
|
|
125
129
|
};
|
|
126
130
|
}
|
|
127
131
|
|
|
128
|
-
/**
|
|
129
|
-
* 生成指定位数的GUID,无【-】格式
|
|
130
|
-
* @param digit 位数,默认值8
|
|
131
|
-
* @returns
|
|
132
|
-
*/
|
|
133
|
-
guid(digit = 8): string {
|
|
134
|
-
return 'x'.repeat(digit).replace(/[xy]/g, (c) => {
|
|
135
|
-
const r = (Math.random() * 16) | 0;
|
|
136
|
-
const v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
137
|
-
return v.toString(16);
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
132
|
public async createId(type: string | number): Promise<string> {
|
|
142
133
|
return `${type}_${this.guid()}`;
|
|
143
134
|
}
|
|
@@ -147,19 +138,12 @@ class Props extends BaseService {
|
|
|
147
138
|
* @param {Object} config 组件配置
|
|
148
139
|
*/
|
|
149
140
|
/* eslint no-param-reassign: ["error", { "props": false }] */
|
|
150
|
-
public async setNewItemId(config: MNode
|
|
151
|
-
const oldId = config.id;
|
|
152
|
-
|
|
141
|
+
public async setNewItemId(config: MNode) {
|
|
153
142
|
config.id = await this.createId(config.type || 'component');
|
|
154
143
|
|
|
155
|
-
// 只有弹窗在页面下的一级子元素才有效
|
|
156
|
-
if (isPop(config) && parent?.type === NodeType.PAGE) {
|
|
157
|
-
updatePopId(oldId, config.id, parent);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
144
|
if (config.items && Array.isArray(config.items)) {
|
|
161
145
|
for (const item of config.items) {
|
|
162
|
-
await this.setNewItemId(item
|
|
146
|
+
await this.setNewItemId(item);
|
|
163
147
|
}
|
|
164
148
|
}
|
|
165
149
|
|
|
@@ -186,31 +170,20 @@ class Props extends BaseService {
|
|
|
186
170
|
name: type,
|
|
187
171
|
};
|
|
188
172
|
}
|
|
189
|
-
}
|
|
190
173
|
|
|
191
|
-
/**
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (config.popId === oldId) {
|
|
205
|
-
config.popId = popId;
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (Array.isArray(config.items)) {
|
|
210
|
-
updatePopId(oldId, popId, config as MPage);
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
};
|
|
174
|
+
/**
|
|
175
|
+
* 生成指定位数的GUID,无【-】格式
|
|
176
|
+
* @param digit 位数,默认值8
|
|
177
|
+
* @returns
|
|
178
|
+
*/
|
|
179
|
+
private guid(digit = 8): string {
|
|
180
|
+
return 'x'.repeat(digit).replace(/[xy]/g, (c) => {
|
|
181
|
+
const r = (Math.random() * 16) | 0;
|
|
182
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
183
|
+
return v.toString(16);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
214
187
|
|
|
215
188
|
export type PropsService = Props;
|
|
216
189
|
|
package/src/services/ui.ts
CHANGED
|
@@ -98,10 +98,6 @@ class Ui extends BaseService {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
(state as any)[name] = value;
|
|
101
|
-
|
|
102
|
-
if (name === 'stageContainerRect') {
|
|
103
|
-
state.zoom = this.calcZoom();
|
|
104
|
-
}
|
|
105
101
|
}
|
|
106
102
|
|
|
107
103
|
public get<T>(name: keyof typeof state): T {
|
|
@@ -113,6 +109,22 @@ class Ui extends BaseService {
|
|
|
113
109
|
if (this.get<number>('zoom') < 0.1) this.set('zoom', 0.1);
|
|
114
110
|
}
|
|
115
111
|
|
|
112
|
+
public calcZoom() {
|
|
113
|
+
const { stageRect, stageContainerRect } = state;
|
|
114
|
+
const { height, width } = stageContainerRect;
|
|
115
|
+
if (!width || !height) return 1;
|
|
116
|
+
|
|
117
|
+
// 30为标尺的大小
|
|
118
|
+
const stageWidth = stageRect.width + 30;
|
|
119
|
+
const stageHeight = stageRect.height + 30;
|
|
120
|
+
|
|
121
|
+
if (width > stageWidth && height > stageHeight) {
|
|
122
|
+
return 1;
|
|
123
|
+
}
|
|
124
|
+
// 60/80是为了不要让画布太过去贴住四周(这样好看些)
|
|
125
|
+
return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
|
|
126
|
+
}
|
|
127
|
+
|
|
116
128
|
private setColumnWidth({ left, center, right }: SetColumnWidth) {
|
|
117
129
|
const columnWidth = {
|
|
118
130
|
...toRaw(this.get<GetColumnWidth>('columnWidth')),
|
|
@@ -150,22 +162,6 @@ class Ui extends BaseService {
|
|
|
150
162
|
};
|
|
151
163
|
state.zoom = this.calcZoom();
|
|
152
164
|
}
|
|
153
|
-
|
|
154
|
-
private calcZoom() {
|
|
155
|
-
const { stageRect, stageContainerRect } = state;
|
|
156
|
-
const { height, width } = stageContainerRect;
|
|
157
|
-
if (!width || !height) return 1;
|
|
158
|
-
|
|
159
|
-
// 30为标尺的大小
|
|
160
|
-
const stageWidth = stageRect.width + 30;
|
|
161
|
-
const stageHeight = stageRect.height + 30;
|
|
162
|
-
|
|
163
|
-
if (width > stageWidth && height > stageHeight) {
|
|
164
|
-
return 1;
|
|
165
|
-
}
|
|
166
|
-
// 60/80是为了不要让画布太过去贴住四周(这样好看些)
|
|
167
|
-
return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
|
|
168
|
-
}
|
|
169
165
|
}
|
|
170
166
|
|
|
171
167
|
export type UiService = Ui;
|
package/src/theme/nav-menu.scss
CHANGED
package/src/type.ts
CHANGED
|
@@ -82,16 +82,22 @@ export interface ComponentGroupState {
|
|
|
82
82
|
list: ComponentGroup[];
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
export enum ColumnLayout {
|
|
86
|
+
LEFT = 'left',
|
|
87
|
+
CENTER = 'center',
|
|
88
|
+
RIGHT = 'right',
|
|
89
|
+
}
|
|
90
|
+
|
|
85
91
|
export interface SetColumnWidth {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
[ColumnLayout.LEFT]?: number;
|
|
93
|
+
[ColumnLayout.CENTER]?: number | 'auto';
|
|
94
|
+
[ColumnLayout.RIGHT]?: number;
|
|
89
95
|
}
|
|
90
96
|
|
|
91
97
|
export interface GetColumnWidth {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
98
|
+
[ColumnLayout.LEFT]: number;
|
|
99
|
+
[ColumnLayout.CENTER]: number;
|
|
100
|
+
[ColumnLayout.RIGHT]: number;
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
export interface StageRect {
|
|
@@ -174,6 +180,7 @@ export interface MenuButton {
|
|
|
174
180
|
/** type为button/dropdown时点击运行的方法 */
|
|
175
181
|
handler?: (data: Services, event: MouseEvent) => Promise<any> | any;
|
|
176
182
|
/** type为dropdown时,下拉的菜单列表, 或者有子菜单时 */
|
|
183
|
+
className?: string;
|
|
177
184
|
items?: MenuButton[];
|
|
178
185
|
}
|
|
179
186
|
|
|
@@ -187,6 +194,7 @@ export interface MenuComponent {
|
|
|
187
194
|
listeners?: Record<string, Function>;
|
|
188
195
|
slots?: Record<string, any>;
|
|
189
196
|
/** 是否显示,默认为true */
|
|
197
|
+
className?: string;
|
|
190
198
|
display?: boolean | ((data?: Services) => Promise<boolean> | boolean);
|
|
191
199
|
}
|
|
192
200
|
|
|
@@ -209,16 +217,17 @@ export type MenuItem =
|
|
|
209
217
|
| 'guides'
|
|
210
218
|
| 'rule'
|
|
211
219
|
| MenuButton
|
|
212
|
-
| MenuComponent
|
|
220
|
+
| MenuComponent
|
|
221
|
+
| string;
|
|
213
222
|
|
|
214
223
|
/** 工具栏 */
|
|
215
224
|
export interface MenuBarData {
|
|
216
225
|
/** 顶部工具栏左边项 */
|
|
217
|
-
|
|
226
|
+
[ColumnLayout.LEFT]?: MenuItem[];
|
|
218
227
|
/** 顶部工具栏中间项 */
|
|
219
|
-
|
|
228
|
+
[ColumnLayout.CENTER]?: MenuItem[];
|
|
220
229
|
/** 顶部工具栏右边项 */
|
|
221
|
-
|
|
230
|
+
[ColumnLayout.RIGHT]?: MenuItem[];
|
|
222
231
|
}
|
|
223
232
|
|
|
224
233
|
export interface SideComponent extends MenuComponent {
|
|
@@ -287,3 +296,10 @@ export enum Keys {
|
|
|
287
296
|
|
|
288
297
|
export const H_GUIDE_LINE_STORAGE_KEY = '$MagicStageHorizontalGuidelinesData';
|
|
289
298
|
export const V_GUIDE_LINE_STORAGE_KEY = '$MagicStageVerticalGuidelinesData';
|
|
299
|
+
|
|
300
|
+
export interface ScrollViewerEvent {
|
|
301
|
+
scrollLeft: number;
|
|
302
|
+
scrollTop: number;
|
|
303
|
+
scrollHeight: number;
|
|
304
|
+
scrollWidth: number;
|
|
305
|
+
}
|
package/src/utils/index.ts
CHANGED