feat: element alignments - snapping (#6256)

Co-authored-by: Ryan Di <ryan.weihao.di@gmail.com>
Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
hugofqt 2023-09-28 16:28:08 +02:00 committed by GitHub
parent 4765f5536e
commit 4c35eba72d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 2295 additions and 87 deletions

View file

@ -41,7 +41,7 @@ import {
MaybeTransformHandleType,
TransformHandleDirection,
} from "./transformHandles";
import { Point, PointerDownState } from "../types";
import { AppState, Point, PointerDownState } from "../types";
import Scene from "../scene/Scene";
import {
getApproxMinLineWidth,
@ -79,6 +79,7 @@ export const transformElements = (
pointerY: number,
centerX: number,
centerY: number,
appState: AppState,
) => {
if (selectedElements.length === 1) {
const [element] = selectedElements;
@ -466,8 +467,8 @@ export const resizeSingleElement = (
boundTextElement.fontSize,
boundTextElement.lineHeight,
);
eleNewWidth = Math.ceil(Math.max(eleNewWidth, minWidth));
eleNewHeight = Math.ceil(Math.max(eleNewHeight, minHeight));
eleNewWidth = Math.max(eleNewWidth, minWidth);
eleNewHeight = Math.max(eleNewHeight, minHeight);
}
}
@ -508,8 +509,11 @@ export const resizeSingleElement = (
}
}
const flipX = eleNewWidth < 0;
const flipY = eleNewHeight < 0;
// Flip horizontally
if (eleNewWidth < 0) {
if (flipX) {
if (transformHandleDirection.includes("e")) {
newTopLeft[0] -= Math.abs(newBoundsWidth);
}
@ -517,8 +521,9 @@ export const resizeSingleElement = (
newTopLeft[0] += Math.abs(newBoundsWidth);
}
}
// Flip vertically
if (eleNewHeight < 0) {
if (flipY) {
if (transformHandleDirection.includes("s")) {
newTopLeft[1] -= Math.abs(newBoundsHeight);
}
@ -542,10 +547,20 @@ export const resizeSingleElement = (
const rotatedNewCenter = rotatePoint(newCenter, startCenter, angle);
newTopLeft = rotatePoint(rotatedTopLeft, rotatedNewCenter, -angle);
// For linear elements (x,y) are the coordinates of the first drawn point not the top-left corner
// So we need to readjust (x,y) to be where the first point should be
const newOrigin = [...newTopLeft];
const linearElementXOffset = stateAtResizeStart.x - newBoundsX1;
const linearElementYOffset = stateAtResizeStart.y - newBoundsY1;
newOrigin[0] += linearElementXOffset;
newOrigin[1] += linearElementYOffset;
const nextX = newOrigin[0];
const nextY = newOrigin[1];
// Readjust points for linear elements
let rescaledElementPointsY;
let rescaledPoints;
if (isLinearElement(element) || isFreeDrawElement(element)) {
rescaledElementPointsY = rescalePoints(
1,
@ -562,16 +577,11 @@ export const resizeSingleElement = (
);
}
// For linear elements (x,y) are the coordinates of the first drawn point not the top-left corner
// So we need to readjust (x,y) to be where the first point should be
const newOrigin = [...newTopLeft];
newOrigin[0] += stateAtResizeStart.x - newBoundsX1;
newOrigin[1] += stateAtResizeStart.y - newBoundsY1;
const resizedElement = {
width: Math.abs(eleNewWidth),
height: Math.abs(eleNewHeight),
x: newOrigin[0],
y: newOrigin[1],
x: nextX,
y: nextY,
points: rescaledPoints,
};
@ -680,6 +690,10 @@ export const resizeMultipleElements = (
const { minX, minY, maxX, maxY, midX, midY } = getCommonBoundingBox(
targetElements.map(({ orig }) => orig).concat(boundTextElements),
);
// const originalHeight = maxY - minY;
// const originalWidth = maxX - minX;
const direction = transformHandleType;
const mapDirectionsToAnchors: Record<typeof direction, Point> = {