MultiSelectOperate.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <template>
  2. <div
  3. class="multi-select-operate"
  4. :style="{
  5. left: minX * canvasScale + 'px',
  6. top: minY * canvasScale + 'px',
  7. }"
  8. >
  9. <BorderLine v-for="line in borderLines" :key="line.type" :type="line.type" :style="line.style" />
  10. <template v-if="!disableResize">
  11. <ResizeHandler
  12. v-for="point in resizeHandlers"
  13. :key="point.direction"
  14. :type="point.direction"
  15. :style="point.style"
  16. @mousedown.stop="scaleMultiElement($event, { minX, maxX, minY, maxY }, point.direction)"
  17. />
  18. </template>
  19. </div>
  20. </template>
  21. <script lang="ts">
  22. import { computed, defineComponent, reactive, PropType, watchEffect, toRefs } from 'vue'
  23. import { useStore } from '@/store'
  24. import { PPTElement } from '@/types/slides'
  25. import { getElementListRange } from '@/utils/element'
  26. import { OperateResizeHandler, MultiSelectRange } from '@/types/edit'
  27. import useCommonOperate from '../hooks/useCommonOperate'
  28. import ResizeHandler from './ResizeHandler.vue'
  29. import BorderLine from './BorderLine.vue'
  30. export default defineComponent({
  31. name: 'multi-select-operate',
  32. components: {
  33. ResizeHandler,
  34. BorderLine,
  35. },
  36. props: {
  37. elementList: {
  38. type: Array as PropType<PPTElement[]>,
  39. required: true,
  40. },
  41. scaleMultiElement: {
  42. type: Function as PropType<(e: MouseEvent, range: MultiSelectRange, command: OperateResizeHandler) => void>,
  43. required: true,
  44. },
  45. },
  46. setup(props) {
  47. const store = useStore()
  48. const activeElementIdList = computed(() => store.state.activeElementIdList)
  49. const canvasScale = computed(() => store.state.canvasScale)
  50. const localActiveElementList = computed(() => props.elementList.filter(el => activeElementIdList.value.includes(el.id)))
  51. const range = reactive({
  52. minX: 0,
  53. maxX: 0,
  54. minY: 0,
  55. maxY: 0,
  56. })
  57. const width = computed(() => (range.maxX - range.minX) * canvasScale.value)
  58. const height = computed(() => (range.maxY - range.minY) * canvasScale.value)
  59. const { resizeHandlers, borderLines } = useCommonOperate(width, height)
  60. const disableResize = computed(() => {
  61. return localActiveElementList.value.some(item => {
  62. if(
  63. (item.type === 'image' || item.type === 'shape') &&
  64. !item.rotate
  65. ) return false
  66. return true
  67. })
  68. })
  69. const setRange = () => {
  70. const { minX, maxX, minY, maxY } = getElementListRange(localActiveElementList.value)
  71. range.minX = minX
  72. range.maxX = maxX
  73. range.minY = minY
  74. range.maxY = maxY
  75. }
  76. watchEffect(setRange)
  77. return {
  78. ...toRefs(range),
  79. canvasScale,
  80. borderLines,
  81. disableResize,
  82. resizeHandlers,
  83. }
  84. },
  85. })
  86. </script>
  87. <style lang="scss" scoped>
  88. .multi-select-operate {
  89. position: absolute;
  90. top: 0;
  91. left: 0;
  92. z-index: 101;
  93. }
  94. </style>