提交代码
This commit is contained in:
196
src/components/mt-edit/components/draw-line-render/index.vue
Normal file
196
src/components/mt-edit/components/draw-line-render/index.vue
Normal file
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<svg
|
||||
:id="lineRenderProps.itemJson.id"
|
||||
class="mt-line-render"
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
left: `${-offset}px`,
|
||||
top: `${-offset}px`,
|
||||
width: `${lineRenderProps.canvasCfg.width + offset}px`,
|
||||
height: `${lineRenderProps.canvasCfg.height + offset}px`
|
||||
}"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
pointer-events="none"
|
||||
>
|
||||
<g>
|
||||
<defs>
|
||||
<marker
|
||||
:id="'markerArrowStart' + lineRenderProps.itemJson.id"
|
||||
viewBox="0 0 10 10"
|
||||
refX="8"
|
||||
refY="5"
|
||||
markerWidth="6"
|
||||
markerHeight="6"
|
||||
orient="auto-start-reverse"
|
||||
>
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" :fill="lineRenderProps.itemJson.props.stroke.val" />
|
||||
</marker>
|
||||
<marker
|
||||
:id="'markerArrowEnd' + lineRenderProps.itemJson.id"
|
||||
viewBox="0 0 10 10"
|
||||
refX="8"
|
||||
refY="5"
|
||||
markerWidth="6"
|
||||
markerHeight="6"
|
||||
orient="auto"
|
||||
>
|
||||
<path d="M 0 0 L 10 5 L 0 10 z" :fill="lineRenderProps.itemJson.props.stroke.val" />
|
||||
</marker>
|
||||
</defs>
|
||||
<path
|
||||
:d="
|
||||
positionArrarToPath(
|
||||
lineRenderProps.itemJson.props.point_position.val,
|
||||
lineRenderProps.itemJson.binfo.left + offset,
|
||||
lineRenderProps.itemJson.binfo.top + offset
|
||||
)
|
||||
"
|
||||
pointer-events="visibleStroke"
|
||||
fill="none"
|
||||
:stroke="
|
||||
lineRenderProps.itemJson.props.ani_type.val === 'electricity'
|
||||
? lineRenderProps.itemJson.props.ani_color.val
|
||||
: lineRenderProps.itemJson.props.stroke.val
|
||||
"
|
||||
:stroke-width="lineRenderProps.itemJson.props['stroke-width'].val"
|
||||
style="cursor: move"
|
||||
stroke-dashoffset="0"
|
||||
:stroke-dasharray="
|
||||
lineRenderProps.itemJson.props.ani_type.val === 'electricity'
|
||||
? lineRenderProps.itemJson.props['stroke-width'].val * 3
|
||||
: 0
|
||||
"
|
||||
:marker-start="
|
||||
lineRenderProps.itemJson.props?.['marker-start']?.val
|
||||
? `url(#markerArrowStart${lineRenderProps.itemJson.id})`
|
||||
: ''
|
||||
"
|
||||
:marker-end="
|
||||
lineRenderProps.itemJson.props?.['marker-end']?.val
|
||||
? `url(#markerArrowEnd${lineRenderProps.itemJson.id})`
|
||||
: ''
|
||||
"
|
||||
class="real"
|
||||
>
|
||||
<animate
|
||||
v-if="lineRenderProps.itemJson.props.ani_type.val === 'electricity'"
|
||||
attributeName="stroke-dashoffset"
|
||||
:from="lineRenderProps.itemJson.props.ani_reverse.val ? 0 : 1000"
|
||||
:to="
|
||||
lineRenderProps.itemJson.props.ani_reverse.val
|
||||
? lineRenderProps.itemJson.props.ani_play.val
|
||||
? 1000
|
||||
: 0
|
||||
: lineRenderProps.itemJson.props.ani_play.val
|
||||
? 0
|
||||
: 1000
|
||||
"
|
||||
:dur="`${
|
||||
lineRenderProps.itemJson.props.ani_dur.val < 1 ? 1 : lineRenderProps.itemJson.props.ani_dur.val
|
||||
}s`"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</path>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type { MouseTouchEvent } from '@/components/mt-dzr/utils/types'
|
||||
import type { IDoneJson, IGlobalStoreCanvasCfg, IGlobalStoreGridCfg } from '../../store/types'
|
||||
import { alignToGrid, positionArrarToPath } from '@/components/mt-edit/utils'
|
||||
import { computed } from 'vue'
|
||||
import { configStore } from '../../store/config'
|
||||
type LineRenderProps = {
|
||||
itemJson: IDoneJson
|
||||
canvasCfg: IGlobalStoreCanvasCfg
|
||||
grid: IGlobalStoreGridCfg
|
||||
canvasDom: HTMLElement | null
|
||||
mode: 'pen' | 'pencil'
|
||||
}
|
||||
const lineRenderProps = withDefaults(defineProps<LineRenderProps>(), {
|
||||
mode: 'pen'
|
||||
})
|
||||
const lineRenderEmits = defineEmits(['drawLineEnd'])
|
||||
const offset = configStore.lineRenderOffset
|
||||
//如果网格关闭或者没有开启网格对齐,网格大小为1
|
||||
const grid_align_size = computed(() =>
|
||||
!lineRenderProps.grid.align || !lineRenderProps.grid.enabled ? 1 : lineRenderProps.grid.size
|
||||
)
|
||||
const onMouseDown = (de: MouseTouchEvent, point_index: number, item: { x: number; y: number }) => {
|
||||
de.stopPropagation()
|
||||
// 记录鼠标按下时实际点的坐标
|
||||
const { x: realityX, y: realityY } = item
|
||||
// 记录最开始点击时鼠标位置
|
||||
const d_x = de instanceof MouseEvent ? de.clientX : de.touches[0].pageX
|
||||
const d_y = de instanceof MouseEvent ? de.clientY : de.touches[0].pageY
|
||||
let new_x = 0
|
||||
let new_y = 0
|
||||
const onMouseMove = (e: MouseTouchEvent) => {
|
||||
// 记录鼠标移动的位置
|
||||
const m_x = e instanceof MouseEvent ? e.clientX : e.touches[0].pageX
|
||||
const m_y = e instanceof MouseEvent ? e.clientY : e.touches[0].pageY
|
||||
// 移动的距离
|
||||
const move_x = de.ctrlKey ? 0 : alignToGrid((m_x - d_x) / lineRenderProps.canvasCfg.scale, 1) //感觉对齐网格有点体验不好 所以固定为一了
|
||||
const move_y = de.shiftKey ? 0 : alignToGrid((m_y - d_y) / lineRenderProps.canvasCfg.scale, 1)
|
||||
new_x = realityX + move_x
|
||||
new_y = realityY + move_y
|
||||
if (lineRenderProps.mode == 'pencil') {
|
||||
const new_point_position = lineRenderProps.itemJson.props.point_position.val
|
||||
new_point_position.push({
|
||||
x: new_x,
|
||||
y: new_y
|
||||
})
|
||||
return
|
||||
} else {
|
||||
const new_point_position = lineRenderProps.itemJson.props.point_position.val
|
||||
new_point_position[point_index].x = new_x
|
||||
new_point_position[point_index].y = new_y
|
||||
}
|
||||
}
|
||||
|
||||
const onMouseUp = () => {
|
||||
document.removeEventListener('mousemove', onMouseMove)
|
||||
document.removeEventListener('mouseup', onMouseUp)
|
||||
document.removeEventListener('touchmove', onMouseMove)
|
||||
document.removeEventListener('touchend', onMouseUp)
|
||||
const itemRect = document.querySelector(`#${lineRenderProps.itemJson.id} g .real`)!.getBoundingClientRect()
|
||||
const canvas_area_bounding_info = lineRenderProps.canvasDom!.getBoundingClientRect()
|
||||
const new_left = (itemRect?.left - canvas_area_bounding_info?.left) / lineRenderProps.canvasCfg.scale
|
||||
const new_top = (itemRect?.top - canvas_area_bounding_info?.top) / lineRenderProps.canvasCfg.scale
|
||||
const move_x = new_left - lineRenderProps.itemJson.binfo.left
|
||||
const move_y = new_top - lineRenderProps.itemJson.binfo.top
|
||||
const new_item_json = {
|
||||
...lineRenderProps.itemJson,
|
||||
binfo: {
|
||||
...lineRenderProps.itemJson.binfo,
|
||||
left: new_left,
|
||||
top: new_top,
|
||||
width: itemRect?.width / lineRenderProps.canvasCfg.scale,
|
||||
height: itemRect?.height / lineRenderProps.canvasCfg.scale
|
||||
},
|
||||
props: {
|
||||
...lineRenderProps.itemJson.props,
|
||||
point_position: {
|
||||
...lineRenderProps.itemJson.props.point_position,
|
||||
val: lineRenderProps.itemJson.props.point_position.val.map((m: { x: number; y: number }) => {
|
||||
return {
|
||||
x: m.x - move_x,
|
||||
y: m.y - move_y
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
lineRenderEmits('drawLineEnd', new_item_json)
|
||||
}
|
||||
document.addEventListener('mousemove', onMouseMove)
|
||||
document.addEventListener('mouseup', onMouseUp)
|
||||
document.addEventListener('touchmove', onMouseMove)
|
||||
document.addEventListener('touchend', onMouseUp)
|
||||
}
|
||||
defineExpose({
|
||||
onMouseDown
|
||||
})
|
||||
</script>
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user