File size: 3,264 Bytes
89ce340 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
import type { Ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore } from '@/store'
import type { CreateElementSelectionData } from '@/types/edit'
import useCreateElement from '@/hooks/useCreateElement'
export default (viewportRef: Ref<HTMLElement | undefined>) => {
const mainStore = useMainStore()
const { canvasScale, creatingElement } = storeToRefs(mainStore)
// 通过鼠标框选时的起点和终点,计算选区的位置大小
const formatCreateSelection = (selectionData: CreateElementSelectionData) => {
const { start, end } = selectionData
if (!viewportRef.value) return
const viewportRect = viewportRef.value.getBoundingClientRect()
const [startX, startY] = start
const [endX, endY] = end
const minX = Math.min(startX, endX)
const maxX = Math.max(startX, endX)
const minY = Math.min(startY, endY)
const maxY = Math.max(startY, endY)
const left = (minX - viewportRect.x) / canvasScale.value
const top = (minY - viewportRect.y) / canvasScale.value
const width = (maxX - minX) / canvasScale.value
const height = (maxY - minY) / canvasScale.value
return { left, top, width, height }
}
// 通过鼠标框选时的起点和终点,计算线条在画布中的位置和起点终点
const formatCreateSelectionForLine = (selectionData: CreateElementSelectionData) => {
const { start, end } = selectionData
if (!viewportRef.value) return
const viewportRect = viewportRef.value.getBoundingClientRect()
const [startX, startY] = start
const [endX, endY] = end
const minX = Math.min(startX, endX)
const maxX = Math.max(startX, endX)
const minY = Math.min(startY, endY)
const maxY = Math.max(startY, endY)
const left = (minX - viewportRect.x) / canvasScale.value
const top = (minY - viewportRect.y) / canvasScale.value
const width = (maxX - minX) / canvasScale.value
const height = (maxY - minY) / canvasScale.value
const _start: [number, number] = [
startX === minX ? 0 : width,
startY === minY ? 0 : height,
]
const _end: [number, number] = [
endX === minX ? 0 : width,
endY === minY ? 0 : height,
]
return {
left,
top,
start: _start,
end: _end,
}
}
const { createTextElement, createShapeElement, createLineElement } = useCreateElement()
// 根据鼠标选区的位置大小插入元素
const insertElementFromCreateSelection = (selectionData: CreateElementSelectionData) => {
if (!creatingElement.value) return
const type = creatingElement.value.type
if (type === 'text') {
const position = formatCreateSelection(selectionData)
position && createTextElement(position, { vertical: creatingElement.value.vertical })
}
else if (type === 'shape') {
const position = formatCreateSelection(selectionData)
position && createShapeElement(position, creatingElement.value.data)
}
else if (type === 'line') {
const position = formatCreateSelectionForLine(selectionData)
position && createLineElement(position, creatingElement.value.data)
}
mainStore.setCreatingElement(null)
}
return {
formatCreateSelection,
insertElementFromCreateSelection,
}
} |