| <template> | |
| <div class="shape-element-operate"> | |
| <BorderLine | |
| class="operate-border-line" | |
| v-for="line in borderLines" | |
| :key="line.type" | |
| :type="line.type" | |
| :style="line.style" | |
| /> | |
| <template v-if="handlerVisible"> | |
| <ResizeHandler | |
| class="operate-resize-handler" | |
| v-for="point in resizeHandlers" | |
| :key="point.direction" | |
| :type="point.direction" | |
| :rotate="elementInfo.rotate" | |
| :style="point.style" | |
| @mousedown.stop="$event => scaleElement($event, elementInfo, point.direction)" | |
| /> | |
| <RotateHandler | |
| class="operate-rotate-handler" | |
| :style="{ left: scaleWidth / 2 + 'px' }" | |
| @mousedown.stop="$event => rotateElement($event, elementInfo)" | |
| /> | |
| <div | |
| class="operate-keypoint-handler" | |
| v-for="(keypoint, index) in keypoints" | |
| :key="index" | |
| :style="keypoint.styles" | |
| @mousedown.stop="$event => moveShapeKeypoint($event, elementInfo, index)" | |
| ></div> | |
| </template> | |
| </div> | |
| </template> | |
| <script lang="ts"> | |
| export default { | |
| inheritAttrs: false, | |
| } | |
| </script> | |
| <script lang="ts" setup> | |
| import { computed, type CSSProperties } from 'vue' | |
| import { storeToRefs } from 'pinia' | |
| import { useMainStore } from '@/store' | |
| import type { PPTShapeElement } from '@/types/slides' | |
| import type { OperateResizeHandlers } from '@/types/edit' | |
| import { SHAPE_PATH_FORMULAS } from '@/configs/shapes' | |
| import useCommonOperate from '../hooks/useCommonOperate' | |
| import RotateHandler from './RotateHandler.vue' | |
| import ResizeHandler from './ResizeHandler.vue' | |
| import BorderLine from './BorderLine.vue' | |
| const props = defineProps<{ | |
| elementInfo: PPTShapeElement | |
| handlerVisible: boolean | |
| rotateElement: (e: MouseEvent, element: PPTShapeElement) => void | |
| scaleElement: (e: MouseEvent, element: PPTShapeElement, command: OperateResizeHandlers) => void | |
| moveShapeKeypoint: (e: MouseEvent, element: PPTShapeElement, index: number) => void | |
| }>() | |
| const { canvasScale } = storeToRefs(useMainStore()) | |
| const scaleWidth = computed(() => props.elementInfo.width * canvasScale.value) | |
| const scaleHeight = computed(() => props.elementInfo.height * canvasScale.value) | |
| const { resizeHandlers, borderLines } = useCommonOperate(scaleWidth, scaleHeight) | |
| const keypoints = computed(() => { | |
| if (!props.elementInfo.pathFormula || props.elementInfo.keypoints === undefined) return [] | |
| const pathFormula = SHAPE_PATH_FORMULAS[props.elementInfo.pathFormula] | |
| return props.elementInfo.keypoints.map((keypoint, index) => { | |
| const getBaseSize = pathFormula.getBaseSize![index] | |
| const relative = pathFormula.relative![index] | |
| const keypointPos = getBaseSize(props.elementInfo.width, props.elementInfo.height) * keypoint | |
| let styles: CSSProperties = {} | |
| if (relative === 'left') styles = { left: keypointPos * canvasScale.value + 'px' } | |
| else if (relative === 'right') styles = { left: (props.elementInfo.width - keypointPos) * canvasScale.value + 'px' } | |
| else if (relative === 'center') styles = { left: (props.elementInfo.width - keypointPos) / 2 * canvasScale.value + 'px' } | |
| else if (relative === 'top') styles = { top: keypointPos * canvasScale.value + 'px' } | |
| else if (relative === 'bottom') styles = { top: (props.elementInfo.height - keypointPos) * canvasScale.value + 'px' } | |
| else if (relative === 'left_bottom') styles = { left: keypointPos * canvasScale.value + 'px', top: props.elementInfo.height * canvasScale.value + 'px' } | |
| else if (relative === 'right_bottom') styles = { left: (props.elementInfo.width - keypointPos) * canvasScale.value + 'px', top: props.elementInfo.height * canvasScale.value + 'px' } | |
| else if (relative === 'top_right') styles = { left: props.elementInfo.width * canvasScale.value + 'px', top: keypointPos * canvasScale.value + 'px' } | |
| else if (relative === 'bottom_right') styles = { left: props.elementInfo.width * canvasScale.value + 'px', top: (props.elementInfo.height - keypointPos) * canvasScale.value + 'px' } | |
| return { | |
| keypoint, | |
| styles, | |
| } | |
| }) | |
| }) | |
| </script> | |
| <style lang="scss" scoped> | |
| .operate-keypoint-handler { | |
| position: absolute; | |
| width: 10px; | |
| height: 10px; | |
| left: 0; | |
| top: 0; | |
| margin: -5px 0 0 -5px; | |
| border: 1px solid $themeColor; | |
| background-color: #ffe873; | |
| border-radius: 1px; | |
| } | |
| </style> |