pipipi-pikachu 5 лет назад
Родитель
Сommit
8fa35d4645

+ 0 - 1
src/store/constants.ts

@@ -4,7 +4,6 @@ export enum MutationTypes {
   SET_ACTIVE_ELEMENT_ID_LIST = 'setActiveElementIdList',
   SET_HANDLE_ELEMENT_ID = 'setHandleElementId',
   SET_EDITOR_AREA_SHOW_SCALE = 'setEditorAreaShowScale',
-  SET_CANVAS_SCALE = 'setCanvasScale',
   SET_THUMBNAILS_FOCUS = 'setThumbnailsFocus',
   SET_EDITORAREA_FOCUS = 'setEditorAreaFocus',
   SET_DISABLE_HOTKEYS_STATE = 'setDisableHotkeysState',

+ 0 - 2
src/store/index.ts

@@ -13,7 +13,6 @@ export interface State {
   activeElementIdList: string[];
   handleElementId: string;
   editorAreaShowScale: number;
-  canvasScale: number;
   thumbnailsFocus: boolean;
   editorAreaFocus: boolean;
   disableHotkeys: boolean;
@@ -30,7 +29,6 @@ const state: State = {
   activeElementIdList: [],
   handleElementId: '',
   editorAreaShowScale: 85,
-  canvasScale: 1,
   thumbnailsFocus: false,
   editorAreaFocus: false,
   disableHotkeys: false,

+ 0 - 4
src/store/mutations.ts

@@ -34,10 +34,6 @@ export const mutations: MutationTree<State> = {
     state.editorAreaShowScale = scale
   },
 
-  [MutationTypes.SET_CANVAS_SCALE](state, scale: number) {
-    state.canvasScale = scale
-  },
-
   [MutationTypes.SET_THUMBNAILS_FOCUS](state, isFocus: boolean) {
     state.thumbnailsFocus = isFocus
   },

+ 6 - 4
src/views/Editor/Canvas/MultiSelectOperate.vue

@@ -41,6 +41,10 @@ export default defineComponent({
     BorderLine,
   },
   props: {
+    canvasScale: {
+      type: Number,
+      required: true,
+    },
     elementList: {
       type: Array as PropType<PPTElement[]>,
       required: true,
@@ -52,7 +56,6 @@ export default defineComponent({
   },
   setup(props) {
     const store = useStore<State>()
-    const canvasScale = computed(() => store.state.canvasScale)
     const activeElementIdList = computed(() => store.state.activeElementIdList)
     const localActiveElementList = computed(() => props.elementList.filter(el => activeElementIdList.value.includes(el.elId)))
 
@@ -63,8 +66,8 @@ export default defineComponent({
       maxY: 0,
     })
 
-    const width = computed(() => (range.maxX - range.minX) * canvasScale.value)
-    const height = computed(() => (range.maxY - range.minY) * canvasScale.value)
+    const width = computed(() => (range.maxX - range.minX) * props.canvasScale)
+    const height = computed(() => (range.maxY - range.minY) * props.canvasScale)
 
     const resizablePoints = computed(() => {
       return [
@@ -110,7 +113,6 @@ export default defineComponent({
 
     return {
       ...toRefs(range),
-      canvasScale,
       borderLines,
       disableResizablePoint,
       resizablePoints,

+ 5 - 2
src/views/Editor/Canvas/hooks/useAlignElementToCanvas.ts

@@ -1,4 +1,4 @@
-import { Ref } from 'vue'
+import { Ref, computed } from 'vue'
 import { useStore } from 'vuex'
 import { State, MutationTypes } from '@/store'
 import { PPTElement } from '@/types/slides'
@@ -6,9 +6,12 @@ import { ElementAlignCommand, ElementAlignCommands } from '@/types/edit'
 import { getElementListRange } from '../utils/elementRange'
 import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
 
-export default (elementList: Ref<PPTElement[]>, activeElementList: Ref<PPTElement[]>, activeElementIdList: Ref<string[]>) => {
+export default (elementList: Ref<PPTElement[]>) => {
   const store = useStore<State>()
 
+  const activeElementIdList = computed(() => store.state.activeElementIdList)
+  const activeElementList: Ref<PPTElement[]> = computed(() => store.getters.activeElementList)
+
   const alignElementToCanvas = (command: ElementAlignCommand) => {
     const viewportWidth = VIEWPORT_SIZE
     const viewportHeight = VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO

+ 4 - 2
src/views/Editor/Canvas/hooks/useCombineElement.ts

@@ -1,11 +1,13 @@
-import { Ref } from 'vue'
+import { Ref, computed } from 'vue'
 import { useStore } from 'vuex'
 import { State, MutationTypes } from '@/store'
 import { PPTElement } from '@/types/slides'
 import { createRandomCode } from '@/utils/common'
 
-export default (elementList: Ref<PPTElement[]>, activeElementList: Ref<PPTElement[]>, activeElementIdList: Ref<string[]>) => {
+export default (elementList: Ref<PPTElement[]>) => {
   const store = useStore<State>()
+  const activeElementIdList = computed(() => store.state.activeElementIdList)
+  const activeElementList: Ref<PPTElement[]> = computed(() => store.getters.activeElementList)
 
   // 组合元素(为当前所有激活元素添加一个相同的groupId)
   const combineElements = () => {

+ 4 - 2
src/views/Editor/Canvas/hooks/useCopyAndPasteElement.ts

@@ -1,4 +1,4 @@
-import { Ref } from 'vue'
+import { Ref, computed } from 'vue'
 import { useStore } from 'vuex'
 import { State, MutationTypes } from '@/store'
 import { PPTElement } from '@/types/slides'
@@ -6,8 +6,10 @@ import { copyText, readClipboard } from '@/utils/clipboard'
 import { encrypt, decrypt } from '@/utils/crypto'
 import { message } from 'ant-design-vue'
 
-export default (deleteElement: () => void, activeElementList: Ref<PPTElement[]>, activeElementIdList: Ref<string[]>) => {
+export default (deleteElement: () => void) => {
   const store = useStore<State>()
+  const activeElementIdList = computed(() => store.state.activeElementIdList)
+  const activeElementList: Ref<PPTElement[]> = computed(() => store.getters.activeElementList)
 
   const copyElement = () => {
     if(!activeElementIdList.value.length) return

+ 3 - 2
src/views/Editor/Canvas/hooks/useDeleteElement.ts

@@ -1,10 +1,11 @@
-import { Ref } from 'vue'
+import { Ref, computed } from 'vue'
 import { useStore } from 'vuex'
 import { State, MutationTypes } from '@/store'
 import { PPTElement } from '@/types/slides'
 
-export default (elementList: Ref<PPTElement[]>, activeElementIdList: Ref<string[]>) => {
+export default (elementList: Ref<PPTElement[]>) => {
   const store = useStore<State>()
+  const activeElementIdList = computed(() => store.state.activeElementIdList)
 
   const deleteElement = () => {
     if(!activeElementIdList.value.length) return

+ 8 - 7
src/hooks/useDropImage.ts

@@ -1,14 +1,17 @@
-import { ref, onMounted, onUnmounted, Ref } from 'vue'
+import { onMounted, onUnmounted, Ref } from 'vue'
+import { getImageDataURL } from '@/utils/image'
 
 export default (elementRef: Ref<HTMLElement | null>) => {
-  const imageFile = ref<File | null>(null)
-
   const handleDrop = (e: DragEvent) => {
     if(!e.dataTransfer) return
     const file = e.dataTransfer.items[0]
     if( file.kind === 'file' && file.type.indexOf('image') !== -1 ) {
-      const _imageFile = file.getAsFile()
-      if(_imageFile) imageFile.value = _imageFile
+      const imageFile = file.getAsFile()
+      if(imageFile) {
+        getImageDataURL(imageFile).then(dataURL => {
+          console.log(dataURL)
+        })
+      }
     }
   }
 
@@ -28,6 +31,4 @@ export default (elementRef: Ref<HTMLElement | null>) => {
     document.ondragenter = null
     document.ondragover = null
   })
-
-  return imageFile
 }

+ 3 - 2
src/views/Editor/Canvas/hooks/useLockElement.ts

@@ -1,10 +1,11 @@
 import { useStore } from 'vuex'
-import { Ref } from 'vue'
+import { Ref, computed } from 'vue'
 import { State, MutationTypes } from '@/store'
 import { PPTElement } from '@/types/slides'
 
-export default (elementList: Ref<PPTElement[]>, activeElementIdList: Ref<string[]>) => {
+export default (elementList: Ref<PPTElement[]>) => {
   const store = useStore<State>()
+  const activeElementIdList = computed(() => store.state.activeElementIdList)
 
   const lockElement = (handleElement: PPTElement) => {
     const newElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList.value))

+ 2 - 2
src/views/Editor/Canvas/hooks/useMoveElement.ts

@@ -1,4 +1,4 @@
-import { Ref } from 'vue'
+import { Ref, computed } from 'vue'
 import { useStore } from 'vuex'
 import { State, MutationTypes } from '@/store'
 import { ElementTypes, PPTElement } from '@/types/slides'
@@ -9,12 +9,12 @@ import { AlignLine, uniqAlignLines } from '../utils/alignLines'
 
 export default (
   elementList: Ref<PPTElement[]>,
-  activeElementIdList: Ref<string[]>,
   activeGroupElementId: Ref<string>,
   canvasScale: Ref<number>,
   alignmentLines: Ref<AlignmentLineProps[]>,
 ) => {
   const store = useStore<State>()
+  const activeElementIdList = computed(() => store.state.activeElementIdList)
 
   const moveElement = (e: MouseEvent, element: PPTElement) => {
     if(!activeElementIdList.value.includes(element.elId)) return

+ 9 - 1
src/views/Editor/Canvas/hooks/useRotateElement.ts

@@ -2,7 +2,15 @@ import { Ref } from 'vue'
 import { useStore } from 'vuex'
 import { State, MutationTypes } from '@/store'
 import { PPTElement, PPTTextElement, PPTImageElement, PPTShapeElement } from '@/types/slides'
-import { getAngleFromCoordinate } from '../utils/elementRotate'
+
+// 给定一个坐标,计算该坐标到(0, 0)点连线的弧度值
+// 注意,Math.atan2的一般用法是Math.atan2(y, x)返回的是原点(0,0)到(x,y)点的线段与X轴正方向之间的弧度值
+// 这里将使用时将x与y的传入顺序交换了,为的是获取原点(0,0)到(x,y)点的线段与Y轴正方向之间的弧度值
+export const getAngleFromCoordinate = (x: number, y: number) => {
+  const radian = Math.atan2(x, y)
+  const angle = 180 / Math.PI * radian
+  return angle
+}
 
 export default (elementList: Ref<PPTElement[]>, viewportRef: Ref<HTMLElement | null>, canvasScale: Ref<number>) => {
   const store = useStore<State>()

+ 77 - 3
src/views/Editor/Canvas/hooks/useScaleElement.ts

@@ -4,19 +4,93 @@ import { State, MutationTypes } from '@/store'
 import { ElementTypes, PPTElement, PPTLineElement } from '@/types/slides'
 import { OPERATE_KEYS, ElementScaleHandler } from '@/types/edit'
 import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
-import { getRotateElementPoints, getOppositePoint } from '../utils/elementRotate'
 import { AlignLine, uniqAlignLines } from '../utils/alignLines'
 import { AlignmentLineProps, MultiSelectRange } from '../types/index'
 
+// 计算元素被旋转一定角度后,八个操作点的新坐标
+interface RotateElementData {
+  left: number;
+  top: number;
+  width: number;
+  height: number;
+}
+export const getRotateElementPoints = (element: RotateElementData, angle: number) => {
+  const { left, top, width, height } = element
+
+  const radius = Math.sqrt( Math.pow(width, 2) + Math.pow(height, 2) ) / 2
+  const auxiliaryAngle = Math.atan(height / width) * 180 / Math.PI
+
+  const tlbraRadian = (180 - angle - auxiliaryAngle) * Math.PI / 180
+  const trblaRadian = (auxiliaryAngle - angle) * Math.PI / 180
+  const taRadian = (90 - angle) * Math.PI / 180
+  const raRadian = angle * Math.PI / 180
+
+  const halfWidth = width / 2
+  const halfHeight = height / 2
+
+  const middleLeft = left + halfWidth
+  const middleTop = top + halfHeight
+
+  const leftTopPoint = {
+    left: middleLeft + radius * Math.cos(tlbraRadian),
+    top: middleTop - radius * Math.sin(tlbraRadian),
+  }
+  const topPoint = {
+    left: middleLeft + halfHeight * Math.cos(taRadian),
+    top: middleTop - halfHeight * Math.sin(taRadian),
+  }
+  const rightTopPoint = {
+    left: middleLeft + radius * Math.cos(trblaRadian),
+    top: middleTop - radius * Math.sin(trblaRadian),
+  }
+  const rightPoint = {
+    left: middleLeft + halfWidth * Math.cos(raRadian),
+    top: middleTop + halfWidth * Math.sin(raRadian),
+  }
+  const rightBottomPoint = {
+    left: middleLeft - radius * Math.cos(tlbraRadian),
+    top: middleTop + radius * Math.sin(tlbraRadian),
+  }
+  const bottomPoint = {
+    left: middleLeft - halfHeight * Math.sin(raRadian),
+    top: middleTop + halfHeight * Math.cos(raRadian),
+  }
+  const leftBottomPoint = {
+    left: middleLeft - radius * Math.cos(trblaRadian),
+    top: middleTop + radius * Math.sin(trblaRadian),
+  }
+  const leftPoint = {
+    left: middleLeft - halfWidth * Math.cos(raRadian),
+    top: middleTop - halfWidth * Math.sin(raRadian),
+  }
+
+  return { leftTopPoint, topPoint, rightTopPoint, rightPoint, rightBottomPoint, bottomPoint, leftBottomPoint, leftPoint }
+}
+
+// 获取元素某个操作点对角线上另一端的操作点坐标(例如:左上 <-> 右下)
+export const getOppositePoint = (direction: number, points: ReturnType<typeof getRotateElementPoints>): { left: number; top: number } => {
+  const oppositeMap = {
+    [OPERATE_KEYS.RIGHT_BOTTOM]: points.leftTopPoint,
+    [OPERATE_KEYS.LEFT_BOTTOM]: points.rightTopPoint,
+    [OPERATE_KEYS.LEFT_TOP]: points.rightBottomPoint,
+    [OPERATE_KEYS.RIGHT_TOP]: points.leftBottomPoint,
+    [OPERATE_KEYS.TOP]: points.bottomPoint,
+    [OPERATE_KEYS.BOTTOM]: points.topPoint,
+    [OPERATE_KEYS.LEFT]: points.rightPoint,
+    [OPERATE_KEYS.RIGHT]: points.leftPoint,
+  }
+  return oppositeMap[direction]
+}
+
 export default (
   elementList: Ref<PPTElement[]>,
   canvasScale: Ref<number>,
   activeGroupElementId: Ref<string>,
-  activeElementIdList: Ref<string[]>,
   alignmentLines: Ref<AlignmentLineProps[]>,
 ) => {
   const store = useStore<State>()
-  const ctrlOrShiftKeyActive = computed(() => store.getters.ctrlOrShiftKeyActive)
+  const activeElementIdList = computed(() => store.state.activeElementIdList)
+  const ctrlOrShiftKeyActive: Ref<boolean> = computed(() => store.getters.ctrlOrShiftKeyActive)
 
   const scaleElement = (e: MouseEvent, element: Exclude<PPTElement, PPTLineElement>, command: ElementScaleHandler) => {
     let isMouseDown = true

+ 4 - 4
src/views/Editor/Canvas/hooks/useSelectElement.ts

@@ -6,14 +6,14 @@ import { PPTElement } from '@/types/slides'
 
 export default (
   elementList: Ref<PPTElement[]>,
-  activeElementIdList: Ref<string[]>,
   activeGroupElementId: Ref<string>,
-  editorAreaFocus: Ref<boolean>,
-  handleElementId: Ref<string>,
   moveElement: (e: MouseEvent, element: PPTElement) => void,
 ) => {
   const store = useStore<State>()
-  const ctrlOrShiftKeyActive = computed(() => store.getters.ctrlOrShiftKeyActive)
+  const activeElementIdList = computed(() => store.state.activeElementIdList)
+  const handleElementId = computed(() => store.state.handleElementId)
+  const editorAreaFocus = computed(() => store.state.editorAreaFocus)
+  const ctrlOrShiftKeyActive: Ref<boolean> = computed(() => store.getters.ctrlOrShiftKeyActive)
 
   const selectElement = (e: MouseEvent, element: PPTElement, canMove = true) => {
     if(!editorAreaFocus.value) store.commit(MutationTypes.SET_EDITORAREA_FOCUS, true)

+ 8 - 2
src/views/Editor/Canvas/hooks/useViewportSize.ts

@@ -30,6 +30,13 @@ export default (canvasRef: Ref<HTMLElement | null>) => {
     }
   }
 
+  const viewportStyles = computed(() => ({
+    width: VIEWPORT_SIZE,
+    height: VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO,
+    left: viewportLeft.value,
+    top: viewportTop.value,
+  }))
+
   const resizeObserver = new ResizeObserver(setViewportSize)
 
   onMounted(() => {
@@ -41,7 +48,6 @@ export default (canvasRef: Ref<HTMLElement | null>) => {
 
   return {
     canvasScale,
-    viewportLeft,
-    viewportTop,
+    viewportStyles,
   }
 }

+ 18 - 34
src/views/Editor/Canvas/index.vue

@@ -40,11 +40,13 @@
         v-if="activeElementIdList.length > 1"
         :elementList="elementList"
         :scaleMultiElement="scaleMultiElement"
+        :canvasScale="canvasScale"
       />
 
       <EditableElement 
         v-for="(element, index) in elementList" 
         :key="element.elId"
+        :canvasScale="canvasScale"
         :elementInfo="element"
         :elementIndex="index + 1"
         :isActive="activeElementIdList.includes(element.elId)"
@@ -69,17 +71,13 @@
 </template>
 
 <script lang="ts">
-import { computed, defineComponent, ref, watch, watchEffect } from 'vue'
+import { computed, defineComponent, Ref, ref, watch, watchEffect } from 'vue'
 import { useStore } from 'vuex'
 import { State, MutationTypes } from '@/store'
 import { ContextmenuItem } from '@/components/Contextmenu/types'
 import { PPTElement } from '@/types/slides'
 import { AlignmentLineProps } from './types/index'
 
-import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
-import { getImageDataURL } from '@/utils/image'
-
-import useDropImage from '@/hooks/useDropImage'
 import useViewportSize from './hooks/useViewportSize'
 import useLockElement from './hooks/useLockElement'
 import useDeleteElement from './hooks/useDeleteElement'
@@ -92,6 +90,7 @@ import useScaleElement from './hooks/useScaleElement'
 import useSelectElement from './hooks/useSelectElement'
 import useMoveElement from './hooks/useMoveElement'
 import useMouseSelection from './hooks/useMouseSelection'
+import useDropImageElement from './hooks/useDropImageElement'
 
 import EditableElement from '@/views/_common/_element/EditableElement.vue'
 import MouseSelection from './MouseSelection.vue'
@@ -112,10 +111,9 @@ export default defineComponent({
     const store = useStore<State>()
 
     const activeElementIdList = computed(() => store.state.activeElementIdList)
-    const activeElementList = computed(() => store.getters.activeElementList)
     const handleElementId = computed(() => store.state.handleElementId)
-    const ctrlOrShiftKeyActive = computed(() => store.getters.ctrlOrShiftKeyActive)
     const editorAreaFocus = computed(() => store.state.editorAreaFocus)
+    const ctrlOrShiftKeyActive: Ref<boolean> = computed(() => store.getters.ctrlOrShiftKeyActive)
 
     const viewportRef = ref<HTMLElement | null>(null)
     const isShowGridLines = ref(false)
@@ -131,26 +129,24 @@ export default defineComponent({
     }
     watchEffect(setLocalElementList)
 
-    const dropImageFile = useDropImage(viewportRef)
-    watch(dropImageFile, () => {
-      if(dropImageFile.value) {
-        getImageDataURL(dropImageFile.value).then(dataURL => {
-          console.log(dataURL)
-        })
-      }
-    })
+    useDropImageElement(viewportRef)
 
     const canvasRef = ref<HTMLElement | null>(null)
-    const { canvasScale, viewportLeft, viewportTop } = useViewportSize(canvasRef)
-    const viewportStyles = computed(() => ({
-      width: VIEWPORT_SIZE,
-      height: VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO,
-      left: viewportLeft.value,
-      top: viewportTop.value,
-    }))
+    const { canvasScale, viewportStyles } = useViewportSize(canvasRef)
 
     const { mouseSelectionState, updateMouseSelection } = useMouseSelection(elementList, viewportRef, canvasScale)
 
+    const { moveElement } = useMoveElement(elementList, activeGroupElementId, canvasScale, alignmentLines)
+    const { selectElement, selectAllElement } = useSelectElement(elementList, activeGroupElementId, moveElement)
+    const { scaleElement, scaleMultiElement } = useScaleElement(elementList, canvasScale, activeGroupElementId, alignmentLines)
+    const { rotateElement } = useRotateElement(elementList, viewportRef, canvasScale)  
+    const { orderElement } = useOrderElement(elementList)
+    const { alignElementToCanvas } = useAlignElementToCanvas(elementList)
+    const { combineElements, uncombineElements } = useCombineElement(elementList)
+    const { deleteElement, deleteAllElements } = useDeleteElement(elementList)
+    const { lockElement, unlockElement } = useLockElement(elementList)
+    const { copyElement, cutElement, pasteElement } = useCopyAndPasteElement(deleteElement)
+
     const handleClickBlankArea = (e: MouseEvent) => {
       store.commit(MutationTypes.SET_ACTIVE_ELEMENT_ID_LIST, [])
       if(!ctrlOrShiftKeyActive.value) updateMouseSelection(e)
@@ -161,17 +157,6 @@ export default defineComponent({
       if(editorAreaFocus.value) store.commit(MutationTypes.SET_EDITORAREA_FOCUS, false)
     }
 
-    const { moveElement } = useMoveElement(elementList, activeElementIdList, activeGroupElementId, canvasScale, alignmentLines)
-    const { selectElement, selectAllElement } = useSelectElement(elementList, activeElementIdList, activeGroupElementId, editorAreaFocus, handleElementId, moveElement)
-    const { scaleElement, scaleMultiElement } = useScaleElement(elementList, canvasScale, activeGroupElementId, activeElementIdList, alignmentLines)
-    const { rotateElement } = useRotateElement(elementList, viewportRef, canvasScale)  
-    const { orderElement } = useOrderElement(elementList)
-    const { alignElementToCanvas } = useAlignElementToCanvas(elementList, activeElementList, activeElementIdList)
-    const { combineElements, uncombineElements } = useCombineElement(elementList, activeElementList, activeElementIdList)
-    const { deleteElement, deleteAllElements } = useDeleteElement(elementList, activeElementIdList)
-    const { lockElement, unlockElement } = useLockElement(elementList, activeElementIdList)
-    const { copyElement, cutElement, pasteElement } = useCopyAndPasteElement(deleteElement, activeElementList, activeElementIdList)
-
     const contextmenus = (): ContextmenuItem[] => {
       return [
         {
@@ -194,7 +179,6 @@ export default defineComponent({
     return {
       elementList,
       activeElementIdList,
-      activeElementList,
       handleElementId,
       activeGroupElementId,
       canvasRef,

+ 0 - 85
src/views/Editor/Canvas/utils/elementRotate.ts

@@ -1,85 +0,0 @@
-import { OPERATE_KEYS } from '@/types/edit'
-
-// 给定一个坐标,计算该坐标到(0, 0)点连线的弧度值
-// 注意,Math.atan2的一般用法是Math.atan2(y, x)返回的是原点(0,0)到(x,y)点的线段与X轴正方向之间的弧度值
-// 这里将使用时将x与y的传入顺序交换了,为的是获取原点(0,0)到(x,y)点的线段与Y轴正方向之间的弧度值
-export const getAngleFromCoordinate = (x: number, y: number) => {
-  const radian = Math.atan2(x, y)
-  const angle = 180 / Math.PI * radian
-  return angle
-}
-
-// 计算元素被旋转一定角度后,八个操作点的新坐标
-interface RotateElementData {
-  left: number;
-  top: number;
-  width: number;
-  height: number;
-}
-export const getRotateElementPoints = (element: RotateElementData, angle: number) => {
-  const { left, top, width, height } = element
-
-  const radius = Math.sqrt( Math.pow(width, 2) + Math.pow(height, 2) ) / 2
-  const auxiliaryAngle = Math.atan(height / width) * 180 / Math.PI
-
-  const tlbraRadian = (180 - angle - auxiliaryAngle) * Math.PI / 180
-  const trblaRadian = (auxiliaryAngle - angle) * Math.PI / 180
-  const taRadian = (90 - angle) * Math.PI / 180
-  const raRadian = angle * Math.PI / 180
-
-  const halfWidth = width / 2
-  const halfHeight = height / 2
-
-  const middleLeft = left + halfWidth
-  const middleTop = top + halfHeight
-
-  const leftTopPoint = {
-    left: middleLeft + radius * Math.cos(tlbraRadian),
-    top: middleTop - radius * Math.sin(tlbraRadian),
-  }
-  const topPoint = {
-    left: middleLeft + halfHeight * Math.cos(taRadian),
-    top: middleTop - halfHeight * Math.sin(taRadian),
-  }
-  const rightTopPoint = {
-    left: middleLeft + radius * Math.cos(trblaRadian),
-    top: middleTop - radius * Math.sin(trblaRadian),
-  }
-  const rightPoint = {
-    left: middleLeft + halfWidth * Math.cos(raRadian),
-    top: middleTop + halfWidth * Math.sin(raRadian),
-  }
-  const rightBottomPoint = {
-    left: middleLeft - radius * Math.cos(tlbraRadian),
-    top: middleTop + radius * Math.sin(tlbraRadian),
-  }
-  const bottomPoint = {
-    left: middleLeft - halfHeight * Math.sin(raRadian),
-    top: middleTop + halfHeight * Math.cos(raRadian),
-  }
-  const leftBottomPoint = {
-    left: middleLeft - radius * Math.cos(trblaRadian),
-    top: middleTop + radius * Math.sin(trblaRadian),
-  }
-  const leftPoint = {
-    left: middleLeft - halfWidth * Math.cos(raRadian),
-    top: middleTop - halfWidth * Math.sin(raRadian),
-  }
-
-  return { leftTopPoint, topPoint, rightTopPoint, rightPoint, rightBottomPoint, bottomPoint, leftBottomPoint, leftPoint }
-}
-
-// 获取元素某个操作点对角线上另一端的操作点坐标(例如:左上 <-> 右下)
-export const getOppositePoint = (direction: number, points: ReturnType<typeof getRotateElementPoints>): { left: number; top: number } => {
-  const oppositeMap = {
-    [OPERATE_KEYS.RIGHT_BOTTOM]: points.leftTopPoint,
-    [OPERATE_KEYS.LEFT_BOTTOM]: points.rightTopPoint,
-    [OPERATE_KEYS.LEFT_TOP]: points.rightBottomPoint,
-    [OPERATE_KEYS.RIGHT_TOP]: points.leftBottomPoint,
-    [OPERATE_KEYS.TOP]: points.bottomPoint,
-    [OPERATE_KEYS.BOTTOM]: points.topPoint,
-    [OPERATE_KEYS.LEFT]: points.rightPoint,
-    [OPERATE_KEYS.RIGHT]: points.leftPoint,
-  }
-  return oppositeMap[direction]
-}

+ 5 - 7
src/views/_common/_element/EditableElement.vue

@@ -7,8 +7,8 @@
   >
     <component
       :is="currentElementComponent"
-      :elementInfo="elementInfo"
       :canvasScale="canvasScale"
+      :elementInfo="elementInfo"
       :isActive="isActive"
       :isHandleEl="isHandleEl"
       :isActiveGroupElement="isActiveGroupElement"
@@ -24,8 +24,6 @@
 
 <script lang="ts">
 import { computed, defineComponent, PropType } from 'vue'
-import { useStore } from 'vuex'
-import { State } from '@/store'
 import { PPTElement, PPTTextElement, PPTImageElement, PPTShapeElement, PPTLineElement } from '@/types/slides'
 import { ContextmenuItem } from '@/components/Contextmenu/types'
 
@@ -43,6 +41,10 @@ import TextElement from './TextElement/index.vue'
 export default defineComponent({
   name: 'editable-element',
   props: {
+    canvasScale: {
+      type: Number,
+      required: true,
+    },
     elementInfo: {
       type: Object as PropType<PPTElement>,
       required: true,
@@ -121,9 +123,6 @@ export default defineComponent({
     },
   },
   setup(props) {
-    const store = useStore<State>()
-    const canvasScale = computed(() => store.state.canvasScale)
-
     const currentElementComponent = computed(() => {
       const elementTypeMap = {
         'image': ImageElement,
@@ -209,7 +208,6 @@ export default defineComponent({
     }
 
     return {
-      canvasScale,
       currentElementComponent,
       contextmenus,
     }