useOrderElement.ts 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import { Ref, computed } from 'vue'
  2. import { useStore } from 'vuex'
  3. import { State, MutationTypes } from '@/store'
  4. import { PPTElement, Slide } from '@/types/slides'
  5. import { ElementOrderCommand, ElementOrderCommands } from '@/types/edit'
  6. import useHistorySnapshot from '@/hooks/useHistorySnapshot'
  7. export default () => {
  8. const store = useStore<State>()
  9. const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
  10. const { addHistorySnapshot } = useHistorySnapshot()
  11. // 获取组合元素层级范围(组合成员中的最大层级和最小层级)
  12. const getCombineElementIndexRange = (elementList: PPTElement[], combineElementList: PPTElement[]) => {
  13. const minIndex = elementList.findIndex(_element => _element.id === combineElementList[0].id)
  14. const maxIndex = elementList.findIndex(_element => _element.id === combineElementList[combineElementList.length - 1].id)
  15. return { minIndex, maxIndex }
  16. }
  17. // 上移一层,返回移动后新的元素列表(下移一层逻辑类似)
  18. const moveUpElement = (elementList: PPTElement[], element: PPTElement) => {
  19. const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList))
  20. // 被操作的元素是组合元素成员
  21. if(element.groupId) {
  22. // 获取该组合元素全部成员,以及组合元素层级范围
  23. const combineElementList = copyOfElementList.filter(_element => _element.groupId === element.groupId)
  24. const { minIndex, maxIndex } = getCombineElementIndexRange(elementList, combineElementList)
  25. // 无法移动(已经处在顶层)
  26. if(maxIndex === elementList.length - 1) return null
  27. // 该组合元素上一层的元素,以下简称为【元素next】
  28. const nextElement = copyOfElementList[maxIndex + 1]
  29. // 从元素列表中移除该组合元素全部成员
  30. const movedElementList = copyOfElementList.splice(minIndex, combineElementList.length)
  31. // 如果【元素next】也是组合元素成员(另一个组合,不是上面被移除的那一组,以下简称为【组合next】)
  32. // 需要获取【组合next】全部成员的长度,将上面移除的组合元素全部成员添加到【组合next】全部成员的上方
  33. if(nextElement.groupId) {
  34. const nextCombineElementList = copyOfElementList.filter(_element => _element.groupId === nextElement.groupId)
  35. copyOfElementList.splice(minIndex + nextCombineElementList.length, 0, ...movedElementList)
  36. }
  37. // 如果【元素next】是单独的元素(非组合成员),将上面移除的组合元素全部成员添加到【元素next】上方
  38. else copyOfElementList.splice(minIndex + 1, 0, ...movedElementList)
  39. }
  40. // 被操作的元素是单独的元素(非组合成员)
  41. else {
  42. // 元素在元素列表中的层级
  43. const elementIndex = elementList.findIndex(item => item.id === element.id)
  44. // 无法移动(已经处在顶层)
  45. if(elementIndex === elementList.length - 1) return null
  46. // 上一层的元素,以下简称为【元素next】
  47. const nextElement = copyOfElementList[elementIndex + 1]
  48. // 从元素列表中移除被操作的元素
  49. const movedElement = copyOfElementList.splice(elementIndex, 1)[0]
  50. // 如果【元素next】是组合元素成员
  51. // 需要获取该组合全部成员的长度,将上面移除的元素添加到该组合全部成员的上方
  52. if(nextElement.groupId) {
  53. const combineElementList = copyOfElementList.filter(_element => _element.groupId === nextElement.groupId)
  54. copyOfElementList.splice(elementIndex + combineElementList.length, 0, movedElement)
  55. }
  56. // 如果【元素next】是单独的元素(非组合成员),将上面移除的元素添加到【元素next】上方
  57. else copyOfElementList.splice(elementIndex + 1, 0, movedElement)
  58. }
  59. return copyOfElementList
  60. }
  61. // 下移一层
  62. const moveDownElement = (elementList: PPTElement[], element: PPTElement) => {
  63. const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList))
  64. if(element.groupId) {
  65. const combineElementList = copyOfElementList.filter(_element => _element.groupId === element.groupId)
  66. const { minIndex } = getCombineElementIndexRange(elementList, combineElementList)
  67. if(minIndex === 0) return null
  68. const prevElement = copyOfElementList[minIndex - 1]
  69. const movedElementList = copyOfElementList.splice(minIndex, combineElementList.length)
  70. if(prevElement.groupId) {
  71. const prevCombineElementList = copyOfElementList.filter(_element => _element.groupId === prevElement.groupId)
  72. copyOfElementList.splice(minIndex - prevCombineElementList.length, 0, ...movedElementList)
  73. }
  74. else copyOfElementList.splice(minIndex - 1, 0, ...movedElementList)
  75. }
  76. else {
  77. const elementIndex = elementList.findIndex(item => item.id === element.id)
  78. if(elementIndex === 0) return null
  79. const prevElement = copyOfElementList[elementIndex - 1]
  80. const movedElement = copyOfElementList.splice(elementIndex, 1)[0]
  81. if(prevElement.groupId) {
  82. const combineElementList = copyOfElementList.filter(_element => _element.groupId === prevElement.groupId)
  83. copyOfElementList.splice(elementIndex - combineElementList.length, 0, movedElement)
  84. }
  85. else copyOfElementList.splice(elementIndex - 1, 0, movedElement)
  86. }
  87. return copyOfElementList
  88. }
  89. // 置顶层,返回移动后新的元素列表(置底层逻辑类似)
  90. const moveTopElement = (elementList: PPTElement[], element: PPTElement) => {
  91. const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList))
  92. // 被操作的元素是组合元素成员
  93. if(element.groupId) {
  94. // 获取该组合元素全部成员,以及组合元素层级范围
  95. const combineElementList = copyOfElementList.filter(_element => _element.groupId === element.groupId)
  96. const { minIndex, maxIndex } = getCombineElementIndexRange(elementList, combineElementList)
  97. // 无法移动(已经处在顶层)
  98. if(maxIndex === elementList.length - 1) return null
  99. // 从元素列表中移除该组合元素全部成员,然后添加到元素列表最上方
  100. const movedElementList = copyOfElementList.splice(minIndex, combineElementList.length)
  101. copyOfElementList.push(...movedElementList)
  102. }
  103. // 被操作的元素是单独的元素(非组合成员)
  104. else {
  105. // 元素在元素列表中的层级
  106. const elementIndex = elementList.findIndex(item => item.id === element.id)
  107. // 无法移动(已经处在顶层)
  108. if(elementIndex === elementList.length - 1) return null
  109. // 从元素列表中移除该元素,然后添加到元素列表最上方
  110. copyOfElementList.splice(elementIndex, 1)
  111. copyOfElementList.push(element)
  112. }
  113. return copyOfElementList
  114. }
  115. // 置底层
  116. const moveBottomElement = (elementList: PPTElement[], element: PPTElement) => {
  117. const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList))
  118. if(element.groupId) {
  119. const combineElementList = copyOfElementList.filter(_element => _element.groupId === element.groupId)
  120. const { minIndex } = getCombineElementIndexRange(elementList, combineElementList)
  121. if(minIndex === 0) return null
  122. const movedElementList = copyOfElementList.splice(minIndex, combineElementList.length)
  123. copyOfElementList.unshift(...movedElementList)
  124. }
  125. else {
  126. const elementIndex = elementList.findIndex(item => item.id === element.id)
  127. if(elementIndex === 0) return null
  128. copyOfElementList.splice(elementIndex, 1)
  129. copyOfElementList.unshift(element)
  130. }
  131. return copyOfElementList
  132. }
  133. const orderElement = (element: PPTElement, command: ElementOrderCommand) => {
  134. let newElementList = null
  135. if(command === ElementOrderCommands.UP) newElementList = moveUpElement(currentSlide.value.elements, element)
  136. else if(command === ElementOrderCommands.DOWN) newElementList = moveDownElement(currentSlide.value.elements, element)
  137. else if(command === ElementOrderCommands.TOP) newElementList = moveTopElement(currentSlide.value.elements, element)
  138. else if(command === ElementOrderCommands.BOTTOM) newElementList = moveBottomElement(currentSlide.value.elements, element)
  139. store.commit(MutationTypes.UPDATE_SLIDE, { elements: newElementList })
  140. addHistorySnapshot()
  141. }
  142. return {
  143. orderElement,
  144. }
  145. }