提交代码

This commit is contained in:
guanj
2025-09-25 11:34:55 +08:00
commit 448b8df85b
188 changed files with 21433 additions and 0 deletions

View 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>