tldraw/state/commands/rotate-ccw.ts

100 lines
2.5 KiB
TypeScript
Raw Normal View History

2021-05-29 22:27:19 +00:00
import Command from './command'
import history from '../history'
import { Data } from 'types'
import {
getBoundsCenter,
getCommonBounds,
getPage,
getSelectedShapes,
2021-06-24 08:18:14 +00:00
} from 'utils'
import vec from 'utils/vec'
2021-06-21 21:35:28 +00:00
import { getShapeUtils } from 'state/shape-utils'
2021-05-29 22:27:19 +00:00
const PI2 = Math.PI * 2
2021-06-21 21:35:28 +00:00
export default function rotateCcwCommand(data: Data): void {
2021-05-29 22:27:19 +00:00
const { currentPageId, boundsRotation } = data
const page = getPage(data)
const initialShapes = Object.fromEntries(
getSelectedShapes(data).map((shape) => {
const bounds = getShapeUtils(shape).getBounds(shape)
return [
shape.id,
{
rotation: shape.rotation,
point: [...shape.point],
center: getBoundsCenter(bounds),
bounds,
},
]
})
)
const commonBoundsCenter = getBoundsCenter(
getCommonBounds(...Object.values(initialShapes).map((b) => b.bounds))
)
const nextShapes = Object.fromEntries(
Object.entries(initialShapes).map(([id, { point, center }]) => {
const shape = { ...page.shapes[id] }
const offset = vec.sub(center, point)
const nextPoint = vec.sub(
vec.rotWith(center, commonBoundsCenter, -(PI2 / 4)),
offset
)
const rot = (PI2 + (shape.rotation - PI2 / 4)) % PI2
2021-06-02 15:05:44 +00:00
getShapeUtils(shape)
.setProperty(shape, 'rotation', rot)
.setProperty(shape, 'point', nextPoint)
2021-05-29 22:27:19 +00:00
return [id, shape]
})
)
const nextboundsRotation = (PI2 + (data.boundsRotation - PI2 / 4)) % PI2
history.execute(
data,
new Command({
2021-06-19 17:22:46 +00:00
name: 'rotate_ccw',
2021-05-29 22:27:19 +00:00
category: 'canvas',
do(data) {
const { shapes } = getPage(data, currentPageId)
2021-06-21 21:35:28 +00:00
for (const id in nextShapes) {
2021-05-29 22:27:19 +00:00
const shape = shapes[id]
2021-06-18 15:31:46 +00:00
if (shape.isLocked) continue
2021-05-29 22:27:19 +00:00
getShapeUtils(shape)
2021-06-02 15:05:44 +00:00
.setProperty(shape, 'rotation', nextShapes[id].rotation)
.setProperty(shape, 'point', nextShapes[id].point)
2021-05-29 22:27:19 +00:00
}
data.boundsRotation = nextboundsRotation
},
undo(data) {
const { shapes } = getPage(data, currentPageId)
2021-06-21 21:35:28 +00:00
for (const id in initialShapes) {
2021-05-29 22:27:19 +00:00
const { point, rotation } = initialShapes[id]
const shape = shapes[id]
2021-06-18 15:31:46 +00:00
if (shape.isLocked) continue
2021-05-29 22:27:19 +00:00
const utils = getShapeUtils(shape)
2021-06-02 15:05:44 +00:00
utils
.setProperty(shape, 'rotation', rotation)
.setProperty(shape, 'point', point)
2021-05-29 22:27:19 +00:00
}
data.boundsRotation = boundsRotation
},
})
)
}