TextElementOperate.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <template>
  2. <div
  3. class="text-element-operate"
  4. :class="{
  5. 'selected': isSelected,
  6. 'multi-select': isMultiSelect && isSelected,
  7. 'active': isActive,
  8. }"
  9. >
  10. <BorderLine
  11. class="operate-border-line"
  12. v-for="line in borderLines"
  13. :key="line.type"
  14. :type="line.type"
  15. :style="line.style"
  16. />
  17. <template v-if="!elementInfo.lock && (isActiveGroupElement || !isMultiSelect)">
  18. <ResizeHandler
  19. class="operate-resize-handler"
  20. v-for="point in textElementResizeHandlers"
  21. :key="point.direction"
  22. :type="point.direction"
  23. :style="point.style"
  24. @mousedown.stop="$event => scaleElement($event, elementInfo, point.direction)"
  25. />
  26. <RotateHandler
  27. class="operate-rotate-handler"
  28. :style="{ left: scaleWidth / 2 + 'px' }"
  29. @mousedown.stop="rotateElement(elementInfo)"
  30. />
  31. </template>
  32. <AnimationIndex v-if="animationIndex !== -1" :animationIndex="animationIndex" />
  33. </div>
  34. </template>
  35. <script lang="ts">
  36. import { computed, defineComponent, PropType } from 'vue'
  37. import { useStore } from 'vuex'
  38. import { State } from '@/store'
  39. import { PPTTextElement } from '@/types/slides'
  40. import { OperateResizeHandler } from '@/types/edit'
  41. import useCommonOperate from '../hooks/useCommonOperate'
  42. import RotateHandler from './RotateHandler.vue'
  43. import ResizeHandler from './ResizeHandler.vue'
  44. import BorderLine from './BorderLine.vue'
  45. import AnimationIndex from './AnimationIndex.vue'
  46. export default defineComponent({
  47. name: 'text-element-operate',
  48. components: {
  49. RotateHandler,
  50. ResizeHandler,
  51. BorderLine,
  52. AnimationIndex,
  53. },
  54. props: {
  55. elementInfo: {
  56. type: Object as PropType<PPTTextElement>,
  57. required: true,
  58. },
  59. isSelected: {
  60. type: Boolean,
  61. required: true,
  62. },
  63. isActive: {
  64. type: Boolean,
  65. required: true,
  66. },
  67. isActiveGroupElement: {
  68. type: Boolean,
  69. required: true,
  70. },
  71. isMultiSelect: {
  72. type: Boolean,
  73. required: true,
  74. },
  75. animationIndex: {
  76. type: Number,
  77. required: true,
  78. },
  79. rotateElement: {
  80. type: Function as PropType<(element: PPTTextElement) => void>,
  81. required: true,
  82. },
  83. scaleElement: {
  84. type: Function as PropType<(e: MouseEvent, element: PPTTextElement, command: OperateResizeHandler) => void>,
  85. required: true,
  86. },
  87. },
  88. setup(props) {
  89. const store = useStore<State>()
  90. const canvasScale = computed(() => store.state.canvasScale)
  91. const scaleWidth = computed(() => props.elementInfo.width * canvasScale.value)
  92. const scaleHeight = computed(() => props.elementInfo.height * canvasScale.value)
  93. const { textElementResizeHandlers, borderLines } = useCommonOperate(scaleWidth, scaleHeight)
  94. return {
  95. scaleWidth,
  96. textElementResizeHandlers,
  97. borderLines,
  98. }
  99. },
  100. })
  101. </script>
  102. <style lang="scss" scoped>
  103. .text-element-operate {
  104. &.selected {
  105. .operate-border-line,
  106. .operate-resize-handler,
  107. .operate-rotate-handler {
  108. display: block;
  109. }
  110. }
  111. &.multi-select:not(.selected) .operate-border-line {
  112. border-color: rgba($color: $themeColor, $alpha: .3);
  113. }
  114. .operate-border-line,
  115. .operate-resize-handler,
  116. .operate-rotate-handler {
  117. display: none;
  118. }
  119. }
  120. </style>