useCombineElement.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  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 { createRandomCode } from '@/utils/common'
  6. import useHistorySnapshot from '@/hooks/useHistorySnapshot'
  7. export default () => {
  8. const store = useStore<State>()
  9. const activeElementIdList = computed(() => store.state.activeElementIdList)
  10. const activeElementList: Ref<PPTElement[]> = computed(() => store.getters.activeElementList)
  11. const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
  12. const { addHistorySnapshot } = useHistorySnapshot()
  13. // 组合元素(为当前所有激活元素添加一个相同的groupId)
  14. const combineElements = () => {
  15. if(!activeElementList.value.length) return
  16. let newElementList: PPTElement[] = JSON.parse(JSON.stringify(currentSlide.value.elements))
  17. const groupId = createRandomCode()
  18. const combineElementList: PPTElement[] = []
  19. for(const element of newElementList) {
  20. if(activeElementIdList.value.includes(element.id)) {
  21. element.groupId = groupId
  22. combineElementList.push(element)
  23. }
  24. }
  25. // 注意,组合元素的层级应该是连续的,所以需要获取该组元素中最顶层的元素,将组内其他成员从原位置移动到最顶层的元素的下面
  26. const combineElementMaxIndex = newElementList.findIndex(_element => _element.id === combineElementList[combineElementList.length - 1].id)
  27. const combineElementIdList = combineElementList.map(_element => _element.id)
  28. newElementList = newElementList.filter(_element => !combineElementIdList.includes(_element.id))
  29. const insertIndex = combineElementMaxIndex - combineElementList.length + 1
  30. newElementList.splice(insertIndex, 0, ...combineElementList)
  31. store.commit(MutationTypes.UPDATE_SLIDE, { elements: newElementList })
  32. addHistorySnapshot()
  33. }
  34. // 取消组合元素(移除所有被激活元素的groupId)
  35. const uncombineElements = () => {
  36. if(!activeElementList.value.length) return
  37. const hasElementInGroup = activeElementList.value.some(item => item.groupId)
  38. if(!hasElementInGroup) return
  39. const newElementList: PPTElement[] = JSON.parse(JSON.stringify(currentSlide.value.elements))
  40. for(const element of newElementList) {
  41. if(activeElementIdList.value.includes(element.id) && element.groupId) delete element.groupId
  42. }
  43. store.commit(MutationTypes.UPDATE_SLIDE, { elements: newElementList })
  44. addHistorySnapshot()
  45. }
  46. return {
  47. combineElements,
  48. uncombineElements,
  49. }
  50. }