tldraw/state/commands/paste.ts

70 lines
1.9 KiB
TypeScript
Raw Normal View History

2021-06-18 10:14:23 +00:00
import Command from './command'
import history from '../history'
import { Data, Shape } from 'types'
2021-06-29 12:00:59 +00:00
import { getCommonBounds, setToArray } from 'utils'
import tld from 'utils/tld'
import { uniqueId } from 'utils/utils'
2021-06-18 10:14:23 +00:00
import vec from 'utils/vec'
2021-06-21 21:35:28 +00:00
import { getShapeUtils } from 'state/shape-utils'
2021-06-18 10:14:23 +00:00
import state from 'state/state'
2021-06-21 21:35:28 +00:00
export default function pasteCommand(data: Data, initialShapes: Shape[]): void {
2021-06-29 12:00:59 +00:00
const center = tld.screenToWorld(
2021-06-18 10:14:23 +00:00
[window.innerWidth / 2, window.innerHeight / 2],
data
)
const bounds = getCommonBounds(
...initialShapes.map((shape) =>
getShapeUtils(shape).getRotatedBounds(shape)
)
)
const topLeft = vec.sub(center, [bounds.width / 2, bounds.height / 2])
const newIdMap = Object.fromEntries(
initialShapes.map((shape) => [shape.id, uniqueId()])
)
2021-06-29 12:00:59 +00:00
const oldSelectedIds = setToArray(tld.getSelectedIds(data))
2021-06-18 10:14:23 +00:00
history.execute(
data,
new Command({
2021-06-19 17:22:46 +00:00
name: 'paste_new_shapes',
2021-06-18 10:14:23 +00:00
category: 'canvas',
manualSelection: true,
do(data) {
2021-06-29 12:00:59 +00:00
const { shapes } = tld.getPage(data)
2021-06-18 10:14:23 +00:00
let childIndex =
(state.values.currentShapes[state.values.currentShapes.length - 1]
?.childIndex || 0) + 1
for (const shape of initialShapes) {
const topLeftOffset = vec.sub(shape.point, [bounds.minX, bounds.minY])
const newId = newIdMap[shape.id]
shapes[newId] = {
...shape,
id: newId,
parentId: oldSelectedIds[shape.parentId] || data.currentPageId,
childIndex: childIndex++,
point: vec.add(topLeft, topLeftOffset),
}
}
2021-06-29 12:00:59 +00:00
tld.setSelectedIds(data, Object.values(newIdMap))
2021-06-18 10:14:23 +00:00
},
undo(data) {
2021-06-29 12:00:59 +00:00
const { shapes } = tld.getPage(data)
2021-06-18 10:14:23 +00:00
Object.values(newIdMap).forEach((id) => delete shapes[id])
2021-06-29 12:00:59 +00:00
tld.setSelectedIds(data, oldSelectedIds)
2021-06-18 10:14:23 +00:00
},
})
)
}