@zhangqingcq/vgce 0.0.20 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) 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 +13 -15
  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
@@ -1,368 +1,315 @@
1
- <script lang="ts">
1
+ <script lang="ts" setup>
2
2
  import { pinia } from '@/hooks'
3
3
  import { useSvgEditLayoutStore } from '@/stores/svg-edit-layout'
4
+ import { useConfigStore } from '@/stores/config'
4
5
 
5
- export default defineComponent({
6
- name: 'V3RulerComponent',
7
- props: {
8
- position: {
9
- type: String,
10
- default: 'relative',
11
- validator: (val: string) => {
12
- return ['absolute', 'fixed', 'relative', 'static', 'inherit'].indexOf(val) !== -1
13
- }
14
- }, // 规定元素的定位类型
15
- isHotKey: {
16
- type: Boolean,
17
- default: true
18
- }, // 热键开关
19
- isScaleRevise: {
20
- type: Boolean,
21
- default: false
22
- }, // 刻度修正(根据content进行刻度重置)
23
- value: {
24
- type: Array,
25
- default: () => {
26
- return [
27
- {
28
- type: 'h',
29
- site: 50
30
- },
31
- {
32
- type: 'v',
33
- site: 180
34
- }
35
- ] //
36
- }
37
- }, // 预置参考线
38
- contentLayout: {
39
- type: Object,
40
- default: () => {
41
- return {
42
- top: 0,
43
- left: 0
44
- }
45
- }
46
- }, // 内容部分布局
47
- parent: {
48
- type: Boolean,
49
- default: false
50
- },
51
- visible: {
52
- type: Boolean,
53
- default: true
54
- },
55
- stepLength: {
56
- type: Number,
57
- default: 50,
58
- validator: (val: number) => val % 10 === 0
59
- } // 步长
60
- },
61
- emits: ['input', 'update:visible'],
62
- setup(props, context) {
63
- const svgEditLayoutStore = useSvgEditLayoutStore(pinia)
64
- /**
65
- * @description 绑定事件 on(element, event, handler)
66
- */
67
- const on = (function () {
68
- return function (element: any, event: any, handler: any) {
69
- if (element && event && handler) {
70
- element.addEventListener(event, handler, false)
71
- }
72
- }
73
- })()
74
-
75
- /**
76
- * @description 解绑事件 off(element, event, handler)
77
- */
78
- const off = (function () {
79
- return function (element: any, event: any, handler: any) {
80
- if (element && event) {
81
- element.removeEventListener(event, handler, false)
82
- }
83
- }
84
- })()
85
- const size = 17
86
- let left_top = 18 // 内容左上填充
87
- let windowWidth = ref(0) // 窗口宽度
88
- let windowHeight = ref(0) // 窗口高度
89
- let xScale = ref<[{ id: number }]>([{ id: 0 }]) // 水平刻度
90
- let yScale = ref<[{ id: number }]>([{ id: 0 }]) // 垂直刻度
91
- let topSpacing = 0 // 标尺与窗口上间距
92
- let leftSpacing = 0 // 标尺与窗口左间距
93
- let isDrag = ref(false)
94
- let dragFlag = '' // 拖动开始标记,可能值x(从水平标尺开始拖动);y(从垂直标尺开始拖动)
95
- let horizontalDottedLeft = ref(-999) // 水平虚线位置
96
- let verticalDottedTop = ref(-999) // 垂直虚线位置
97
- let rulerWidth = 0 // 垂直标尺的宽度
98
- let rulerHeight = 0 // 水平标尺的高度
99
- let dragLineId = '' // 被移动线的ID
100
- //ref
101
- const content = ref(null)
102
- const el = ref(null)
103
- const verticalRuler = ref(null)
104
- const horizontalRuler = ref(null)
105
- const wrapperStyle: any = computed(() => {
106
- return {
107
- width: windowWidth.value + 'px',
108
- height: windowHeight.value + 'px',
109
- position: props.position
110
- }
111
- })
112
- const contentStyle = computed(() => {
113
- return {
114
- left: props.contentLayout.left + 'px',
115
- top: props.contentLayout.top + 'px',
116
- padding: left_top + 'px 0px 0px ' + left_top + 'px'
117
- }
118
- })
119
- const lineList = computed(() => {
120
- let hCount = 0
121
- let vCount = 0
122
- return props.value.map((item: any) => {
123
- const isH = item.type === 'h'
124
- return {
125
- id: `${item.type}_${isH ? hCount++ : vCount++}`,
126
- type: item.type,
127
- title: item.site.toFixed(2) + 'px',
128
- [isH ? 'top' : 'left']: item.site / (props.stepLength / 50) + size
129
- }
130
- })
131
- })
132
-
133
- svgEditLayoutStore.$subscribe((mutation) => {
134
- if (mutation.storeId === 'svg-edit-layout-store') {
135
- window.setTimeout(init, 420)
136
- }
137
- })
6
+ const props = withDefaults(
7
+ defineProps<{
8
+ visible?: boolean
9
+ stepLength?: number // 步长
10
+ }>(),
11
+ {
12
+ visible: true,
13
+ stepLength: 100
14
+ }
15
+ )
138
16
 
139
- onMounted(() => {
140
- on(document, 'mousemove', dottedLineMove)
141
- on(document, 'mouseup', dottedLineUp)
142
- init()
143
- on(window, 'resize', windowResize)
144
- })
145
- onBeforeUnmount(() => {
146
- off(document, 'mousemove', dottedLineMove)
147
- off(document, 'mouseup', dottedLineUp)
148
- off(window, 'resize', windowResize)
149
- })
150
- //function
151
- const init = () => {
152
- box()
153
- scaleCalc()
17
+ const svgEditLayoutStore = useSvgEditLayoutStore(pinia)
18
+ const configStore = useConfigStore(pinia)
19
+ /**
20
+ * @description 绑定事件 on(element, event, handler)
21
+ */
22
+ const on = (function () {
23
+ return function (element: any, event: any, handler: any) {
24
+ if (element && event && handler) {
25
+ element.addEventListener(event, handler, false)
154
26
  }
27
+ }
28
+ })()
155
29
 
156
- const windowResize = () => {
157
- xScale.value = [{ id: 0 }]
158
- yScale.value = [{ id: 0 }]
159
- init()
30
+ /**
31
+ * @description 解绑事件 off(element, event, handler)
32
+ */
33
+ const off = (function () {
34
+ return function (element: any, event: any, handler: any) {
35
+ if (element && event) {
36
+ element.removeEventListener(event, handler, false)
160
37
  }
161
- const getLineStyle = ({ type, top, left }: any) => {
162
- return type === 'h' ? { top: top + 'px' } : { left: left + 'px' }
163
- }
164
- const handleDragLine = ({ type, id }: any) => {
165
- return type === 'h' ? dragHorizontalLine(id) : dragVerticalLine(id)
38
+ }
39
+ })()
40
+ let contentPadding = 18 // 内容左上填充
41
+ let windowWidth = ref(0) // 窗口宽度
42
+ let windowHeight = ref(0) // 窗口高度
43
+ let xScale = ref<Array<{ id: number }>>([]) // 水平刻度
44
+ let yScale = ref<Array<{ id: number }>>([]) // 垂直刻度
45
+ const lines = ref<any[]>([])
46
+ let isDrag = ref(false)
47
+ let dragFlag = '' // 拖动开始标记,可能值x(从水平标尺开始拖动);y(从垂直标尺开始拖动)
48
+ let horizontalDottedLeft = ref(-999) // 水平虚线位置
49
+ let verticalDottedTop = ref(-999) // 垂直虚线位置
50
+ let rulerWidth = 18 // 垂直标尺的宽度
51
+ let rulerHeight = 18 // 水平标尺的高度
52
+ let dragLineId = '' // 被移动线的ID
53
+ //ref
54
+ const content = ref(null)
55
+ const el = ref(null)
56
+ const verticalRuler = ref(null)
57
+ const horizontalRuler = ref(null)
58
+ const wrapperStyle: any = computed(() => ({
59
+ width: windowWidth.value + 'px',
60
+ height: windowHeight.value + 'px'
61
+ }))
62
+ const contentStyle = computed(() => ({
63
+ padding: contentPadding + 'px 0px 0px ' + contentPadding + 'px'
64
+ }))
65
+ const lineList = computed(() => {
66
+ let hCount = 0
67
+ let vCount = 0
68
+ return lines.value.map((item: any) => {
69
+ const isH = item.type === 'h'
70
+ return {
71
+ id: `${item.type}_${isH ? hCount++ : vCount++}`,
72
+ type: item.type,
73
+ title: item.site.toFixed(0) + 'px',
74
+ [isH ? 'top' : 'left']:
75
+ item.site * configStore.svg.scale +
76
+ contentPadding +
77
+ svgEditLayoutStore.center_offset[isH ? 'y' : 'x'] * configStore.svg.scale
166
78
  }
167
- //获取窗口宽与高
168
- const box = () => {
169
- if (props.isScaleRevise) {
170
- // 根据内容部分进行刻度修正
171
- const contentLeft = (content.value as any).offsetLeft
172
- const contentTop = (content.value as any).offsetTop
173
- getCalcRevise(xScale.value, contentLeft)
174
- getCalcRevise(yScale.value, contentTop)
175
- }
176
- if (props.parent) {
177
- const style = window.getComputedStyle((el.value as any).parentNode, null)
178
- windowWidth.value = parseInt(style.getPropertyValue('width'), 10)
179
- windowHeight.value = parseInt(style.getPropertyValue('height'), 10)
180
- } else {
181
- windowWidth.value = document.documentElement.clientWidth - leftSpacing
182
- windowHeight.value = document.documentElement.clientHeight - topSpacing
79
+ })
80
+ })
81
+
82
+ svgEditLayoutStore.$subscribe((m: any) => {
83
+ if (m.events?.target?.hasOwnProperty('left_nav') || m.events?.target?.hasOwnProperty('right_nav')) {
84
+ window.setTimeout(init, 420)
85
+ }
86
+ })
87
+
88
+ configStore.$subscribe((m: any) => {
89
+ if (m.events?.target?.hasOwnProperty('scale')) {
90
+ scaleCalc()
91
+ }
92
+ })
93
+ onMounted(() => {
94
+ on(document, 'mousemove', mouseMove)
95
+ on(document, 'mouseup', mouseUp)
96
+ init()
97
+ on(window, 'resize', windowResize)
98
+ })
99
+ onBeforeUnmount(() => {
100
+ off(document, 'mousemove', mouseMove)
101
+ off(document, 'mouseup', mouseUp)
102
+ off(window, 'resize', windowResize)
103
+ })
104
+ const init = () => {
105
+ box()
106
+ scaleCalc()
107
+ }
108
+
109
+ const windowResize = () => {
110
+ xScale.value = []
111
+ yScale.value = []
112
+ init()
113
+ }
114
+ const getLineStyle = ({ type, top, left }: any) => {
115
+ return type === 'h' ? { top: top + 'px' } : { left: left + 'px' }
116
+ }
117
+ const handleDragLine = ({ type, id }: any) => {
118
+ return type === 'h' ? dragHorizontalLine(id) : dragVerticalLine(id)
119
+ }
120
+ //获取窗口宽与高
121
+ const box = () => {
122
+ const style = window.getComputedStyle((el.value as any).parentNode, null)
123
+ windowWidth.value = parseInt(style.getPropertyValue('width'))
124
+ windowHeight.value = parseInt(style.getPropertyValue('height'))
125
+ rulerWidth = (verticalRuler.value as any).clientWidth
126
+ rulerHeight = (horizontalRuler.value as any).clientHeight
127
+ }
128
+ // 计算刻度
129
+ const scaleCalc = () => {
130
+ getCalc(xScale.value, windowWidth.value, svgEditLayoutStore.center_offset.x)
131
+ getCalc(yScale.value, windowHeight.value, svgEditLayoutStore.center_offset.y)
132
+ }
133
+
134
+ //获取刻度
135
+ const getCalc = (
136
+ array: {
137
+ id: number
138
+ }[],
139
+ length: number,
140
+ start: number
141
+ ) => {
142
+ if (array.length === 0) {
143
+ for (let i = 0; i < length; i += props.stepLength) {
144
+ if (i % props.stepLength === 0) {
145
+ array.push({ id: Number((i / configStore.svg.scale - start).toFixed(0)) })
183
146
  }
184
- rulerWidth = (verticalRuler.value as any).clientWidth
185
- rulerHeight = (horizontalRuler.value as any).clientHeight
186
- setSpacing()
187
- }
188
- const setSpacing = () => {
189
- topSpacing = (horizontalRuler.value as any).getBoundingClientRect().y //.offsetParent.offsetTop
190
- leftSpacing = (verticalRuler.value as any).getBoundingClientRect().x // .offsetParent.offsetLeft
191
- }
192
- // 计算刻度
193
- const scaleCalc = () => {
194
- getCalc(xScale.value, windowWidth.value)
195
- getCalc(yScale.value, windowHeight.value)
196
147
  }
148
+ } else {
149
+ array.forEach((e, i) => {
150
+ e.id = Number(((i * props.stepLength) / configStore.svg.scale - start).toFixed(0))
151
+ })
152
+ }
153
+ }
197
154
 
198
- //获取刻度
199
- const getCalc = (array: [{ id: number }], length: any) => {
200
- for (let i = 0; i < (length * props.stepLength) / 50; i += props.stepLength) {
201
- if (i % props.stepLength === 0 && i != 0) {
202
- array.push({ id: i })
203
- }
155
+ const mouseMove = (e: any) => {
156
+ //移动画布
157
+ scaleCalc()
158
+ dottedLineMove(e)
159
+ }
160
+ //虚线移动
161
+ const dottedLineMove = ($event: any) => {
162
+ if ($event.layerX === $event.x || $event.layerY === $event.y) {
163
+ return
164
+ }
165
+ switch (dragFlag) {
166
+ case 'x':
167
+ if (isDrag.value) {
168
+ verticalDottedTop.value = $event.layerY
204
169
  }
205
- // console.log(array, 225);
206
- }
207
- // 获取矫正刻度方法
208
- const getCalcRevise = (array: [{ id: number }], length: any) => {
209
- for (let i = 0; i < length; i += 1) {
210
- if (i % props.stepLength === 0 && i + props.stepLength <= length) {
211
- array.push({ id: i })
212
- }
170
+ break
171
+ case 'y':
172
+ if (isDrag.value) {
173
+ horizontalDottedLeft.value = $event.layerX
213
174
  }
214
- // console.log(array, 233);
215
- }
216
- //生成一个参考线
217
- const newLine = (val: any) => {
218
- isDrag.value = true
219
- dragFlag = val
220
- }
221
- //虚线移动
222
- const dottedLineMove = ($event: any) => {
223
- setSpacing()
224
- switch (dragFlag) {
225
- case 'x':
226
- if (isDrag.value) {
227
- verticalDottedTop.value = $event.pageY - topSpacing
228
- }
229
- break
230
- case 'y':
231
- if (isDrag.value) {
232
- horizontalDottedLeft.value = $event.pageX - leftSpacing
233
- }
234
- break
235
- case 'h':
236
- if (isDrag.value) {
237
- verticalDottedTop.value = $event.pageY - topSpacing
238
- }
239
- break
240
- case 'v':
241
- if (isDrag.value) {
242
- horizontalDottedLeft.value = $event.pageX - leftSpacing
243
- }
244
- break
245
- default:
246
- break
175
+ break
176
+ case 'h':
177
+ if (isDrag.value) {
178
+ verticalDottedTop.value = $event.layerY
247
179
  }
248
- }
249
- //虚线松开
250
- const dottedLineUp = ($event: any) => {
251
- setSpacing()
180
+ break
181
+ case 'v':
252
182
  if (isDrag.value) {
253
- isDrag.value = false
254
- const cloneList = JSON.parse(JSON.stringify(props.value))
255
- switch (dragFlag) {
256
- case 'x':
257
- cloneList.push({
258
- type: 'h',
259
- site: ($event.pageY - topSpacing - size) * (props.stepLength / 50)
260
- })
261
- context.emit('input', cloneList)
262
- break
263
- case 'y':
264
- cloneList.push({
265
- type: 'v',
266
- site: ($event.pageX - leftSpacing - size) * (props.stepLength / 50)
267
- })
268
- context.emit('input', cloneList)
269
- break
270
- case 'h':
271
- dragCalc(cloneList, $event.pageY, topSpacing, rulerHeight, 'h')
272
- context.emit('input', cloneList)
273
- break
274
- case 'v':
275
- dragCalc(cloneList, $event.pageX, leftSpacing, rulerWidth, 'v')
276
- context.emit('input', cloneList)
277
- break
278
- default:
279
- break
280
- }
281
- verticalDottedTop.value = horizontalDottedLeft.value = -10
183
+ horizontalDottedLeft.value = $event.layerX
282
184
  }
283
- }
284
- const dragCalc = (list: any, page: any, spacing: any, ruler: any, type: any) => {
285
- if (page - spacing < ruler) {
286
- let Index
287
- lineList.value.forEach((item: any, index: any) => {
288
- if (item.id === dragLineId) {
289
- Index = index
290
- }
291
- })
292
- list.splice(Index, 1, {
293
- type: type,
294
- site: -600
295
- })
296
- } else {
297
- let Index
298
- lineList.value.forEach((item, index) => {
299
- if (item.id === dragLineId) {
300
- Index = index
301
- }
185
+ break
186
+ default:
187
+ break
188
+ }
189
+ }
190
+ //生成一个参考线
191
+ const newLine = (val: any) => {
192
+ isDrag.value = true
193
+ dragFlag = val
194
+ }
195
+ const mouseUp = (e: any) => {
196
+ dottedLineUp(e)
197
+ }
198
+ //虚线松开
199
+ const dottedLineUp = ($event: any) => {
200
+ if (isDrag.value) {
201
+ isDrag.value = false
202
+ switch (dragFlag) {
203
+ case 'x':
204
+ const x = Math.round(
205
+ ($event.layerY - contentPadding) / configStore.svg.scale - svgEditLayoutStore.center_offset.y
206
+ )
207
+ if (x <= 0) {
208
+ verticalDottedTop.value = -999
209
+ return
210
+ }
211
+ lines.value.push({
212
+ type: 'h',
213
+ site: x
302
214
  })
303
- list.splice(Index, 1, {
304
- type: type,
305
- site: (page - spacing - size) * (props.stepLength / 50)
215
+ break
216
+ case 'y':
217
+ const y = Math.round(
218
+ ($event.layerX - contentPadding) / configStore.svg.scale - svgEditLayoutStore.center_offset.x
219
+ )
220
+ if (y <= 0) {
221
+ horizontalDottedLeft.value = -999
222
+ return
223
+ }
224
+ lines.value.push({
225
+ type: 'v',
226
+ site: y
306
227
  })
307
- }
308
- }
309
- //水平标尺按下鼠标
310
- const horizontalDragRuler = () => {
311
- newLine('x')
312
- }
313
- //垂直标尺按下鼠标
314
- const verticalDragRuler = () => {
315
- newLine('y')
316
- }
317
- // 水平线处按下鼠标
318
- const dragHorizontalLine = (id: any) => {
319
- isDrag.value = true
320
- dragFlag = 'h'
321
- dragLineId = id
322
- }
323
- // 垂直线处按下鼠标
324
- const dragVerticalLine = (id: any) => {
325
- isDrag.value = true
326
- dragFlag = 'v'
327
- dragLineId = id
328
- }
329
- return {
330
- wrapperStyle,
331
- horizontalDragRuler,
332
- xScale,
333
- verticalDragRuler,
334
- yScale,
335
- verticalDottedTop,
336
- horizontalDottedLeft,
337
- lineList,
338
- getLineStyle,
339
- handleDragLine,
340
- contentStyle,
341
- isDrag,
342
- content,
343
- el,
344
- verticalRuler,
345
- horizontalRuler
228
+ break
229
+ case 'h':
230
+ dragCalc(
231
+ lines.value,
232
+ Math.round(($event.layerY - contentPadding) / configStore.svg.scale - svgEditLayoutStore.center_offset.y),
233
+ Math.round(rulerHeight / configStore.svg.scale - svgEditLayoutStore.center_offset.y),
234
+ 'h'
235
+ )
236
+ break
237
+ case 'v':
238
+ dragCalc(
239
+ lines.value,
240
+ Math.round(($event.layerX - contentPadding) / configStore.svg.scale - svgEditLayoutStore.center_offset.x),
241
+ Math.round(rulerWidth / configStore.svg.scale - svgEditLayoutStore.center_offset.x),
242
+ 'v'
243
+ )
244
+ break
245
+ default:
246
+ break
346
247
  }
248
+
249
+ verticalDottedTop.value = horizontalDottedLeft.value = -999
347
250
  }
348
- })
251
+ }
252
+ const dragCalc = (list: any, page: any, ruler: any, type: any) => {
253
+ if (page < ruler) {
254
+ let Index
255
+ lineList.value.forEach((item: any, index: any) => {
256
+ if (item.id === dragLineId) {
257
+ Index = index
258
+ }
259
+ })
260
+ list.splice(Index, 1)
261
+ } else {
262
+ let Index
263
+ lineList.value.forEach((item, index) => {
264
+ if (item.id === dragLineId) {
265
+ Index = index
266
+ }
267
+ })
268
+ list.splice(Index, 1, {
269
+ type: type,
270
+ site: page
271
+ })
272
+ }
273
+ }
274
+ //水平标尺按下鼠标
275
+ const horizontalDragRuler = () => {
276
+ newLine('x')
277
+ }
278
+ //垂直标尺按下鼠标
279
+ const verticalDragRuler = () => {
280
+ newLine('y')
281
+ }
282
+ // 水平线处按下鼠标
283
+ const dragHorizontalLine = (id: any) => {
284
+ isDrag.value = true
285
+ dragFlag = 'h'
286
+ dragLineId = id
287
+ }
288
+ // 垂直线处按下鼠标
289
+ const dragVerticalLine = (id: any) => {
290
+ isDrag.value = true
291
+ dragFlag = 'v'
292
+ dragLineId = id
293
+ }
349
294
  </script>
350
295
 
351
296
  <template>
352
297
  <div :style="wrapperStyle" class="vue-ruler-wrapper" onselectStart="return false;" ref="el">
353
- <section v-show="$props.visible">
298
+ <section v-show="props.visible">
354
299
  <div ref="horizontalRuler" class="vue-ruler-h" @mousedown.stop="horizontalDragRuler">
355
- <span v-for="(item, index) in xScale" :key="index" :style="{ left: index * 50 + 2 + 'px' }" class="n">{{
300
+ <span v-for="(item, index) in xScale" :style="{ left: index * stepLength + 'px' }" class="n">{{
356
301
  item.id
357
302
  }}</span>
358
303
  </div>
359
304
  <div ref="verticalRuler" class="vue-ruler-v" @mousedown.stop="verticalDragRuler">
360
- <span v-for="(item, index) in yScale" :key="index" :style="{ top: index * 50 + 2 + 'px' }" class="n">{{
361
- item.id
362
- }}</span>
305
+ <span v-for="(item, index) in yScale" :style="{ top: index * stepLength + 'px' }" class="n">{{ item.id }}</span>
363
306
  </div>
364
- <div :style="{ top: verticalDottedTop + 'px' }" class="vue-ruler-ref-dot-h" />
365
- <div :style="{ left: horizontalDottedLeft + 'px' }" class="vue-ruler-ref-dot-v" />
307
+ <div :style="{ top: verticalDottedTop + 'px' }" class="vue-ruler-ref-dot-h"
308
+ ><span>{{ Math.round((verticalDottedTop - rulerHeight) / configStore.svg.scale) }}</span></div
309
+ >
310
+ <div :style="{ left: horizontalDottedLeft + 'px' }" class="vue-ruler-ref-dot-v"
311
+ ><span>{{ Math.round((horizontalDottedLeft - rulerWidth) / configStore.svg.scale) }}</span></div
312
+ >
366
313
  <div
367
314
  v-for="item in lineList"
368
315
  :title="item.title"
@@ -370,7 +317,7 @@
370
317
  :key="item.id"
371
318
  :class="`vue-ruler-ref-line-${item.type}`"
372
319
  @mousedown="handleDragLine(item)"
373
- ></div>
320
+ />
374
321
  </section>
375
322
  <div ref="content" class="vue-ruler-content" :style="contentStyle">
376
323
  <slot />
@@ -385,6 +332,7 @@
385
332
  top: 0;
386
333
  z-index: 999;
387
334
  user-select: none;
335
+ position: relative;
388
336
  }
389
337
 
390
338
  .vue-ruler-h,
@@ -396,28 +344,25 @@
396
344
  position: absolute;
397
345
  left: 0;
398
346
  top: 0;
399
- overflow: hidden;
400
347
  z-index: 999;
401
348
  }
402
349
 
350
+ .vue-ruler-h,
351
+ .vue-ruler-v {
352
+ opacity: 0.6;
353
+ background-color: rgba(0, 0, 0, 0.04);
354
+ }
355
+
403
356
  .vue-ruler-h {
404
357
  width: calc(100% - 18px);
405
358
  height: 18px;
406
359
  left: 18px;
407
- opacity: 0.6;
408
- background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAASCAMAAAAuTX21AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAlQTFRFMzMzAAAA////BqjYlAAAACNJREFUeNpiYCAdMDKRCka1jGoBA2JZZGshiaCXFpIBQIABAAplBkCmQpujAAAAAElFTkSuQmCC)
409
- repeat-x;
410
- /*./image/ruler_h.png*/
411
360
  }
412
361
 
413
362
  .vue-ruler-v {
414
363
  width: 18px;
415
364
  height: calc(100% - 18px);
416
365
  top: 18px;
417
- opacity: 0.6;
418
- background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAyCAMAAABmvHtTAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAlQTFRFMzMzAAAA////BqjYlAAAACBJREFUeNpiYGBEBwwMTGiAakI0NX7U9aOuHyGuBwgwAH6bBkAR6jkzAAAAAElFTkSuQmCC)
419
- repeat-y;
420
- /*./image/ruler_v.png*/
421
366
  }
422
367
 
423
368
  .vue-ruler-v .n,
@@ -429,12 +374,22 @@
429
374
  color: #333;
430
375
  cursor: default;
431
376
  top: 1px;
377
+ box-sizing: border-box;
378
+ }
379
+
380
+ .vue-ruler-h .n {
381
+ border-left: 1px solid #856b01;
382
+ padding-left: 3px;
383
+ height: 100%;
384
+ padding-top: 3px;
432
385
  }
433
386
 
434
387
  .vue-ruler-v .n {
435
- width: 8px;
436
- left: 3px;
437
- word-wrap: break-word;
388
+ width: 100%;
389
+ writing-mode: vertical-rl;
390
+ border-top: 1px solid #856b01;
391
+ padding-top: 3px;
392
+ padding-right: 3px;
438
393
  }
439
394
 
440
395
  .vue-ruler-ref-line-v,
@@ -446,46 +401,48 @@
446
401
 
447
402
  .vue-ruler-ref-line-h {
448
403
  width: 100%;
449
- height: 3px;
450
- background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAABCAMAAADU3h9xAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRFSv//AAAAH8VRuAAAAA5JREFUeNpiYIACgAADAAAJAAE0lmO3AAAAAElFTkSuQmCC)
451
- repeat-x left center;
452
- /*./image/line_h.png*/
453
- cursor: n-resize;
454
- /*url(./image/cur_move_h.cur), move*/
404
+ height: 4px;
405
+ border-top: 1px solid #ff4101;
406
+ cursor: s-resize;
455
407
  }
456
408
 
457
409
  .vue-ruler-ref-line-v {
458
- width: 3px;
410
+ width: 4px;
459
411
  height: 100%;
460
- _height: 9999px;
461
- background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAICAMAAAAPxGVzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRFSv//AAAAH8VRuAAAAA5JREFUeNpiYEAFAAEGAAAQAAGePof9AAAAAElFTkSuQmCC)
462
- repeat-y center top;
463
- /*./image/line_v.png*/
412
+ border-left: 1px solid #ff4101;
464
413
  cursor: w-resize;
465
- /*url(./image/cur_move_v.cur), move*/
414
+ }
415
+
416
+ .vue-ruler-ref-dot-h,
417
+ .vue-ruler-ref-dot-v {
418
+ span {
419
+ position: absolute;
420
+ font-size: 12px;
421
+ color: #856b01;
422
+ }
466
423
  }
467
424
 
468
425
  .vue-ruler-ref-dot-h {
469
426
  width: 100%;
470
- height: 3px;
471
- background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAMAAABFaP0WAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRFf39/////F3PnHQAAAAJ0Uk5T/wDltzBKAAAAEElEQVR42mJgYGRgZAQIMAAADQAExkizYQAAAABJRU5ErkJggg==)
472
- repeat-x left 1px;
473
- /*./image/line_dot.png*/
427
+ height: 4px;
474
428
  cursor: n-resize;
475
- /*url(./image/cur_move_h.cur), move*/
476
- top: -10px;
429
+ border-top: 1px dashed #999;
430
+ span {
431
+ left: 30px;
432
+ top: 3px;
433
+ }
477
434
  }
478
435
 
479
436
  .vue-ruler-ref-dot-v {
480
- width: 3px;
437
+ width: 4px;
481
438
  height: 100%;
482
439
  _height: 9999px;
483
- background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAMAAABFaP0WAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRFf39/////F3PnHQAAAAJ0Uk5T/wDltzBKAAAAEElEQVR42mJgYGRgZAQIMAAADQAExkizYQAAAABJRU5ErkJggg==)
484
- repeat-y 1px top;
485
- /*./image/line_dot.png*/
486
440
  cursor: w-resize;
487
- /*url(./image/cur_move_v.cur), move*/
488
- left: -10px;
441
+ border-left: 1px dashed #999;
442
+ span {
443
+ top: 30px;
444
+ left: 7px;
445
+ }
489
446
  }
490
447
 
491
448
  .vue-ruler-content {