Tldraw/packages/tldraw/src/state/commands/styleShapes/styleShapes.ts

103 wiersze
2.4 KiB
TypeScript

import {
ShapeStyles,
TLDrawCommand,
TLDrawSnapshot,
TLDrawShape,
TLDrawShapeType,
TextShape,
} from '~types'
import { TLDR } from '~state/TLDR'
import type { Patch } from 'rko'
import Vec from '@tldraw/vec'
export function styleShapes(
data: TLDrawSnapshot,
ids: string[],
changes: Partial<ShapeStyles>
): TLDrawCommand {
const { currentPageId } = data.appState
const shapeIdsToMutate = ids.flatMap((id) => TLDR.getDocumentBranch(data, id, currentPageId))
// const { before, after } = TLDR.mutateShapes(
// data,
// shapeIdsToMutate,
// (shape) => ({ style: { ...shape.style, ...changes } }),
// currentPageId
// )
const beforeShapes: Record<string, Patch<TLDrawShape>> = {}
const afterShapes: Record<string, Patch<TLDrawShape>> = {}
shapeIdsToMutate
.map((id) => TLDR.getShape(data, id, currentPageId))
.filter((shape) => !shape.isLocked)
.forEach((shape) => {
beforeShapes[shape.id] = {
style: {
...Object.fromEntries(
Object.keys(changes).map((key) => [key, shape.style[key as keyof typeof shape.style]])
),
},
}
afterShapes[shape.id] = {
style: changes,
}
if (shape.type === TLDrawShapeType.Text) {
beforeShapes[shape.id].point = shape.point
afterShapes[shape.id].point = Vec.round(
Vec.add(
shape.point,
Vec.sub(
TLDR.getShapeUtils(shape).getCenter(shape),
TLDR.getShapeUtils(shape).getCenter({
...shape,
style: { ...shape.style, ...changes },
} as TextShape)
)
)
)
}
})
return {
id: 'style',
before: {
document: {
pages: {
[currentPageId]: {
shapes: beforeShapes,
},
},
pageStates: {
[currentPageId]: {
selectedIds: ids,
},
},
},
appState: {
currentStyle: { ...data.appState.currentStyle },
},
},
after: {
document: {
pages: {
[currentPageId]: {
shapes: afterShapes,
},
},
pageStates: {
[currentPageId]: {
selectedIds: ids,
},
},
},
appState: {
currentStyle: { ...data.appState.currentStyle, ...changes },
},
},
}
}