選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

align.ts 3.2KB

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