| import type { Ref } from 'vue' | |
| import { useSlidesStore } from '@/store' | |
| import type { PPTElement, PPTShapeElement } from '@/types/slides' | |
| import useHistorySnapshot from '@/hooks/useHistorySnapshot' | |
| import { SHAPE_PATH_FORMULAS } from '@/configs/shapes' | |
| interface ShapePathData { | |
| baseSize: number, | |
| originPos: number, | |
| min: number, | |
| max: number, | |
| relative: string, | |
| } | |
| export default ( | |
| elementList: Ref<PPTElement[]>, | |
| canvasScale: Ref<number>, | |
| ) => { | |
| const slidesStore = useSlidesStore() | |
| const { addHistorySnapshot } = useHistorySnapshot() | |
| const moveShapeKeypoint = (e: MouseEvent | TouchEvent, element: PPTShapeElement, index = 0) => { | |
| const isTouchEvent = !(e instanceof MouseEvent) | |
| if (isTouchEvent && (!e.changedTouches || !e.changedTouches[0])) return | |
| let isMouseDown = true | |
| const startPageX = isTouchEvent ? e.changedTouches[0].pageX : e.pageX | |
| const startPageY = isTouchEvent ? e.changedTouches[0].pageY : e.pageY | |
| const originKeypoints = element.keypoints! | |
| const pathFormula = SHAPE_PATH_FORMULAS[element.pathFormula!] | |
| let shapePathData: ShapePathData | null = null | |
| if ('editable' in pathFormula && pathFormula.editable) { | |
| const getBaseSize = pathFormula.getBaseSize![index] | |
| const range = pathFormula.range![index] | |
| const relative = pathFormula.relative![index] | |
| const keypoint = originKeypoints[index] | |
| const baseSize = getBaseSize(element.width, element.height) | |
| const originPos = baseSize * keypoint | |
| const [min, max] = range | |
| shapePathData = { baseSize, originPos, min, max, relative } | |
| } | |
| const handleMousemove = (e: MouseEvent | TouchEvent) => { | |
| if (!isMouseDown) return | |
| const currentPageX = e instanceof MouseEvent ? e.pageX : e.changedTouches[0].pageX | |
| const currentPageY = e instanceof MouseEvent ? e.pageY : e.changedTouches[0].pageY | |
| const moveX = (currentPageX - startPageX) / canvasScale.value | |
| const moveY = (currentPageY - startPageY) / canvasScale.value | |
| elementList.value = elementList.value.map(el => { | |
| if (el.id === element.id && shapePathData) { | |
| const { baseSize, originPos, min, max, relative } = shapePathData | |
| const shapeElement = el as PPTShapeElement | |
| let keypoint = 0 | |
| if (relative === 'center') keypoint = (originPos - moveX * 2) / baseSize | |
| else if (relative === 'left') keypoint = (originPos + moveX) / baseSize | |
| else if (relative === 'right') keypoint = (originPos - moveX) / baseSize | |
| else if (relative === 'top') keypoint = (originPos + moveY) / baseSize | |
| else if (relative === 'bottom') keypoint = (originPos - moveY) / baseSize | |
| else if (relative === 'left_bottom') keypoint = (originPos + moveX) / baseSize | |
| else if (relative === 'right_bottom') keypoint = (originPos - moveX) / baseSize | |
| else if (relative === 'top_right') keypoint = (originPos + moveY) / baseSize | |
| else if (relative === 'bottom_right') keypoint = (originPos - moveY) / baseSize | |
| if (keypoint < min) keypoint = min | |
| if (keypoint > max) keypoint = max | |
| let keypoints: number[] = [] | |
| if (Array.isArray(originKeypoints)) { | |
| keypoints = [...originKeypoints] | |
| keypoints[index] = keypoint | |
| } | |
| else keypoints = [keypoint] | |
| return { | |
| ...el, | |
| keypoints, | |
| path: pathFormula.formula(shapeElement.width, shapeElement.height, keypoints), | |
| } | |
| } | |
| return el | |
| }) | |
| } | |
| const handleMouseup = (e: MouseEvent | TouchEvent) => { | |
| isMouseDown = false | |
| document.ontouchmove = null | |
| document.ontouchend = null | |
| document.onmousemove = null | |
| document.onmouseup = null | |
| const currentPageX = e instanceof MouseEvent ? e.pageX : e.changedTouches[0].pageX | |
| const currentPageY = e instanceof MouseEvent ? e.pageY : e.changedTouches[0].pageY | |
| if (startPageX === currentPageX && startPageY === currentPageY) return | |
| slidesStore.updateSlide({ elements: elementList.value }) | |
| addHistorySnapshot() | |
| } | |
| if (isTouchEvent) { | |
| document.ontouchmove = handleMousemove | |
| document.ontouchend = handleMouseup | |
| } | |
| else { | |
| document.onmousemove = handleMousemove | |
| document.onmouseup = handleMouseup | |
| } | |
| } | |
| return { | |
| moveShapeKeypoint, | |
| } | |
| } |