Transforming rotated items
This commit is contained in:
parent
1ece606db0
commit
da8f812090
5 changed files with 91 additions and 14 deletions
|
@ -73,6 +73,8 @@ const ellipse = createShape<EllipseShape>({
|
||||||
},
|
},
|
||||||
|
|
||||||
hitTestBounds(this, shape, brushBounds) {
|
hitTestBounds(this, shape, brushBounds) {
|
||||||
|
// TODO: Account for rotation
|
||||||
|
|
||||||
const shapeBounds = this.getBounds(shape)
|
const shapeBounds = this.getBounds(shape)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -61,11 +61,13 @@ export interface ShapeUtility<K extends Shape> {
|
||||||
bounds: Bounds,
|
bounds: Bounds,
|
||||||
info: {
|
info: {
|
||||||
type: TransformEdge | TransformCorner
|
type: TransformEdge | TransformCorner
|
||||||
|
boundsRotation: number
|
||||||
initialShape: K
|
initialShape: K
|
||||||
initialShapeBounds: BoundsSnapshot
|
initialShapeBounds: BoundsSnapshot
|
||||||
initialBounds: Bounds
|
initialBounds: Bounds
|
||||||
isFlippedX: boolean
|
isFlippedX: boolean
|
||||||
isFlippedY: boolean
|
isFlippedY: boolean
|
||||||
|
isSingle: boolean
|
||||||
anchor: TransformEdge | TransformCorner
|
anchor: TransformEdge | TransformCorner
|
||||||
}
|
}
|
||||||
): K
|
): K
|
||||||
|
|
|
@ -103,9 +103,44 @@ const rectangle = createShape<RectangleShape>({
|
||||||
return shape
|
return shape
|
||||||
},
|
},
|
||||||
|
|
||||||
transform(shape, bounds) {
|
transform(
|
||||||
shape.point = [bounds.minX, bounds.minY]
|
shape,
|
||||||
shape.size = [bounds.width, bounds.height]
|
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
|
return shape
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,6 +22,8 @@ export default function translateCommand(
|
||||||
initialBounds,
|
initialBounds,
|
||||||
currentPageId,
|
currentPageId,
|
||||||
selectedIds,
|
selectedIds,
|
||||||
|
isSingle,
|
||||||
|
boundsRotation,
|
||||||
} = after
|
} = after
|
||||||
|
|
||||||
const { shapes } = data.document.pages[currentPageId]
|
const { shapes } = data.document.pages[currentPageId]
|
||||||
|
@ -35,8 +37,10 @@ export default function translateCommand(
|
||||||
initialShape,
|
initialShape,
|
||||||
initialShapeBounds,
|
initialShapeBounds,
|
||||||
initialBounds,
|
initialBounds,
|
||||||
|
boundsRotation,
|
||||||
isFlippedX: false,
|
isFlippedX: false,
|
||||||
isFlippedY: false,
|
isFlippedY: false,
|
||||||
|
isSingle,
|
||||||
anchor,
|
anchor,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -48,6 +52,8 @@ export default function translateCommand(
|
||||||
initialBounds,
|
initialBounds,
|
||||||
currentPageId,
|
currentPageId,
|
||||||
selectedIds,
|
selectedIds,
|
||||||
|
isSingle,
|
||||||
|
boundsRotation,
|
||||||
} = before
|
} = before
|
||||||
|
|
||||||
const { shapes } = data.document.pages[currentPageId]
|
const { shapes } = data.document.pages[currentPageId]
|
||||||
|
@ -61,8 +67,10 @@ export default function translateCommand(
|
||||||
initialShape,
|
initialShape,
|
||||||
initialShapeBounds,
|
initialShapeBounds,
|
||||||
initialBounds,
|
initialBounds,
|
||||||
|
boundsRotation,
|
||||||
isFlippedX: false,
|
isFlippedX: false,
|
||||||
isFlippedY: false,
|
isFlippedY: false,
|
||||||
|
isSingle,
|
||||||
anchor: type,
|
anchor: type,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -32,6 +32,18 @@ export default class TransformSession extends BaseSession {
|
||||||
super(data)
|
super(data)
|
||||||
this.origin = point
|
this.origin = point
|
||||||
this.transformType = transformType
|
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)
|
this.snapshot = getTransformSnapshot(data, transformType)
|
||||||
|
|
||||||
const { minX, minY, maxX, maxY } = this.snapshot.initialBounds
|
const { minX, minY, maxX, maxY } = this.snapshot.initialBounds
|
||||||
|
@ -43,21 +55,26 @@ export default class TransformSession extends BaseSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
update(data: Data, point: number[]) {
|
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 {
|
const {
|
||||||
corners: { a, b },
|
corners: { a, b },
|
||||||
transformType,
|
transformType,
|
||||||
} = this
|
} = 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
|
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
|
bounding box. Depending on what the user is dragging, change one or both
|
||||||
|
@ -153,8 +170,10 @@ export default class TransformSession extends BaseSession {
|
||||||
initialShape,
|
initialShape,
|
||||||
initialShapeBounds,
|
initialShapeBounds,
|
||||||
initialBounds,
|
initialBounds,
|
||||||
|
boundsRotation,
|
||||||
isFlippedX: this.isFlippedX,
|
isFlippedX: this.isFlippedX,
|
||||||
isFlippedY: this.isFlippedY,
|
isFlippedY: this.isFlippedY,
|
||||||
|
isSingle,
|
||||||
anchor: getTransformAnchor(
|
anchor: getTransformAnchor(
|
||||||
this.transformType,
|
this.transformType,
|
||||||
this.isFlippedX,
|
this.isFlippedX,
|
||||||
|
@ -165,8 +184,14 @@ export default class TransformSession extends BaseSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel(data: Data) {
|
cancel(data: Data) {
|
||||||
const { shapeBounds, initialBounds, currentPageId, selectedIds } =
|
const {
|
||||||
this.snapshot
|
shapeBounds,
|
||||||
|
boundsRotation,
|
||||||
|
initialBounds,
|
||||||
|
currentPageId,
|
||||||
|
selectedIds,
|
||||||
|
isSingle,
|
||||||
|
} = this.snapshot
|
||||||
|
|
||||||
const { shapes } = data.document.pages[currentPageId]
|
const { shapes } = data.document.pages[currentPageId]
|
||||||
|
|
||||||
|
@ -180,8 +205,10 @@ export default class TransformSession extends BaseSession {
|
||||||
initialShape,
|
initialShape,
|
||||||
initialShapeBounds,
|
initialShapeBounds,
|
||||||
initialBounds,
|
initialBounds,
|
||||||
|
boundsRotation,
|
||||||
isFlippedX: false,
|
isFlippedX: false,
|
||||||
isFlippedY: false,
|
isFlippedY: false,
|
||||||
|
isSingle,
|
||||||
anchor: getTransformAnchor(this.transformType, false, false),
|
anchor: getTransformAnchor(this.transformType, false, false),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -205,6 +232,7 @@ export function getTransformSnapshot(
|
||||||
document: { pages },
|
document: { pages },
|
||||||
selectedIds,
|
selectedIds,
|
||||||
currentPageId,
|
currentPageId,
|
||||||
|
boundsRotation,
|
||||||
} = current(data)
|
} = current(data)
|
||||||
|
|
||||||
const pageShapes = pages[currentPageId].shapes
|
const pageShapes = pages[currentPageId].shapes
|
||||||
|
@ -226,6 +254,8 @@ export function getTransformSnapshot(
|
||||||
currentPageId,
|
currentPageId,
|
||||||
type: transformType,
|
type: transformType,
|
||||||
initialBounds: bounds,
|
initialBounds: bounds,
|
||||||
|
boundsRotation,
|
||||||
|
isSingle: selectedIds.size === 1,
|
||||||
selectedIds: new Set(selectedIds),
|
selectedIds: new Set(selectedIds),
|
||||||
shapeBounds: Object.fromEntries(
|
shapeBounds: Object.fromEntries(
|
||||||
Array.from(selectedIds.values()).map((id) => {
|
Array.from(selectedIds.values()).map((id) => {
|
||||||
|
|
Loading…
Reference in a new issue