Transforming rotated items

This commit is contained in:
Steve Ruiz 2021-05-18 11:45:29 +01:00
parent 1ece606db0
commit da8f812090
5 changed files with 91 additions and 14 deletions

View file

@ -73,6 +73,8 @@ const ellipse = createShape<EllipseShape>({
},
hitTestBounds(this, shape, brushBounds) {
// TODO: Account for rotation
const shapeBounds = this.getBounds(shape)
return (

View file

@ -61,11 +61,13 @@ export interface ShapeUtility<K extends Shape> {
bounds: Bounds,
info: {
type: TransformEdge | TransformCorner
boundsRotation: number
initialShape: K
initialShapeBounds: BoundsSnapshot
initialBounds: Bounds
isFlippedX: boolean
isFlippedY: boolean
isSingle: boolean
anchor: TransformEdge | TransformCorner
}
): K

View file

@ -103,9 +103,44 @@ const rectangle = createShape<RectangleShape>({
return shape
},
transform(shape, bounds) {
shape.point = [bounds.minX, bounds.minY]
shape.size = [bounds.width, bounds.height]
transform(
shape,
shapeBounds,
{ initialShape, isSingle, initialShapeBounds, isFlippedX, isFlippedY }
) {
// TODO: Apply rotation to single-selection items
if (shape.rotation === 0 || isSingle) {
shape.size = [shapeBounds.width, shapeBounds.height]
shape.point = [shapeBounds.minX, shapeBounds.minY]
} else {
shape.size = vec.mul(
initialShape.size,
Math.min(
shapeBounds.width / initialShapeBounds.width,
shapeBounds.height / initialShapeBounds.height
)
)
const newCenter = [
shapeBounds.minX + shapeBounds.width / 2,
shapeBounds.minY + shapeBounds.height / 2,
]
shape.point = vec.sub(newCenter, vec.div(shape.size, 2))
}
// Rotation for flipped shapes
shape.rotation = initialShape.rotation
if (isFlippedX) {
shape.rotation *= -1
}
if (isFlippedY) {
shape.rotation *= -1
}
return shape
},

View file

@ -22,6 +22,8 @@ export default function translateCommand(
initialBounds,
currentPageId,
selectedIds,
isSingle,
boundsRotation,
} = after
const { shapes } = data.document.pages[currentPageId]
@ -35,8 +37,10 @@ export default function translateCommand(
initialShape,
initialShapeBounds,
initialBounds,
boundsRotation,
isFlippedX: false,
isFlippedY: false,
isSingle,
anchor,
})
})
@ -48,6 +52,8 @@ export default function translateCommand(
initialBounds,
currentPageId,
selectedIds,
isSingle,
boundsRotation,
} = before
const { shapes } = data.document.pages[currentPageId]
@ -61,8 +67,10 @@ export default function translateCommand(
initialShape,
initialShapeBounds,
initialBounds,
boundsRotation,
isFlippedX: false,
isFlippedY: false,
isSingle,
anchor: type,
})
})

View file

@ -32,6 +32,18 @@ export default class TransformSession extends BaseSession {
super(data)
this.origin = point
this.transformType = transformType
// if (data.selectedIds.size === 1) {
// const shape =
// data.document.pages[data.currentPageId].shapes[
// Array.from(data.selectedIds.values())[0]
// ]
// if (shape.rotation > 0) {
// }
// }
this.snapshot = getTransformSnapshot(data, transformType)
const { minX, minY, maxX, maxY } = this.snapshot.initialBounds
@ -43,21 +55,26 @@ export default class TransformSession extends BaseSession {
}
update(data: Data, point: number[]) {
const { shapeBounds, initialBounds, currentPageId, selectedIds } =
this.snapshot
const { shapes } = data.document.pages[currentPageId]
const delta = vec.vec(this.origin, point)
const {
corners: { a, b },
transformType,
} = this
// Edge Transform
const {
boundsRotation,
shapeBounds,
initialBounds,
currentPageId,
selectedIds,
isSingle,
} = this.snapshot
const { shapes } = data.document.pages[currentPageId]
const delta = vec.vec(this.origin, point)
/*
Edge transform
Transforms
Corners a and b are the original top-left and bottom-right corners of the
bounding box. Depending on what the user is dragging, change one or both
@ -153,8 +170,10 @@ export default class TransformSession extends BaseSession {
initialShape,
initialShapeBounds,
initialBounds,
boundsRotation,
isFlippedX: this.isFlippedX,
isFlippedY: this.isFlippedY,
isSingle,
anchor: getTransformAnchor(
this.transformType,
this.isFlippedX,
@ -165,8 +184,14 @@ export default class TransformSession extends BaseSession {
}
cancel(data: Data) {
const { shapeBounds, initialBounds, currentPageId, selectedIds } =
this.snapshot
const {
shapeBounds,
boundsRotation,
initialBounds,
currentPageId,
selectedIds,
isSingle,
} = this.snapshot
const { shapes } = data.document.pages[currentPageId]
@ -180,8 +205,10 @@ export default class TransformSession extends BaseSession {
initialShape,
initialShapeBounds,
initialBounds,
boundsRotation,
isFlippedX: false,
isFlippedY: false,
isSingle,
anchor: getTransformAnchor(this.transformType, false, false),
})
})
@ -205,6 +232,7 @@ export function getTransformSnapshot(
document: { pages },
selectedIds,
currentPageId,
boundsRotation,
} = current(data)
const pageShapes = pages[currentPageId].shapes
@ -226,6 +254,8 @@ export function getTransformSnapshot(
currentPageId,
type: transformType,
initialBounds: bounds,
boundsRotation,
isSingle: selectedIds.size === 1,
selectedIds: new Set(selectedIds),
shapeBounds: Object.fromEntries(
Array.from(selectedIds.values()).map((id) => {