@tmagic/editor 1.1.0-beta.12 → 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.
Files changed (40) hide show
  1. package/dist/style.css +46 -0
  2. package/dist/tmagic-editor.mjs +781 -688
  3. package/dist/tmagic-editor.mjs.map +1 -1
  4. package/dist/tmagic-editor.umd.js +783 -686
  5. package/dist/tmagic-editor.umd.js.map +1 -1
  6. package/package.json +8 -8
  7. package/src/Editor.vue +3 -3
  8. package/src/components/ContentMenu.vue +4 -4
  9. package/src/components/Icon.vue +6 -20
  10. package/src/components/ScrollBar.vue +147 -0
  11. package/src/components/ScrollViewer.vue +89 -44
  12. package/src/components/ToolButton.vue +40 -138
  13. package/src/index.ts +2 -0
  14. package/src/layouts/NavMenu.vue +156 -23
  15. package/src/layouts/sidebar/LayerMenu.vue +3 -3
  16. package/src/layouts/workspace/Stage.vue +8 -90
  17. package/src/layouts/workspace/ViewerMenu.vue +3 -3
  18. package/src/layouts/workspace/Workspace.vue +131 -138
  19. package/src/services/ui.ts +16 -20
  20. package/src/theme/nav-menu.scss +6 -0
  21. package/src/type.ts +26 -10
  22. package/src/utils/index.ts +1 -0
  23. package/src/utils/scroll-viewer.ts +90 -158
  24. package/src/utils/stage.ts +91 -0
  25. package/types/Editor.vue.d.ts +7 -7
  26. package/types/components/ContentMenu.vue.d.ts +8 -8
  27. package/types/components/Icon.vue.d.ts +62 -12
  28. package/types/components/ScrollBar.vue.d.ts +83 -0
  29. package/types/components/ScrollViewer.vue.d.ts +131 -19
  30. package/types/components/ToolButton.vue.d.ts +56 -59
  31. package/types/index.d.ts +2 -0
  32. package/types/layouts/NavMenu.vue.d.ts +92 -23
  33. package/types/layouts/sidebar/LayerMenu.vue.d.ts +7 -7
  34. package/types/layouts/sidebar/LayerPanel.vue.d.ts +12 -12
  35. package/types/layouts/workspace/Workspace.vue.d.ts +54 -4
  36. package/types/services/ui.d.ts +1 -1
  37. package/types/type.d.ts +23 -10
  38. package/types/utils/index.d.ts +1 -0
  39. package/types/utils/scroll-viewer.d.ts +16 -18
  40. package/types/utils/stage.d.ts +3 -0
@@ -1,20 +1,20 @@
1
1
  <template>
2
2
  <div class="m-editor-workspace" tabindex="1" ref="workspace">
3
3
  <slot name="stage">
4
- <magic-stage :key="page?.id"></magic-stage>
4
+ <MagicStage :key="page?.id"></MagicStage>
5
5
  </slot>
6
6
 
7
7
  <slot name="workspace-content"></slot>
8
8
 
9
- <page-bar>
9
+ <PageBar>
10
10
  <template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
11
11
  <template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
12
- </page-bar>
12
+ </PageBar>
13
13
  </div>
14
14
  </template>
15
15
 
16
- <script lang="ts">
17
- import { computed, defineComponent, inject, onMounted, onUnmounted, ref } from 'vue';
16
+ <script lang="ts" setup>
17
+ import { computed, inject, onMounted, onUnmounted, ref } from 'vue';
18
18
  import KeyController from 'keycon';
19
19
 
20
20
  import type { MNode, MPage } from '@tmagic/schema';
@@ -25,140 +25,133 @@ import type { Services } from '../../type';
25
25
  import PageBar from './PageBar.vue';
26
26
  import MagicStage from './Stage.vue';
27
27
 
28
- export default defineComponent({
29
- name: 'm-editor-workspace',
30
-
31
- components: {
32
- PageBar,
33
- MagicStage,
34
- },
35
-
36
- setup() {
37
- const services = inject<Services>('services');
38
- const workspace = ref<HTMLDivElement>();
39
- const nodes = computed(() => services?.editorService.get<MNode[]>('nodes'));
40
- let keycon: KeyController;
41
-
42
- const mouseenterHandler = () => {
43
- workspace.value?.focus();
44
- };
45
-
46
- const mouseleaveHandler = () => {
47
- workspace.value?.blur();
48
- };
49
-
50
- onMounted(() => {
51
- workspace.value?.addEventListener('mouseenter', mouseenterHandler);
52
- workspace.value?.addEventListener('mouseleave', mouseleaveHandler);
53
-
54
- keycon = new KeyController(workspace.value);
55
-
56
- const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
57
-
58
- const ctrl = isMac ? 'meta' : 'ctrl';
59
-
60
- keycon
61
- .keyup('delete', (e) => {
62
- e.inputEvent.preventDefault();
63
- if (!nodes.value || isPage(nodes.value[0])) return;
64
- services?.editorService.remove(nodes.value);
65
- })
66
- .keyup('backspace', (e) => {
67
- e.inputEvent.preventDefault();
68
- if (!nodes.value || isPage(nodes.value[0])) return;
69
- services?.editorService.remove(nodes.value);
70
- })
71
- .keydown([ctrl, 'c'], (e) => {
72
- e.inputEvent.preventDefault();
73
- nodes.value && services?.editorService.copy(nodes.value);
74
- })
75
- .keydown([ctrl, 'v'], (e) => {
76
- e.inputEvent.preventDefault();
77
- nodes.value && services?.editorService.paste({ offsetX: 10, offsetY: 10 });
78
- })
79
- .keydown([ctrl, 'x'], (e) => {
80
- e.inputEvent.preventDefault();
81
- if (!nodes.value || isPage(nodes.value[0])) return;
82
- services?.editorService.copy(nodes.value);
83
- services?.editorService.remove(nodes.value);
84
- })
85
- .keydown([ctrl, 'z'], (e) => {
86
- e.inputEvent.preventDefault();
87
- services?.editorService.undo();
88
- })
89
- .keydown([ctrl, 'shift', 'z'], (e) => {
90
- e.inputEvent.preventDefault();
91
- services?.editorService.redo();
92
- })
93
- .keydown('up', (e) => {
94
- e.inputEvent.preventDefault();
95
- services?.editorService.move(0, -1);
96
- })
97
- .keydown('down', (e) => {
98
- e.inputEvent.preventDefault();
99
- services?.editorService.move(0, 1);
100
- })
101
- .keydown('left', (e) => {
102
- e.inputEvent.preventDefault();
103
- services?.editorService.move(-1, 0);
104
- })
105
- .keydown('right', (e) => {
106
- e.inputEvent.preventDefault();
107
- services?.editorService.move(1, 0);
108
- })
109
- .keydown([ctrl, 'up'], (e) => {
110
- e.inputEvent.preventDefault();
111
- services?.editorService.move(0, -10);
112
- })
113
- .keydown([ctrl, 'down'], (e) => {
114
- e.inputEvent.preventDefault();
115
- services?.editorService.move(0, 10);
116
- })
117
- .keydown([ctrl, 'left'], (e) => {
118
- e.inputEvent.preventDefault();
119
- services?.editorService.move(-10, 0);
120
- })
121
- .keydown([ctrl, 'right'], (e) => {
122
- e.inputEvent.preventDefault();
123
- services?.editorService.move(10, 0);
124
- })
125
- .keydown('tab', (e) => {
126
- e.inputEvent.preventDefault();
127
- services?.editorService.selectNextNode();
128
- })
129
- .keydown([ctrl, 'tab'], (e) => {
130
- e.inputEvent.preventDefault();
131
- services?.editorService.selectNextPage();
132
- })
133
- .keydown([ctrl, '='], (e) => {
134
- e.inputEvent.preventDefault();
135
- services?.uiService.zoom(0.1);
136
- })
137
- .keydown([ctrl, 'numpadplus'], (e) => {
138
- e.inputEvent.preventDefault();
139
- services?.uiService.zoom(0.1);
140
- })
141
- .keydown([ctrl, '-'], (e) => {
142
- e.inputEvent.preventDefault();
143
- services?.uiService.zoom(-0.1);
144
- })
145
- .keydown([ctrl, 'numpad-'], (e) => {
146
- e.inputEvent.preventDefault();
147
- services?.uiService.zoom(-0.1);
148
- });
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);
149
149
  });
150
+ });
150
151
 
151
- onUnmounted(() => {
152
- workspace.value?.removeEventListener('mouseenter', mouseenterHandler);
153
- workspace.value?.removeEventListener('mouseleave', mouseleaveHandler);
154
- keycon.destroy();
155
- });
156
-
157
- return {
158
- workspace,
159
-
160
- page: computed(() => services?.editorService.get<MPage>('page')),
161
- };
162
- },
152
+ onUnmounted(() => {
153
+ workspace.value?.removeEventListener('mouseenter', mouseenterHandler);
154
+ workspace.value?.removeEventListener('mouseleave', mouseleaveHandler);
155
+ keycon.destroy();
163
156
  });
164
157
  </script>
@@ -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;
@@ -69,5 +69,11 @@
69
69
  .menu-item-text {
70
70
  color: $--nav-color;
71
71
  }
72
+
73
+ &.rule {
74
+ .el-icon {
75
+ transform: rotate(-90deg);
76
+ }
77
+ }
72
78
  }
73
79
  }
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
- left?: number;
87
- center?: number | 'auto';
88
- right?: number;
92
+ [ColumnLayout.LEFT]?: number;
93
+ [ColumnLayout.CENTER]?: number | 'auto';
94
+ [ColumnLayout.RIGHT]?: number;
89
95
  }
90
96
 
91
97
  export interface GetColumnWidth {
92
- left: number;
93
- center: number;
94
- right: number;
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
- left?: MenuItem[];
226
+ [ColumnLayout.LEFT]?: MenuItem[];
218
227
  /** 顶部工具栏中间项 */
219
- center?: MenuItem[];
228
+ [ColumnLayout.CENTER]?: MenuItem[];
220
229
  /** 顶部工具栏右边项 */
221
- right?: MenuItem[];
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
+ }
@@ -20,3 +20,4 @@ export * from './config';
20
20
  export * from './props';
21
21
  export * from './logger';
22
22
  export * from './editor';
23
+ export * from './stage';