@tldraw/editor
Version:
tldraw infinite canvas SDK (editor).
80 lines (79 loc) • 2.69 kB
JavaScript
import { isShapeId } from "@tldraw/tlschema";
import { compact } from "@tldraw/utils";
import { Mat } from "../primitives/Mat.mjs";
import { canonicalizeRotation } from "../primitives/utils.mjs";
import { Vec } from "../primitives/Vec.mjs";
function getRotationSnapshot({
editor,
ids
}) {
const shapes = compact(ids.map((id) => editor.getShape(id)));
const rotation = editor.getShapesSharedRotation(ids);
const rotatedPageBounds = editor.getShapesRotatedPageBounds(ids);
if (!rotatedPageBounds) {
return null;
}
const initialPageCenter = rotatedPageBounds.center.clone().rotWith(rotatedPageBounds.point, rotation);
return {
initialPageCenter,
initialCursorAngle: initialPageCenter.angle(editor.inputs.originPagePoint),
initialShapesRotation: rotation,
shapeSnapshots: shapes.map((shape) => ({
shape,
initialPagePoint: editor.getShapePageTransform(shape.id).point()
}))
};
}
function applyRotationToSnapshotShapes({
delta,
editor,
snapshot,
stage,
centerOverride
}) {
const { initialPageCenter, shapeSnapshots } = snapshot;
editor.updateShapes(
shapeSnapshots.map(({ shape, initialPagePoint }) => {
const parentTransform = isShapeId(shape.parentId) ? editor.getShapePageTransform(shape.parentId) : Mat.Identity();
const newPagePoint = Vec.RotWith(initialPagePoint, centerOverride ?? initialPageCenter, delta);
const newLocalPoint = Mat.applyToPoint(
// use the current parent transform in case it has moved/resized since the start
// (e.g. if rotating a shape at the edge of a group)
Mat.Inverse(parentTransform),
newPagePoint
);
const newRotation = canonicalizeRotation(shape.rotation + delta);
return {
id: shape.id,
type: shape.type,
x: newLocalPoint.x,
y: newLocalPoint.y,
rotation: newRotation
};
})
);
const changes = [];
shapeSnapshots.forEach(({ shape }) => {
const current = editor.getShape(shape.id);
if (!current) return;
const util = editor.getShapeUtil(shape);
if (stage === "start" || stage === "one-off") {
const changeStart = util.onRotateStart?.(shape);
if (changeStart) changes.push(changeStart);
}
const changeUpdate = util.onRotate?.(shape, current);
if (changeUpdate) changes.push(changeUpdate);
if (stage === "end" || stage === "one-off") {
const changeEnd = util.onRotateEnd?.(shape, current);
if (changeEnd) changes.push(changeEnd);
}
});
if (changes.length > 0) {
editor.updateShapes(changes);
}
}
export {
applyRotationToSnapshotShapes,
getRotationSnapshot
};
//# sourceMappingURL=rotation.mjs.map