tldraw/state/commands/ungroup.ts

100 lines
2.9 KiB
TypeScript
Raw Normal View History

2021-06-04 16:08:43 +00:00
import Command from './command'
import history from '../history'
2021-06-19 17:22:46 +00:00
import { Data, ShapeType } from 'types'
2021-06-21 21:35:28 +00:00
import { getShapeUtils } from 'state/shape-utils'
2021-06-29 12:00:59 +00:00
import tld from 'utils/tld'
import { deepClone } from 'utils'
2021-06-04 16:08:43 +00:00
2021-06-21 21:35:28 +00:00
export default function ungroupCommand(data: Data): void {
2021-06-29 12:00:59 +00:00
const { currentPageId } = data
2021-06-04 16:08:43 +00:00
2021-06-29 12:00:59 +00:00
const selectedGroups = tld
.getSelectedShapes(data)
2021-06-04 16:08:43 +00:00
.filter((shape) => shape.type === ShapeType.Group)
.sort((a, b) => a.childIndex - b.childIndex)
2021-06-29 12:00:59 +00:00
.map((shape) => deepClone(shape))
2021-06-04 16:08:43 +00:00
// Are all of the shapes already in the same group?
// - ungroup the shapes
// Otherwise...
// - remove the shapes from any existing group and add them to a new one
history.execute(
data,
new Command({
name: 'ungroup_shapes',
category: 'canvas',
do(data) {
2021-06-29 12:00:59 +00:00
const { shapes } = tld.getPage(data)
2021-06-04 16:08:43 +00:00
// Remove shapes from old parents
for (const oldGroupShape of selectedGroups) {
const siblings = (
oldGroupShape.parentId === currentPageId
? Object.values(shapes).filter(
(shape) => shape.parentId === currentPageId
)
: shapes[oldGroupShape.parentId].children.map((id) => shapes[id])
).sort((a, b) => a.childIndex - b.childIndex)
const trueIndex = siblings.findIndex((s) => s.id === oldGroupShape.id)
let step: number
if (trueIndex === siblings.length - 1) {
step = 1
} else {
step =
(siblings[trueIndex + 1].childIndex - oldGroupShape.childIndex) /
(oldGroupShape.children.length + 1)
}
// Move shapes to page
oldGroupShape.children
.map((id) => shapes[id])
.forEach(({ id }, i) => {
const shape = shapes[id]
getShapeUtils(shape)
.setProperty(shape, 'parentId', oldGroupShape.parentId)
.setProperty(
shape,
'childIndex',
oldGroupShape.childIndex + step * i
)
})
2021-06-29 12:00:59 +00:00
tld.setSelectedIds(data, oldGroupShape.children)
2021-06-04 16:08:43 +00:00
delete shapes[oldGroupShape.id]
}
},
undo(data) {
2021-06-29 12:00:59 +00:00
const { shapes } = tld.getPage(data)
2021-06-04 16:08:43 +00:00
selectedGroups.forEach((group) => {
shapes[group.id] = group
group.children.forEach((id, i) => {
const shape = shapes[id]
getShapeUtils(shape)
.setProperty(shape, 'parentId', group.id)
.setProperty(shape, 'childIndex', i)
})
})
2021-06-29 12:00:59 +00:00
tld.setSelectedIds(
data,
selectedGroups.map((g) => g.id)
)
2021-06-04 16:08:43 +00:00
},
})
)
}
2021-06-21 21:35:28 +00:00
// function getShapeDepth(data: Data, id: string, depth = 0) {
// if (id === data.currentPageId) {
// return depth
// }
2021-06-04 16:08:43 +00:00
2021-06-29 12:00:59 +00:00
// return getShapeDepth(data, tld.getShape(data, id).parentId, depth + 1)
2021-06-21 21:35:28 +00:00
// }