ImageElementOperate.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <template>
  2. <ImageClipHandler
  3. v-if="isCliping"
  4. :src="elementInfo.src"
  5. :clipData="elementInfo.clip"
  6. :canvasScale="canvasScale"
  7. :width="elementInfo.width"
  8. :height="elementInfo.height"
  9. :top="elementInfo.top"
  10. :left="elementInfo.left"
  11. :clipPath="clipShape.style"
  12. @clip="range => clip(range)"
  13. />
  14. <div
  15. class="image-element-operate"
  16. v-else
  17. :class="{
  18. 'selected': isSelected,
  19. 'multi-select': isMultiSelect && isSelected,
  20. 'active': isActive,
  21. }"
  22. >
  23. <BorderLine
  24. class="operate-border-line"
  25. v-for="line in borderLines"
  26. :key="line.type"
  27. :type="line.type"
  28. :style="line.style"
  29. />
  30. <template v-if="!elementInfo.lock && (isActiveGroupElement || !isMultiSelect)">
  31. <ResizeHandler
  32. class="operate-resize-handler"
  33. v-for="point in resizeHandlers"
  34. :key="point.direction"
  35. :type="point.direction"
  36. :style="point.style"
  37. @mousedown.stop="$event => scaleElement($event, elementInfo, point.direction)"
  38. />
  39. <RotateHandler
  40. class="operate-rotate-handler"
  41. :style="{ left: scaleWidth / 2 + 'px' }"
  42. @mousedown.stop="rotateElement(elementInfo)"
  43. />
  44. </template>
  45. <AnimationIndex v-if="animationIndex !== -1" :animationIndex="animationIndex" />
  46. </div>
  47. </template>
  48. <script lang="ts">
  49. import { computed, defineComponent, PropType, ref } from 'vue'
  50. import { useStore } from 'vuex'
  51. import { State } from '@/store'
  52. import { PPTImageElement } from '@/types/slides'
  53. import { OperateResizeHandler, ImageClipedEmitData } from '@/types/edit'
  54. import useCommonOperate from '../hooks/useCommonOperate'
  55. import RotateHandler from './RotateHandler.vue'
  56. import ResizeHandler from './ResizeHandler.vue'
  57. import BorderLine from './BorderLine.vue'
  58. import AnimationIndex from './AnimationIndex.vue'
  59. import ImageClipHandler from './ImageClipHandler.vue'
  60. export default defineComponent({
  61. name: 'image-element-operate',
  62. components: {
  63. RotateHandler,
  64. ResizeHandler,
  65. BorderLine,
  66. AnimationIndex,
  67. ImageClipHandler,
  68. },
  69. props: {
  70. elementInfo: {
  71. type: Object as PropType<PPTImageElement>,
  72. required: true,
  73. },
  74. isSelected: {
  75. type: Boolean,
  76. required: true,
  77. },
  78. isActive: {
  79. type: Boolean,
  80. required: true,
  81. },
  82. isActiveGroupElement: {
  83. type: Boolean,
  84. required: true,
  85. },
  86. isMultiSelect: {
  87. type: Boolean,
  88. required: true,
  89. },
  90. animationIndex: {
  91. type: Number,
  92. required: true,
  93. },
  94. rotateElement: {
  95. type: Function as PropType<(element: PPTImageElement) => void>,
  96. required: true,
  97. },
  98. scaleElement: {
  99. type: Function as PropType<(e: MouseEvent, element: PPTImageElement, command: OperateResizeHandler) => void>,
  100. required: true,
  101. },
  102. },
  103. setup(props) {
  104. const store = useStore<State>()
  105. const canvasScale = computed(() => store.state.canvasScale)
  106. const scaleWidth = computed(() => props.elementInfo.width * canvasScale.value)
  107. const scaleHeight = computed(() => props.elementInfo.height * canvasScale.value)
  108. const { resizeHandlers, borderLines } = useCommonOperate(scaleWidth, scaleHeight)
  109. const clipingImageElId = ref('')
  110. const isCliping = computed(() => clipingImageElId.value === props.elementInfo.id)
  111. const clip = (data: ImageClipedEmitData) => {
  112. clipingImageElId.value = ''
  113. if(!data) return
  114. const { range, position } = data
  115. const originClip = props.elementInfo.clip || {}
  116. const _props = {
  117. clip: { ...originClip, range },
  118. left: props.elementInfo.left + position.left,
  119. top: props.elementInfo.top + position.top,
  120. width: props.elementInfo.width + position.width,
  121. height: props.elementInfo.height + position.height,
  122. }
  123. console.log(_props)
  124. }
  125. return {
  126. scaleWidth,
  127. resizeHandlers,
  128. borderLines,
  129. isCliping,
  130. clip,
  131. }
  132. },
  133. })
  134. </script>
  135. <style lang="scss" scoped>
  136. .image-element-operate {
  137. &.selected {
  138. .operate-border-line,
  139. .operate-resize-handler,
  140. .operate-rotate-handler {
  141. display: block;
  142. }
  143. }
  144. &.multi-select:not(.active) .operate-border-line {
  145. border-color: rgba($color: $themeColor, $alpha: .3);
  146. }
  147. .operate-border-line,
  148. .operate-resize-handler,
  149. .operate-rotate-handler {
  150. display: none;
  151. }
  152. }
  153. </style>