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.

ungroup.ts 2.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import Command from './command'
  2. import history from '../history'
  3. import { Data, ShapeType } from 'types'
  4. import { getPage, getSelectedShapes, setSelectedIds } from 'utils/utils'
  5. import { current } from 'immer'
  6. import { getShapeUtils } from 'state/shape-utils'
  7. export default function ungroupCommand(data: Data): void {
  8. const cData = current(data)
  9. const { currentPageId } = cData
  10. const selectedGroups = getSelectedShapes(cData)
  11. .filter((shape) => shape.type === ShapeType.Group)
  12. .sort((a, b) => a.childIndex - b.childIndex)
  13. // Are all of the shapes already in the same group?
  14. // - ungroup the shapes
  15. // Otherwise...
  16. // - remove the shapes from any existing group and add them to a new one
  17. history.execute(
  18. data,
  19. new Command({
  20. name: 'ungroup_shapes',
  21. category: 'canvas',
  22. do(data) {
  23. const { shapes } = getPage(data)
  24. // Remove shapes from old parents
  25. for (const oldGroupShape of selectedGroups) {
  26. const siblings = (
  27. oldGroupShape.parentId === currentPageId
  28. ? Object.values(shapes).filter(
  29. (shape) => shape.parentId === currentPageId
  30. )
  31. : shapes[oldGroupShape.parentId].children.map((id) => shapes[id])
  32. ).sort((a, b) => a.childIndex - b.childIndex)
  33. const trueIndex = siblings.findIndex((s) => s.id === oldGroupShape.id)
  34. let step: number
  35. if (trueIndex === siblings.length - 1) {
  36. step = 1
  37. } else {
  38. step =
  39. (siblings[trueIndex + 1].childIndex - oldGroupShape.childIndex) /
  40. (oldGroupShape.children.length + 1)
  41. }
  42. // Move shapes to page
  43. oldGroupShape.children
  44. .map((id) => shapes[id])
  45. .forEach(({ id }, i) => {
  46. const shape = shapes[id]
  47. getShapeUtils(shape)
  48. .setProperty(shape, 'parentId', oldGroupShape.parentId)
  49. .setProperty(
  50. shape,
  51. 'childIndex',
  52. oldGroupShape.childIndex + step * i
  53. )
  54. })
  55. setSelectedIds(data, oldGroupShape.children)
  56. delete shapes[oldGroupShape.id]
  57. }
  58. },
  59. undo(data) {
  60. const { shapes } = getPage(data, currentPageId)
  61. selectedGroups.forEach((group) => {
  62. shapes[group.id] = group
  63. group.children.forEach((id, i) => {
  64. const shape = shapes[id]
  65. getShapeUtils(shape)
  66. .setProperty(shape, 'parentId', group.id)
  67. .setProperty(shape, 'childIndex', i)
  68. })
  69. })
  70. setSelectedIds(
  71. data,
  72. selectedGroups.map((g) => g.id)
  73. )
  74. },
  75. })
  76. )
  77. }
  78. // function getShapeDepth(data: Data, id: string, depth = 0) {
  79. // if (id === data.currentPageId) {
  80. // return depth
  81. // }
  82. // return getShapeDepth(data, getShape(data, id).parentId, depth + 1)
  83. // }