tldraw/state/sessions/transform-single-session.ts

116 lines
2.7 KiB
TypeScript
Raw Normal View History

2021-05-19 09:35:00 +00:00
import { Data, TransformEdge, TransformCorner } from "types"
import * as vec from "utils/vec"
import BaseSession from "./base-session"
import commands from "state/commands"
import { current } from "immer"
2021-05-20 09:49:40 +00:00
import { getShapeUtils } from "lib/shape-utils"
2021-05-19 09:35:00 +00:00
import {
getTransformedBoundingBox,
getCommonBounds,
getRotatedCorners,
getTransformAnchor,
} from "utils/utils"
export default class TransformSingleSession extends BaseSession {
2021-05-19 21:24:41 +00:00
transformType: TransformEdge | TransformCorner
origin: number[]
scaleX = 1
scaleY = 1
2021-05-19 09:35:00 +00:00
snapshot: TransformSingleSnapshot
2021-05-19 21:24:41 +00:00
isCreating: boolean
2021-05-19 09:35:00 +00:00
constructor(
data: Data,
transformType: TransformCorner | TransformEdge,
2021-05-19 21:24:41 +00:00
point: number[],
isCreating = false
2021-05-19 09:35:00 +00:00
) {
super(data)
this.origin = point
this.transformType = transformType
this.snapshot = getTransformSingleSnapshot(data, transformType)
2021-05-19 21:24:41 +00:00
this.isCreating = isCreating
2021-05-19 09:35:00 +00:00
}
2021-05-21 07:42:56 +00:00
update(data: Data, point: number[], isAspectRatioLocked = false) {
const { transformType } = this
2021-05-19 09:35:00 +00:00
const { initialShapeBounds, currentPageId, initialShape, id } =
this.snapshot
2021-05-19 09:35:00 +00:00
const shape = data.document.pages[currentPageId].shapes[id]
2021-05-19 09:35:00 +00:00
const newBoundingBox = getTransformedBoundingBox(
initialShapeBounds,
transformType,
vec.vec(this.origin, point),
2021-05-21 07:42:56 +00:00
shape.rotation,
isAspectRatioLocked
2021-05-19 09:35:00 +00:00
)
this.scaleX = newBoundingBox.scaleX
this.scaleY = newBoundingBox.scaleY
2021-05-19 09:35:00 +00:00
getShapeUtils(shape).transformSingle(shape, newBoundingBox, {
initialShape,
type: this.transformType,
scaleX: this.scaleX,
scaleY: this.scaleY,
2021-05-19 09:35:00 +00:00
})
}
cancel(data: Data) {
const { id, initialShape, initialShapeBounds, currentPageId } =
this.snapshot
2021-05-19 09:35:00 +00:00
const { shapes } = data.document.pages[currentPageId]
const shape = shapes[id]
getShapeUtils(shape).transform(shape, initialShapeBounds, {
initialShape,
type: this.transformType,
scaleX: this.scaleX,
scaleY: this.scaleY,
})
2021-05-19 09:35:00 +00:00
}
complete(data: Data) {
commands.transformSingle(
data,
this.snapshot,
getTransformSingleSnapshot(data, this.transformType),
this.scaleX,
2021-05-19 21:24:41 +00:00
this.scaleY,
this.isCreating
2021-05-19 09:35:00 +00:00
)
}
}
export function getTransformSingleSnapshot(
data: Data,
transformType: TransformEdge | TransformCorner
) {
const {
document: { pages },
selectedIds,
currentPageId,
} = current(data)
const id = Array.from(selectedIds)[0]
const shape = pages[currentPageId].shapes[id]
2021-05-19 09:35:00 +00:00
const bounds = getShapeUtils(shape).getBounds(shape)
return {
id,
currentPageId,
type: transformType,
initialShape: shape,
initialShapeBounds: bounds,
2021-05-19 09:35:00 +00:00
}
}
export type TransformSingleSnapshot = ReturnType<
typeof getTransformSingleSnapshot
>