@zhangqingcq/vgce 0.0.23 → 0.0.25

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhangqingcq/vgce",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "description": "Vector graphics configure editor. svg组态编辑器。基于vue3.3+ts+element-plus+vite",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -1 +1 @@
1
- <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1686279304877" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12132" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M512 128c211.2 0 384 172.8 384 384s-172.8 384-384 384-384-172.8-384-384 172.8-384 384-384m0-64C262.4 64 64 262.4 64 512s198.4 448 448 448 448-198.4 448-448-198.4-448-448-448z" p-id="12133"></path><path d="M320 512m-32 0a32 32 0 1 0 64 0 32 32 0 1 0-64 0Z" p-id="12134"></path><path d="M704 512m-32 0a32 32 0 1 0 64 0 32 32 0 1 0-64 0Z" p-id="12135"></path><path d="M512 320m-32 0a32 32 0 1 0 64 0 32 32 0 1 0-64 0Z" p-id="12136"></path><path d="M512 704m-32 0a32 32 0 1 0 64 0 32 32 0 1 0-64 0Z" p-id="12137"></path><path d="M320 480h384v64H320z" p-id="12138"></path><path d="M480 320h64v384h-64z" p-id="12139"></path></svg>
1
+ <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1686279304877" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12132" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path class="icon-out" d="M512 128c211.2 0 384 172.8 384 384s-172.8 384-384 384-384-172.8-384-384 172.8-384 384-384m0-64C262.4 64 64 262.4 64 512s198.4 448 448 448 448-198.4 448-448-198.4-448-448-448z" p-id="12133"></path><path class="icon-in" d="M320 512m-32 0a32 32 0 1 0 64 0 32 32 0 1 0-64 0Z" p-id="12134"></path><path class="icon-in" d="M704 512m-32 0a32 32 0 1 0 64 0 32 32 0 1 0-64 0Z" p-id="12135"></path><path class="icon-in" d="M512 320m-32 0a32 32 0 1 0 64 0 32 32 0 1 0-64 0Z" p-id="12136"></path><path class="icon-in" d="M512 704m-32 0a32 32 0 1 0 64 0 32 32 0 1 0-64 0Z" p-id="12137"></path><path class="icon-in" d="M320 480h384v64H320z" p-id="12138"></path><path class="icon-in" d="M480 320h64v384h-64z" p-id="12139"></path></svg>
@@ -1089,20 +1089,20 @@
1089
1089
  />
1090
1090
  </g>
1091
1091
  </svg>
1092
- <!-- 右键菜单 -->
1093
- <ul ref="contextMenuRef" class="contextMenu" v-show="contextMenuStore.display">
1094
- <li
1095
- v-for="(item, key) in contextMenuStore.info"
1096
- :key="item.title"
1097
- @click="contextMenuStore.onContextMenuClick(key)"
1098
- >
1099
- <p :class="item.enable ? '' : 'disabled'">
1100
- {{ item.title }}
1101
- <span class="shortcut">{{ item.hot_key }}</span>
1102
- </p>
1103
- </li>
1104
- </ul>
1105
1092
  </div>
1093
+ <!-- 右键菜单 -->
1094
+ <ul ref="contextMenuRef" class="contextMenu" v-show="contextMenuStore.display">
1095
+ <li
1096
+ v-for="(item, key) in contextMenuStore.info"
1097
+ :key="item.title"
1098
+ @click="contextMenuStore.onContextMenuClick(key)"
1099
+ >
1100
+ <p :class="item.enable ? '' : 'disabled'">
1101
+ {{ item.title }}
1102
+ <span class="shortcut">{{ item.hot_key }}</span>
1103
+ </p>
1104
+ </li>
1105
+ </ul>
1106
1106
  </template>
1107
1107
 
1108
1108
  <style lang="less" scoped>
@@ -85,9 +85,24 @@
85
85
 
86
86
  const { appContext } = getCurrentInstance()!
87
87
 
88
+ function onReturnClick(d: IDataModel) {
89
+ emits('onReturn', {
90
+ data: d,
91
+ isChange: editPrivateStore.getTopBtnUndoStatus
92
+ })
93
+ }
94
+
88
95
  function save(d: IDataModel) {
89
96
  if (props.saveFile) {
90
- ElMessageBox.prompt('请输入文件名', '保存', { cancelButtonText: '取消', confirmButtonText: '保存' }, appContext)
97
+ ElMessageBox.prompt(
98
+ '请输入文件名',
99
+ '保存',
100
+ {
101
+ cancelButtonText: '取消',
102
+ confirmButtonText: '保存'
103
+ },
104
+ appContext
105
+ )
91
106
  .then((r: any) => {
92
107
  fileWrite(d, r.value.trim())
93
108
  emits('onSave', d)
@@ -110,7 +125,7 @@
110
125
  <el-header class="top-el-header">
111
126
  <top-panel
112
127
  @change-visible="changeVisible"
113
- @on-return="emits('onReturn')"
128
+ @on-return="onReturnClick"
114
129
  @on-preview="(val: IDataModel) => emits('onPreview', val)"
115
130
  @on-save="save"
116
131
  ></top-panel>
@@ -1,85 +1,85 @@
1
- <script setup lang="ts">
2
- import type { IAttrItem } from '@/config/types'
3
- import { ElIcon, ElInput } from 'element-plus'
4
- import SvgAnalysis from '@/components/svg-analysis/index.vue'
5
-
6
- const props = withDefaults(defineProps<{ modelValue: IAttrItem[] }>(), {
7
- modelValue: () => [
8
- {
9
- key: '',
10
- val: ''
11
- }
12
- ]
13
- })
14
- const emit = defineEmits(['update:modelValue'])
15
-
16
- const value = computed({
17
- get() {
18
- return props.modelValue
19
- },
20
- set(val) {
21
- emit('update:modelValue', val)
22
- }
23
- })
24
-
25
- const addL = () => {
26
- value.value.push({
27
- key: '',
28
- val: ''
29
- })
30
- }
31
-
32
- const deleteL = (i: number) => {
33
- value.value.splice(i, 1)
34
- }
35
- </script>
36
-
37
- <template>
38
- <div class="wall-l">
39
- <div class="head-l">
40
- <span>key</span>
41
- <span>value</span>
42
-
43
- <el-icon :size="16" class="bt-Icon" @click="addL">
44
- <svg-analysis name="add" />
45
- </el-icon>
46
- </div>
47
- <div class="row-l" v-for="(item, i) of value">
48
- <el-input class="content-l" v-model="item.key" size="small" placeholder="key" />
49
- <el-input class="content-l" v-model="item.val" size="small" placeholder="value" />
50
-
51
- <el-icon :size="16" class="bt-Icon" @click="deleteL(i)">
52
- <svg-analysis name="delete" />
53
- </el-icon>
54
- </div>
55
- </div>
56
- </template>
57
-
58
- <style lang="less" scoped>
59
- .wall-l {
60
- background-color: #f3f6f9;
61
- padding: 4px 5px 2px 5px;
62
- border-radius: 4px;
63
- .head-l {
64
- display: flex;
65
- align-items: center;
66
-
67
- span {
68
- display: inline-block;
69
- width: 42%;
70
- margin-right: 10px;
71
- color: #666;
72
- }
73
- }
74
-
75
- .row-l {
76
- display: flex;
77
- align-items: center;
78
- padding-bottom: 6px;
79
- .content-l {
80
- width: 42%;
81
- margin-right: 10px;
82
- }
83
- }
84
- }
85
- </style>
1
+ <script setup lang="ts">
2
+ import type { IAttrItem } from '@/config/types'
3
+ import { ElIcon, ElInput } from 'element-plus'
4
+ import SvgAnalysis from '@/components/svg-analysis/index.vue'
5
+
6
+ const props = withDefaults(defineProps<{ modelValue: IAttrItem[] }>(), {
7
+ modelValue: () => [
8
+ {
9
+ key: '',
10
+ val: ''
11
+ }
12
+ ]
13
+ })
14
+ const emit = defineEmits(['update:modelValue'])
15
+
16
+ const value = computed({
17
+ get() {
18
+ return props.modelValue
19
+ },
20
+ set(val) {
21
+ emit('update:modelValue', val)
22
+ }
23
+ })
24
+
25
+ const addL = () => {
26
+ value.value.push({
27
+ key: '',
28
+ val: ''
29
+ })
30
+ }
31
+
32
+ const deleteL = (i: number) => {
33
+ value.value.splice(i, 1)
34
+ }
35
+ </script>
36
+
37
+ <template>
38
+ <div class="wall-l">
39
+ <div class="head-l">
40
+ <span>key</span>
41
+ <span>value</span>
42
+
43
+ <el-icon :size="16" class="bt-Icon" @click="addL">
44
+ <svg-analysis name="add" />
45
+ </el-icon>
46
+ </div>
47
+ <div class="row-l" v-for="(item, i) of value">
48
+ <el-input class="content-l" v-model="item.key" size="small" placeholder="key" />
49
+ <el-input class="content-l" v-model="item.val" size="small" placeholder="value" />
50
+
51
+ <el-icon :size="16" class="bt-Icon" @click="deleteL(i)">
52
+ <svg-analysis name="delete" />
53
+ </el-icon>
54
+ </div>
55
+ </div>
56
+ </template>
57
+
58
+ <style lang="less" scoped>
59
+ .wall-l {
60
+ background-color: #f5f8fb;
61
+ padding: 4px 5px 2px 5px;
62
+ border-radius: 4px;
63
+ .head-l {
64
+ display: flex;
65
+ align-items: center;
66
+
67
+ span {
68
+ display: inline-block;
69
+ width: 42%;
70
+ margin-right: 10px;
71
+ color: #666;
72
+ }
73
+ }
74
+
75
+ .row-l {
76
+ display: flex;
77
+ align-items: center;
78
+ padding-bottom: 6px;
79
+ .content-l {
80
+ width: 42%;
81
+ margin-right: 10px;
82
+ }
83
+ }
84
+ }
85
+ </style>
@@ -9,8 +9,6 @@
9
9
  import { EVisibleConfKey } from '../types'
10
10
  import type { IDataModel } from '../types'
11
11
  import { EGlobalStoreIntention } from '@/stores/global/types'
12
- import { VAceEditor } from 'vue3-ace-editor'
13
- import LeftPanel from '@/components/svg-editor/left-panel/index.vue'
14
12
 
15
13
  const svgEditLayoutStore = useSvgEditLayoutStore(pinia)
16
14
  const globalStore = useGlobalStore(pinia)
@@ -21,21 +19,14 @@
21
19
  globalStore.done_json.length <= 0 || globalStore.setDoneJson([])
22
20
  globalStore.intention = EGlobalStoreIntention.None
23
21
  }
24
- const onPreviewClick = () => {
25
- const data_model: IDataModel = {
26
- layout_center: svgEditLayoutStore.center_offset,
27
- config: configStore.$state,
28
- done_json: globalStore.done_json
29
- }
30
- emits('onPreview', data_model)
31
- }
32
- const onSaveClick = () => {
22
+
23
+ const dataBtnClick = (d: 'onReturn' | 'onPreview' | 'onSave') => {
33
24
  const data_model: IDataModel = {
34
25
  layout_center: svgEditLayoutStore.center_offset,
35
26
  config: configStore.$state,
36
27
  done_json: globalStore.done_json
37
28
  }
38
- emits('onSave', data_model)
29
+ emits(d, data_model)
39
30
  }
40
31
 
41
32
  const open = ref(false)
@@ -137,15 +128,15 @@
137
128
  </el-icon> -->
138
129
  </div>
139
130
  <div class="flex items-center mr-20px">
140
- <el-icon title="返回" class="bt-Icon" :size="24" @click="emits('onReturn')">
131
+ <el-icon title="返回" class="bt-Icon" :size="24" @click="dataBtnClick('onReturn')">
141
132
  <svg-analysis name="return" />
142
133
  </el-icon>
143
134
  <el-divider direction="vertical"></el-divider>
144
- <el-icon title="保存" class="bt-Icon" :size="24" @click="onSaveClick">
135
+ <el-icon title="保存" class="bt-Icon" :size="24" @click="dataBtnClick('onSave')">
145
136
  <svg-analysis name="save" />
146
137
  </el-icon>
147
138
  <el-divider direction="vertical"></el-divider>
148
- <el-icon title="预览" class="bt-Icon" :size="22" @click="onPreviewClick">
139
+ <el-icon title="预览" class="bt-Icon" :size="22" @click="dataBtnClick('onPreview')">
149
140
  <svg-analysis name="preview" />
150
141
  </el-icon>
151
142
  </div>
@@ -166,24 +157,24 @@
166
157
  <el-scrollbar max-height="60vh">
167
158
  <div class="font-bold mb-10px text-15px guide-title" style="padding-top: 16px">多选</div>
168
159
  <div>鼠标按住左键可以框选,也可以按住ctrl+鼠标左键点图形进行多选</div>
169
- <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"> </div>
160
+ <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"></div>
170
161
  <div class="font-bold mb-10px text-15px guide-title">拖动画布</div>
171
162
  <div>右键画布然后拖动即可,右侧面板‘图纸’栏可微调或重置位置</div>
172
- <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"> </div>
163
+ <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"></div>
173
164
  <div class="font-bold mb-10px text-15px guide-title">画布缩放</div>
174
165
  <div>使用鼠标滚轮或者右侧面板‘图纸’栏可控制画布缩放</div>
175
- <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"> </div>
166
+ <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"></div>
176
167
  <div class="font-bold mb-10px text-15px guide-title">标尺辅助线</div>
177
168
  <div>在标尺区域按住鼠标左键并拖动即可创建标尺辅助线,将标尺辅助线拖动到标尺区域即可删除标尺辅助线</div>
178
- <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"> </div>
169
+ <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"></div>
179
170
  <div class="font-bold mb-10px text-15px guide-title">连线样式</div>
180
171
  <div
181
- >在右侧‘连线’栏可以统一配置连线样式,配置后先增加的线会应用新样式,之前的线样式不变,如需改变,可选中线手动更改或删除重画</div
182
- >
183
- <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"> </div>
172
+ >在右侧‘连线’栏可以统一配置连线样式,配置后先增加的线会应用新样式,之前的线样式不变,如需改变,可选中线手动更改或删除重画
173
+ </div>
174
+ <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"></div>
184
175
  <div class="font-bold mb-10px text-15px guide-title">横线和竖线</div>
185
176
  <div>画线的时候按住ctrl即可画竖线,按住shift即可画横线</div>
186
- <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"> </div>
177
+ <div class="el-divider el-divider--horizontal" role="separator" style="--el-border-style: solid"></div>
187
178
  <div class="font-bold mb-10px text-15px guide-title">线段选中</div>
188
179
  <div style="padding-bottom: 14px">
189
180
  若线段绑定了锚点,移动线段,绑定的锚点不会移动。若是想将线段整体移动,需要先选中线段,在右侧‘数据’栏里解除绑定
@@ -214,6 +205,7 @@
214
205
  margin-right: 0;
215
206
  padding-right: 16px;
216
207
  }
208
+
217
209
  .el-dialog__body {
218
210
  padding-top: 0;
219
211
  padding-bottom: 8px;
@@ -62,7 +62,6 @@
62
62
  return
63
63
  }
64
64
  if (!props.canvasDrag) {
65
- console.log(props.canvasDrag)
66
65
  return
67
66
  }
68
67
  const { clientX, clientY } = e
@@ -139,6 +138,19 @@
139
138
  const setNodeAttrByID = (id: string, attr: string, val: any) => {
140
139
  return setArrItemByID(id, attr, val, preview_data.done_json)
141
140
  }
141
+
142
+ const getStyle = (root: IDoneJson) => {
143
+ let t = false
144
+ if (root.events?.length > 0) {
145
+ for (let e of root.events) {
146
+ if (e.type === EEventType.Click) {
147
+ t = true
148
+ break
149
+ }
150
+ }
151
+ }
152
+ return { cursor: t ? 'pointer' : 'default' }
153
+ }
142
154
  const eventHandle = (root: IDoneJson) => {
143
155
  if (root.events?.length > 0) {
144
156
  for (let e of root.events) {
@@ -263,6 +275,7 @@
263
275
  :key="item.id"
264
276
  :transform="`translate(${item.x},${item.y})rotate(0)scale(1)`"
265
277
  v-show="item.display"
278
+ :style="getStyle(item)"
266
279
  @click="eventHandle(item)"
267
280
  >
268
281
  <g :class="`${getCommonClass(item)}`">
package/src/router.ts CHANGED
@@ -12,11 +12,6 @@ const router = createRouter({
12
12
  path: '/EditorS',
13
13
  name: 'EditorS',
14
14
  component: EditorS
15
- },
16
- {
17
- path: '/Preview',
18
- name: 'Preview',
19
- component: () => import('@/views/Preview.vue')
20
15
  }
21
16
  ]
22
17
  })
@@ -2,16 +2,20 @@
2
2
  import SvgEditor from '@/components/svg-editor/index.vue'
3
3
  import { useStore } from '@/stores/main'
4
4
  import type { IDataModel } from '@/components/svg-editor/types'
5
+ import Preview from './Preview.vue'
5
6
 
6
- const router = useRouter()
7
7
  const store = useStore()
8
8
 
9
- function preview(d: IDataModel) {
9
+ const previewShow = ref(false)
10
+ function previewHandle(d: IDataModel) {
10
11
  store.data = d
11
- router.push('/Preview')
12
+ nextTick(function () {
13
+ previewShow.value = true
14
+ })
12
15
  }
13
16
  </script>
14
17
 
15
18
  <template>
16
- <SvgEditor :data="(store.data && JSON.stringify(store.data)) || ''" @onPreview="preview" saveFile />
19
+ <SvgEditor :data="(store.data && JSON.stringify(store.data)) || ''" @onPreview="previewHandle" saveFile />
20
+ <Preview v-if="previewShow" @back="previewShow = false" />
17
21
  </template>
@@ -1,12 +1,38 @@
1
- <script setup lang="ts">
2
- import SvgViewer from '@/components/svg-viewer/index.vue'
3
- import { useStore } from '@/stores/main'
4
-
5
- const store = useStore()
6
- </script>
7
-
8
- <template>
9
- <svg-viewer :data="store.data" />
10
- </template>
11
-
12
- <style lang="less" scoped></style>
1
+ <script setup lang="ts">
2
+ import SvgViewer from '@/components/svg-viewer/index.vue'
3
+ import { ElButton } from 'element-plus'
4
+ import { ArrowLeftBold } from '@element-plus/icons-vue'
5
+ import { useStore } from '@/stores/main'
6
+
7
+ const emit = defineEmits(['back'])
8
+ const store = useStore()
9
+
10
+ function back() {
11
+ emit('back')
12
+ }
13
+ </script>
14
+
15
+ <template>
16
+ <div class="previewPage">
17
+ <svg-viewer :data="store.data" />
18
+ <el-button @click="back" class="backBtn" :icon="ArrowLeftBold">返回</el-button>
19
+ </div>
20
+ </template>
21
+
22
+ <style lang="less" scoped>
23
+ .previewPage {
24
+ position: fixed;
25
+ z-index: 1000;
26
+ left: 0;
27
+ right: 0;
28
+ top: 0;
29
+ bottom: 0;
30
+
31
+ .backBtn {
32
+ position: absolute;
33
+ top: 20px;
34
+ right: 30px;
35
+ z-index: 100;
36
+ }
37
+ }
38
+ </style>