@zhangqingcq/vgce 0.0.19 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. package/README.md +1 -1
  2. package/dist/style.css +2 -2
  3. package/dist/vgce.js +15857 -15275
  4. package/dist/vgce.umd.cjs +82 -129
  5. package/package.json +4 -6
  6. package/src/assets/base.less +79 -31
  7. package/src/assets/icons/delete-gray.svg +1 -0
  8. package/src/assets/icons/delete.svg +1 -12
  9. package/src/assets/icons/export.svg +1 -1
  10. package/src/assets/icons/import.svg +1 -1
  11. package/src/assets/icons/line-active.svg +1 -0
  12. package/src/assets/icons/line.svg +1 -0
  13. package/src/assets/icons/menu-fold.svg +1 -9
  14. package/src/assets/icons/menu-unfold.svg +1 -9
  15. package/src/assets/icons/preview.svg +1 -6
  16. package/src/assets/icons/question.svg +1 -0
  17. package/src/assets/icons/redo-gray.svg +1 -0
  18. package/src/assets/icons/redo.svg +1 -8
  19. package/src/assets/icons/return.svg +1 -8
  20. package/src/assets/icons/rotate.svg +1 -1
  21. package/src/assets/icons/save.svg +1 -9
  22. package/src/assets/icons/undo-gray.svg +1 -0
  23. package/src/assets/icons/undo.svg +1 -7
  24. package/src/assets/svgs/sheet-border.svg +1 -0
  25. package/src/assets/svgs/svg-text.svg +1 -5
  26. package/src/components/svg-analysis/index.vue +1 -1
  27. package/src/components/svg-editor/center-panel/index.vue +508 -176
  28. package/src/components/svg-editor/component-tree/index.vue +4 -0
  29. package/src/components/svg-editor/connection-line/index.vue +12 -8
  30. package/src/components/svg-editor/connection-panel/index.vue +121 -181
  31. package/src/components/svg-editor/handle-panel/index.vue +32 -24
  32. package/src/components/svg-editor/index.vue +15 -22
  33. package/src/components/svg-editor/left-panel/index.vue +2 -2
  34. package/src/components/svg-editor/right-panel/bind-anchor.vue +124 -0
  35. package/src/components/svg-editor/right-panel/code-edit-modal.vue +1 -1
  36. package/src/components/svg-editor/right-panel/dynamic-el-form-item.vue +8 -1
  37. package/src/components/svg-editor/right-panel/index.vue +117 -56
  38. package/src/components/svg-editor/top-panel/index.vue +109 -25
  39. package/src/components/svg-viewer/index.vue +31 -21
  40. package/src/components/vue3-ruler-tool/index.vue +329 -372
  41. package/src/config/files/clock-a.vue +64 -64
  42. package/src/config/svg/animation/index.ts +1 -1
  43. package/src/config/svg/custom/svg-text.ts +2 -2
  44. package/src/config/svg/stateful/index.ts +1 -1
  45. package/src/config/svg/stateless/index.ts +3 -2
  46. package/src/config/svg/stateless/sheet-border.ts +22 -0
  47. package/src/config/types.ts +1 -0
  48. package/src/stores/config/index.ts +1 -8
  49. package/src/stores/config/types.ts +0 -8
  50. package/src/stores/global/index.ts +0 -10
  51. package/src/stores/global/types.ts +33 -10
  52. package/src/stores/svg-edit-layout/index.ts +7 -0
  53. package/src/stores/svg-edit-layout/types.ts +1 -0
  54. package/src/utils/index.ts +227 -103
  55. package/src/utils/scale-core.ts +1 -0
  56. package/src/views/EditorS.vue +1 -1
  57. package/types/index.d.ts +4 -6
@@ -1,7 +1,14 @@
1
+ import type { ISystemStraightLine } from '@/components/config/types'
1
2
  import { ELineBindAnchors } from '@/components/config/types'
3
+ import type { ICondition, IConfigItem } from '@/config/types'
2
4
  import { EDoneJsonType } from '@/config/types'
3
- import type { IConfigItem } from '@/config/types'
4
- import type { IDoneJson } from '@/stores/global/types'
5
+ import type { ICoordinate, IDoneJson, IPointCoordinate } from '@/stores/global/types'
6
+ import { EGlobalStoreIntention, EMouseInfoState } from '@/stores/global/types'
7
+ import { straight_line_system } from '@/components/config'
8
+ import { useGlobalStore } from '@/stores/global'
9
+ import { pinia } from '@/hooks'
10
+ import { useConfigStore } from '@/stores/config'
11
+ import { useSvgEditLayoutStore } from '@/stores/svg-edit-layout'
5
12
 
6
13
  /**
7
14
  * 生成随机字符串
@@ -42,10 +49,10 @@ export const angleToRadian = (angle: number) => {
42
49
  }
43
50
  /**
44
51
  * 计算根据圆心旋转后的点的坐标
45
- * @param {Object} point 旋转前的点坐标
46
- * @param {Object} center 旋转中心
47
- * @param {Number} rotate 旋转的角度
48
- * @return {Object} 旋转后的坐标
52
+ * @param point 旋转前的点坐标
53
+ * @param center 旋转中心
54
+ * @param rotate 旋转的角度
55
+ * @return 旋转后的坐标
49
56
  * https://www.zhihu.com/question/67425734/answer/252724399 旋转矩阵公式
50
57
  */
51
58
  export const calculateRotatedPointCoordinate = (
@@ -64,14 +71,20 @@ export const calculateRotatedPointCoordinate = (
64
71
  */
65
72
 
66
73
  return {
67
- x:
68
- (point.x - center.x) * Math.cos(angleToRadian(rotate)) -
69
- (point.y - center.y) * Math.sin(angleToRadian(rotate)) +
70
- center.x,
71
- y:
72
- (point.x - center.x) * Math.sin(angleToRadian(rotate)) +
73
- (point.y - center.y) * Math.cos(angleToRadian(rotate)) +
74
- center.y
74
+ x: parseFloat(
75
+ (
76
+ (point.x - center.x) * Math.cos(angleToRadian(rotate)) -
77
+ (point.y - center.y) * Math.sin(angleToRadian(rotate)) +
78
+ center.x
79
+ ).toFixed(1)
80
+ ),
81
+ y: parseFloat(
82
+ (
83
+ (point.x - center.x) * Math.sin(angleToRadian(rotate)) +
84
+ (point.y - center.y) * Math.cos(angleToRadian(rotate)) +
85
+ center.y
86
+ ).toFixed(1)
87
+ )
75
88
  }
76
89
  }
77
90
  // 求两点之间的中点坐标
@@ -99,9 +112,9 @@ export const positionArrToPath = (position_arr: { x: number; y: number }[]) => {
99
112
  }
100
113
  /**
101
114
  * 获取相对于svg最新的坐标
102
- * @param init_pos 相对于页面的初始坐标
103
- * @param finally_pos 相对于页面的最终坐标
104
- * @param svg_init_pos 相对于svg的初始坐标
115
+ * @param init_pos 原中心坐标
116
+ * @param finally_pos 新中心坐标
117
+ * @param svg_init_pos 在画布中的的原坐标
105
118
  * @returns svg最新的坐标
106
119
  */
107
120
  export const getSvgNowPosition = (init_pos: number, finally_pos: number, svg_init_pos: number) => {
@@ -113,7 +126,7 @@ export const getSvgNowPosition = (init_pos: number, finally_pos: number, svg_ini
113
126
  * @param default_val
114
127
  * @returns
115
128
  */
116
- export const objectDeepClone = <T>(object: object, default_val: any = {}) => {
129
+ export const objectDeepClone = <T>(object: Record<keyof any, any>, default_val: any = {}) => {
117
130
  if (!object) {
118
131
  return default_val as T
119
132
  }
@@ -134,11 +147,10 @@ export const setSvgActualInfo = (done_json: IDoneJson, resize?: boolean) => {
134
147
  height = 0
135
148
  if (done_json.type !== EDoneJsonType.Vue) {
136
149
  const BBox = (queryBbox as SVGGraphicsElement).getBBox()
137
- console.log(BBox)
138
- x = BBox.x
139
- y = BBox.y
140
- width = BBox.width
141
- height = BBox.height
150
+ x = parseFloat(BBox.x.toFixed(0))
151
+ y = parseFloat(BBox.y.toFixed(0))
152
+ width = parseFloat(BBox.width.toFixed(0))
153
+ height = parseFloat(BBox.height.toFixed(0))
142
154
  } else {
143
155
  width = (queryBbox as HTMLElement).offsetWidth
144
156
  height = (queryBbox as HTMLElement).offsetHeight
@@ -187,41 +199,100 @@ export const setSvgActualInfo = (done_json: IDoneJson, resize?: boolean) => {
187
199
  height
188
200
  }
189
201
  }
202
+ done_json.center_position = {
203
+ x: done_json.x + done_json.actual_bound.x + width / 2,
204
+ y: done_json.y + done_json.actual_bound.y + height / 2
205
+ }
190
206
  done_json.point_coordinate.tl = {
191
- x: done_json.x - (width * done_json.scale_x) / 2,
192
- y: done_json.y - (height * done_json.scale_y) / 2
207
+ x: done_json.center_position.x - (width * done_json.scale_x) / 2,
208
+ y: done_json.center_position.y - (height * done_json.scale_y) / 2
193
209
  }
194
210
  done_json.point_coordinate.tc = {
195
- x: done_json.x,
196
- y: done_json.y - (height * done_json.scale_y) / 2
211
+ x: done_json.center_position.x,
212
+ y: done_json.center_position.y - (height * done_json.scale_y) / 2
197
213
  }
198
214
  done_json.point_coordinate.tr = {
199
- x: done_json.x + (width * done_json.scale_x) / 2,
200
- y: done_json.y - (height * done_json.scale_y) / 2
215
+ x: done_json.center_position.x + (width * done_json.scale_x) / 2,
216
+ y: done_json.center_position.y - (height * done_json.scale_y) / 2
201
217
  }
202
218
  done_json.point_coordinate.l = {
203
- x: done_json.x - (width * done_json.scale_x) / 2,
204
- y: done_json.y
219
+ x: done_json.center_position.x - (width * done_json.scale_x) / 2,
220
+ y: done_json.center_position.y
205
221
  }
206
222
  done_json.point_coordinate.r = {
207
- x: done_json.x + (width * done_json.scale_x) / 2,
208
- y: done_json.y
223
+ x: done_json.center_position.x + (width * done_json.scale_x) / 2,
224
+ y: done_json.center_position.y
209
225
  }
210
226
  done_json.point_coordinate.bl = {
211
- x: done_json.x - (width * done_json.scale_x) / 2,
212
- y: done_json.y + (height * done_json.scale_y) / 2
227
+ x: done_json.center_position.x - (width * done_json.scale_x) / 2,
228
+ y: done_json.center_position.y + (height * done_json.scale_y) / 2
213
229
  }
214
230
  done_json.point_coordinate.bc = {
215
- x: done_json.x,
216
- y: done_json.y + (height * done_json.scale_y) / 2
231
+ x: done_json.center_position.x,
232
+ y: done_json.center_position.y + (height * done_json.scale_y) / 2
217
233
  }
218
234
  done_json.point_coordinate.br = {
219
- x: done_json.x + (width * done_json.scale_x) / 2,
220
- y: done_json.y + (height * done_json.scale_y) / 2
235
+ x: done_json.center_position.x + (width * done_json.scale_x) / 2,
236
+ y: done_json.center_position.y + (height * done_json.scale_y) / 2
221
237
  }
222
238
  if (done_json.rotate !== 0) {
223
239
  setAfterRotationPointCoordinate(done_json)
224
240
  }
241
+ moveAnchors(done_json)
242
+ }
243
+ }
244
+ /**
245
+ * 重置旧八点坐标
246
+ * @param done_json
247
+ */
248
+ export const resetHandlePointOld = (done_json: IDoneJson) => {
249
+ for (const k of Object.keys(done_json.point_coordinate)) {
250
+ if (done_json.point_coordinate_old) {
251
+ done_json.point_coordinate_old[k as keyof IPointCoordinate].x = 0
252
+ done_json.point_coordinate_old[k as keyof IPointCoordinate].y = 0
253
+ }
254
+ }
255
+ }
256
+
257
+ /**
258
+ * 移动八点坐标
259
+ * @param done_json 当前组件
260
+ * @param x x轴移动量
261
+ * @param y y轴移动量
262
+ */
263
+ export const moveHandlePoint = (done_json: IDoneJson, x?: number, y?: number) => {
264
+ const globalStore = useGlobalStore(pinia)
265
+ const _x = x ?? globalStore.mouse_info.new_position_x - globalStore.mouse_info.position_x
266
+ const _y = y ?? globalStore.mouse_info.new_position_y - globalStore.mouse_info.position_y
267
+ for (const k of Object.keys(done_json.point_coordinate)) {
268
+ if (x !== undefined && y !== undefined) {
269
+ done_json.point_coordinate[k as keyof IPointCoordinate].x += _x
270
+ done_json.point_coordinate[k as keyof IPointCoordinate].y += _y
271
+ } else if (done_json.point_coordinate_old) {
272
+ done_json.point_coordinate[k as keyof IPointCoordinate].x =
273
+ done_json.point_coordinate_old[k as keyof IPointCoordinate].x + _x
274
+ done_json.point_coordinate[k as keyof IPointCoordinate].y =
275
+ done_json.point_coordinate_old[k as keyof IPointCoordinate].y + _y
276
+ }
277
+ }
278
+ }
279
+ /**
280
+ * 移动绑定锚点的线
281
+ * @param done_json
282
+ */
283
+ export const moveAnchors = (done_json: IDoneJson) => {
284
+ const globalStore = useGlobalStore(pinia)
285
+ for (let d of globalStore.done_json) {
286
+ if (d.type === EDoneJsonType.ConnectionLine) {
287
+ if (d.bind_anchors?.start?.target_id === done_json.id) {
288
+ const a = getAnchorPosByAnchorType(d.bind_anchors.start.type, done_json)
289
+ d.props.point_position.val[0] = { x: a.x - d.x, y: a.y - d.y }
290
+ }
291
+ if (d.bind_anchors?.end?.target_id === done_json.id) {
292
+ const a = getAnchorPosByAnchorType(d.bind_anchors.end.type, done_json)
293
+ d.props.point_position.val[d.props.point_position.val.length - 1] = { x: a.x - d.x, y: a.y - d.y }
294
+ }
295
+ }
225
296
  }
226
297
  }
227
298
  /**
@@ -247,70 +318,14 @@ export const getAnchorPosByAnchorType = (anchor_type: ELineBindAnchors, done_jso
247
318
  */
248
319
  export const setAfterRotationPointCoordinate = (item: IDoneJson) => {
249
320
  item.point_coordinate = {
250
- tl: calculateRotatedPointCoordinate(
251
- item.point_coordinate.tl,
252
- {
253
- x: item.x,
254
- y: item.y
255
- },
256
- item.rotate
257
- ),
258
- tc: calculateRotatedPointCoordinate(
259
- item.point_coordinate.tc,
260
- {
261
- x: item.x,
262
- y: item.y
263
- },
264
- item.rotate
265
- ),
266
- tr: calculateRotatedPointCoordinate(
267
- item.point_coordinate.tr,
268
- {
269
- x: item.x,
270
- y: item.y
271
- },
272
- item.rotate
273
- ),
274
- l: calculateRotatedPointCoordinate(
275
- item.point_coordinate.l,
276
- {
277
- x: item.x,
278
- y: item.y
279
- },
280
- item.rotate
281
- ),
282
- r: calculateRotatedPointCoordinate(
283
- item.point_coordinate.r,
284
- {
285
- x: item.x,
286
- y: item.y
287
- },
288
- item.rotate
289
- ),
290
- bl: calculateRotatedPointCoordinate(
291
- item.point_coordinate.bl,
292
- {
293
- x: item.x,
294
- y: item.y
295
- },
296
- item.rotate
297
- ),
298
- bc: calculateRotatedPointCoordinate(
299
- item.point_coordinate.bc,
300
- {
301
- x: item.x,
302
- y: item.y
303
- },
304
- item.rotate
305
- ),
306
- br: calculateRotatedPointCoordinate(
307
- item.point_coordinate.br,
308
- {
309
- x: item.x,
310
- y: item.y
311
- },
312
- item.rotate
313
- )
321
+ tl: calculateRotatedPointCoordinate(item.point_coordinate.tl, item.center_position, item.rotate),
322
+ tc: calculateRotatedPointCoordinate(item.point_coordinate.tc, item.center_position, item.rotate),
323
+ tr: calculateRotatedPointCoordinate(item.point_coordinate.tr, item.center_position, item.rotate),
324
+ l: calculateRotatedPointCoordinate(item.point_coordinate.l, item.center_position, item.rotate),
325
+ r: calculateRotatedPointCoordinate(item.point_coordinate.r, item.center_position, item.rotate),
326
+ bl: calculateRotatedPointCoordinate(item.point_coordinate.bl, item.center_position, item.rotate),
327
+ bc: calculateRotatedPointCoordinate(item.point_coordinate.bc, item.center_position, item.rotate),
328
+ br: calculateRotatedPointCoordinate(item.point_coordinate.br, item.center_position, item.rotate)
314
329
  }
315
330
  }
316
331
 
@@ -395,3 +410,112 @@ export const valFormat = (v: any) => {
395
410
  }
396
411
  return v
397
412
  }
413
+ /**
414
+ * 创建连线
415
+ * @param e 事件对象
416
+ * @param type 锚点位置
417
+ * @param itemInfo 被绑定组件
418
+ */
419
+ export const createLine = (e: MouseEvent, type?: ELineBindAnchors, itemInfo?: IDoneJson) => {
420
+ e.preventDefault()
421
+
422
+ const globalStore = useGlobalStore(pinia)
423
+ const configStore = useConfigStore(pinia)
424
+ const svgEditLayoutStore = useSvgEditLayoutStore(pinia)
425
+
426
+ const { clientX, clientY } = e
427
+ let create_line_info = objectDeepClone<ISystemStraightLine>(configStore.connection_line)
428
+ //以后顶部可以选择连线是哪种 直线先不做
429
+ /*if (false) {
430
+ create_line_info = straight_line_system
431
+ }*/
432
+ let x: number = 0
433
+ let y: number = 0
434
+ if (type && itemInfo) {
435
+ create_line_info.bind_anchors.start = {
436
+ type: type,
437
+ target_id: itemInfo.id
438
+ }
439
+ let t = getAnchorPosByAnchorType(type, itemInfo)
440
+ x = t.x
441
+ y = t.y
442
+ } else {
443
+ x = Math.round(
444
+ (clientX - svgEditLayoutStore.canvasInfo.left) / configStore.svg.scale - svgEditLayoutStore.center_offset.x
445
+ )
446
+ y = Math.round(
447
+ (clientY - svgEditLayoutStore.canvasInfo.top) / configStore.svg.scale - svgEditLayoutStore.center_offset.y
448
+ )
449
+ }
450
+ const done_item_json = {
451
+ id: straight_line_system.name + randomString(),
452
+ x: x,
453
+ y: y,
454
+ client: {
455
+ x: x,
456
+ y: y
457
+ },
458
+ scale_x: 1,
459
+ scale_y: 1,
460
+ rotate: 0,
461
+ actual_bound: {
462
+ x: 0,
463
+ y: 0,
464
+ width: 0,
465
+ height: 0
466
+ },
467
+ center_position: { x: 0, y: 0 },
468
+ point_coordinate: {
469
+ tl: {
470
+ x: 0,
471
+ y: 0
472
+ },
473
+ tc: {
474
+ x: 0,
475
+ y: 0
476
+ },
477
+ tr: {
478
+ x: 0,
479
+ y: 0
480
+ },
481
+ l: {
482
+ x: 0,
483
+ y: 0
484
+ },
485
+ r: {
486
+ x: 0,
487
+ y: 0
488
+ },
489
+ bl: {
490
+ x: 0,
491
+ y: 0
492
+ },
493
+ bc: {
494
+ x: 0,
495
+ y: 0
496
+ },
497
+ br: {
498
+ x: 0,
499
+ y: 0
500
+ }
501
+ },
502
+ ...create_line_info
503
+ }
504
+ done_item_json.props.point_position.val.push({
505
+ x: 0,
506
+ y: 0
507
+ })
508
+ globalStore.setDoneJson(done_item_json)
509
+ globalStore.setHandleSvgInfo(done_item_json, globalStore.done_json.length - 1)
510
+
511
+ globalStore.intention = EGlobalStoreIntention.Connection
512
+ globalStore.mouse_info = {
513
+ state: EMouseInfoState.Down,
514
+ position_x: x,
515
+ position_y: y,
516
+ now_position_x: x,
517
+ now_position_y: y,
518
+ new_position_x: 0,
519
+ new_position_y: 0
520
+ }
521
+ }
@@ -115,6 +115,7 @@ export const calculateTop = (
115
115
  * @param curPosition 按住的缩放按钮的坐标
116
116
  * @param symmetricPoint 缩放前对称点的坐标
117
117
  * @param rotate 旋转角度
118
+ * @param curPoint
118
119
  * @returns
119
120
  */
120
121
  export const calculateRight = (
@@ -13,5 +13,5 @@
13
13
  </script>
14
14
 
15
15
  <template>
16
- <SvgEditor :data="(store.data && JSON.stringify(store.data)) || ''" @onPreview="preview" />
16
+ <SvgEditor :data="(store.data && JSON.stringify(store.data)) || ''" @onPreview="preview" saveFile />
17
17
  </template>
package/types/index.d.ts CHANGED
@@ -4,19 +4,17 @@
4
4
  * @created 2023.07.10
5
5
  */
6
6
  import { DefineComponent } from 'vue'
7
- import type { IConfig } from '../src/config/types'
8
- import type { IDataModel } from '../src/components/svg-editor/types'
9
7
 
10
8
  export declare const SvgEditor: DefineComponent<{
11
9
  data?: string
12
- customToolbar?: IConfig
10
+ customToolbar?: any[]
13
11
  saveFile?: boolean
14
- onOnPreview?: (d: IDataModel) => void
15
- onOnSave?: (d: IDataModel) => void
12
+ onOnPreview?: (d: Record<string, any>) => void
13
+ onOnSave?: (d: Record<string, any>) => void
16
14
  onOnReturn?: () => void
17
15
  }>
18
16
  export declare const SvgViewer: DefineComponent<{
19
- data?: IDataModel
17
+ data?: Record<string, any>
20
18
  canvasDrag?: boolean
21
19
  onOnMessage?: (d: { topics: string, message: string }) => void
22
20
  }>