useAlignElementToCanvas.ts 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import { computed } from 'vue'
  2. import { MutationTypes, useStore } from '@/store'
  3. import { PPTElement, Slide } from '@/types/slides'
  4. import { ElementAlignCommand, ElementAlignCommands } from '@/types/edit'
  5. import { getElementListRange } from '@/utils/element'
  6. import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
  7. import useHistorySnapshot from './useHistorySnapshot'
  8. export default () => {
  9. const store = useStore()
  10. const activeElementIdList = computed(() => store.state.activeElementIdList)
  11. const activeElementList = computed<PPTElement[]>(() => store.getters.activeElementList)
  12. const currentSlide = computed<Slide>(() => store.getters.currentSlide)
  13. const { addHistorySnapshot } = useHistorySnapshot()
  14. /**
  15. * 将所有选中的元素对齐到画布
  16. * @param command 对齐方向
  17. */
  18. const alignElementToCanvas = (command: ElementAlignCommand) => {
  19. const viewportWidth = VIEWPORT_SIZE
  20. const viewportHeight = VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO
  21. const { minX, maxX, minY, maxY } = getElementListRange(activeElementList.value)
  22. const newElementList: PPTElement[] = JSON.parse(JSON.stringify(currentSlide.value.elements))
  23. for (const element of newElementList) {
  24. if (!activeElementIdList.value.includes(element.id)) continue
  25. // 水平垂直居中
  26. if (command === ElementAlignCommands.CENTER) {
  27. const offsetY = minY + (maxY - minY) / 2 - viewportHeight / 2
  28. const offsetX = minX + (maxX - minX) / 2 - viewportWidth / 2
  29. element.top = element.top - offsetY
  30. element.left = element.left - offsetX
  31. }
  32. // 顶部对齐
  33. if (command === ElementAlignCommands.TOP) {
  34. const offsetY = minY - 0
  35. element.top = element.top - offsetY
  36. }
  37. // 垂直居中
  38. else if (command === ElementAlignCommands.VERTICAL) {
  39. const offsetY = minY + (maxY - minY) / 2 - viewportHeight / 2
  40. element.top = element.top - offsetY
  41. }
  42. // 底部对齐
  43. else if (command === ElementAlignCommands.BOTTOM) {
  44. const offsetY = maxY - viewportHeight
  45. element.top = element.top - offsetY
  46. }
  47. // 左侧对齐
  48. else if (command === ElementAlignCommands.LEFT) {
  49. const offsetX = minX - 0
  50. element.left = element.left - offsetX
  51. }
  52. // 水平居中
  53. else if (command === ElementAlignCommands.HORIZONTAL) {
  54. const offsetX = minX + (maxX - minX) / 2 - viewportWidth / 2
  55. element.left = element.left - offsetX
  56. }
  57. // 右侧对齐
  58. else if (command === ElementAlignCommands.RIGHT) {
  59. const offsetX = maxX - viewportWidth
  60. element.left = element.left - offsetX
  61. }
  62. }
  63. store.commit(MutationTypes.UPDATE_SLIDE, { elements: newElementList })
  64. addHistorySnapshot()
  65. }
  66. return {
  67. alignElementToCanvas,
  68. }
  69. }