You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import Command from './command'
  2. import history from '../history'
  3. import { AlignType, Data } from 'types'
  4. import { getCommonBounds, getPage, getSelectedShapes } from 'utils'
  5. import { getShapeUtils } from 'state/shape-utils'
  6. export default function alignCommand(data: Data, type: AlignType): void {
  7. const selectedShapes = getSelectedShapes(data)
  8. const entries = selectedShapes.map(
  9. (shape) => [shape.id, getShapeUtils(shape).getBounds(shape)] as const
  10. )
  11. const boundsForShapes = Object.fromEntries(entries)
  12. const commonBounds = getCommonBounds(...entries.map((entry) => entry[1]))
  13. const midX = commonBounds.minX + commonBounds.width / 2
  14. const midY = commonBounds.minY + commonBounds.height / 2
  15. history.execute(
  16. data,
  17. new Command({
  18. name: 'aligned',
  19. category: 'canvas',
  20. do(data) {
  21. const { shapes } = getPage(data)
  22. switch (type) {
  23. case AlignType.Top: {
  24. for (const id in boundsForShapes) {
  25. const shape = shapes[id]
  26. getShapeUtils(shape).translateTo(shape, [
  27. shape.point[0],
  28. commonBounds.minY,
  29. ])
  30. }
  31. break
  32. }
  33. case AlignType.CenterVertical: {
  34. for (const id in boundsForShapes) {
  35. const shape = shapes[id]
  36. getShapeUtils(shape).translateTo(shape, [
  37. shape.point[0],
  38. midY - boundsForShapes[id].height / 2,
  39. ])
  40. }
  41. break
  42. }
  43. case AlignType.Bottom: {
  44. for (const id in boundsForShapes) {
  45. const shape = shapes[id]
  46. getShapeUtils(shape).translateTo(shape, [
  47. shape.point[0],
  48. commonBounds.maxY - boundsForShapes[id].height,
  49. ])
  50. }
  51. break
  52. }
  53. case AlignType.Left: {
  54. for (const id in boundsForShapes) {
  55. const shape = shapes[id]
  56. getShapeUtils(shape).translateTo(shape, [
  57. commonBounds.minX,
  58. shape.point[1],
  59. ])
  60. }
  61. break
  62. }
  63. case AlignType.CenterHorizontal: {
  64. for (const id in boundsForShapes) {
  65. const shape = shapes[id]
  66. getShapeUtils(shape).translateTo(shape, [
  67. midX - boundsForShapes[id].width / 2,
  68. shape.point[1],
  69. ])
  70. }
  71. break
  72. }
  73. case AlignType.Right: {
  74. for (const id in boundsForShapes) {
  75. const shape = shapes[id]
  76. getShapeUtils(shape).translateTo(shape, [
  77. commonBounds.maxX - boundsForShapes[id].width,
  78. shape.point[1],
  79. ])
  80. }
  81. break
  82. }
  83. }
  84. },
  85. undo(data) {
  86. const { shapes } = getPage(data)
  87. for (const id in boundsForShapes) {
  88. const shape = shapes[id]
  89. const initialBounds = boundsForShapes[id]
  90. getShapeUtils(shape).translateTo(shape, [
  91. initialBounds.minX,
  92. initialBounds.minY,
  93. ])
  94. }
  95. },
  96. })
  97. )
  98. }