Fix resize logic (partly) (#1475)
This commit is contained in:
parent
4824f9e1d4
commit
da1031aeb4
@ -140,7 +140,7 @@ export const resizeElements = (
|
|||||||
const handleOffset = 4 / appState.zoom; // XXX import constant
|
const handleOffset = 4 / appState.zoom; // XXX import constant
|
||||||
const dashedLinePadding = 4 / appState.zoom; // XXX import constant
|
const dashedLinePadding = 4 / appState.zoom; // XXX import constant
|
||||||
const offsetPointer = handleOffset + dashedLinePadding;
|
const offsetPointer = handleOffset + dashedLinePadding;
|
||||||
const minSize = handleOffset * 4;
|
const minSize = 0;
|
||||||
if (selectedElements.length === 1) {
|
if (selectedElements.length === 1) {
|
||||||
const [element] = selectedElements;
|
const [element] = selectedElements;
|
||||||
if (resizeHandle === "rotation") {
|
if (resizeHandle === "rotation") {
|
||||||
@ -182,15 +182,17 @@ export const resizeElements = (
|
|||||||
lastY,
|
lastY,
|
||||||
);
|
);
|
||||||
} else if (resizeHandle) {
|
} else if (resizeHandle) {
|
||||||
const [x1, y1] = getElementAbsoluteCoords(element);
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
||||||
const resized = resizeXYWidthHightWithRotation(
|
const resized = resizeXYWidthHightWithRotation(
|
||||||
resizeHandle,
|
resizeHandle,
|
||||||
x1,
|
x1,
|
||||||
y1,
|
y1,
|
||||||
|
x2,
|
||||||
|
y2,
|
||||||
element.width,
|
element.width,
|
||||||
element.height,
|
element.height,
|
||||||
x1 - element.x,
|
element.x,
|
||||||
y1 - element.y,
|
element.y,
|
||||||
element.angle,
|
element.angle,
|
||||||
xPointer,
|
xPointer,
|
||||||
yPointer,
|
yPointer,
|
||||||
@ -198,7 +200,10 @@ export const resizeElements = (
|
|||||||
getResizeWithSidesSameLengthKey(event),
|
getResizeWithSidesSameLengthKey(event),
|
||||||
getResizeCenterPointKey(event),
|
getResizeCenterPointKey(event),
|
||||||
);
|
);
|
||||||
if (resized.width !== 0 && resized.height !== 0) {
|
if (
|
||||||
|
Math.abs(resized.width) > minSize &&
|
||||||
|
Math.abs(resized.height) > minSize
|
||||||
|
) {
|
||||||
mutateElement(element, {
|
mutateElement(element, {
|
||||||
...resized,
|
...resized,
|
||||||
...(isLinearElement(element)
|
...(isLinearElement(element)
|
||||||
|
55
src/math.ts
55
src/math.ts
@ -46,7 +46,7 @@ export function rotate(
|
|||||||
x2: number,
|
x2: number,
|
||||||
y2: number,
|
y2: number,
|
||||||
angle: number,
|
angle: number,
|
||||||
) {
|
): [number, number] {
|
||||||
// 𝑎′𝑥=(𝑎𝑥−𝑐𝑥)cos𝜃−(𝑎𝑦−𝑐𝑦)sin𝜃+𝑐𝑥
|
// 𝑎′𝑥=(𝑎𝑥−𝑐𝑥)cos𝜃−(𝑎𝑦−𝑐𝑦)sin𝜃+𝑐𝑥
|
||||||
// 𝑎′𝑦=(𝑎𝑥−𝑐𝑥)sin𝜃+(𝑎𝑦−𝑐𝑦)cos𝜃+𝑐𝑦.
|
// 𝑎′𝑦=(𝑎𝑥−𝑐𝑥)sin𝜃+(𝑎𝑦−𝑐𝑦)cos𝜃+𝑐𝑦.
|
||||||
// https://math.stackexchange.com/questions/2204520/how-do-i-rotate-a-line-segment-in-a-specific-point-on-the-line
|
// https://math.stackexchange.com/questions/2204520/how-do-i-rotate-a-line-segment-in-a-specific-point-on-the-line
|
||||||
@ -67,8 +67,6 @@ const adjustXYWithRotation = (
|
|||||||
) => {
|
) => {
|
||||||
const cos = Math.cos(angle);
|
const cos = Math.cos(angle);
|
||||||
const sin = Math.sin(angle);
|
const sin = Math.sin(angle);
|
||||||
deltaX /= 2;
|
|
||||||
deltaY /= 2;
|
|
||||||
if (side === "e" || side === "ne" || side === "se") {
|
if (side === "e" || side === "ne" || side === "se") {
|
||||||
if (isResizeFromCenter) {
|
if (isResizeFromCenter) {
|
||||||
x += deltaX;
|
x += deltaX;
|
||||||
@ -106,12 +104,14 @@ const adjustXYWithRotation = (
|
|||||||
|
|
||||||
export const resizeXYWidthHightWithRotation = (
|
export const resizeXYWidthHightWithRotation = (
|
||||||
side: "n" | "s" | "w" | "e" | "nw" | "ne" | "sw" | "se",
|
side: "n" | "s" | "w" | "e" | "nw" | "ne" | "sw" | "se",
|
||||||
x: number,
|
x1: number,
|
||||||
y: number,
|
y1: number,
|
||||||
width: number,
|
x2: number,
|
||||||
height: number,
|
y2: number,
|
||||||
offsetX: number,
|
elementWidth: number,
|
||||||
offsetY: number,
|
elementHeight: number,
|
||||||
|
elementX: number,
|
||||||
|
elementY: number,
|
||||||
angle: number,
|
angle: number,
|
||||||
xPointer: number,
|
xPointer: number,
|
||||||
yPointer: number,
|
yPointer: number,
|
||||||
@ -120,43 +120,56 @@ export const resizeXYWidthHightWithRotation = (
|
|||||||
isResizeFromCenter: boolean,
|
isResizeFromCenter: boolean,
|
||||||
) => {
|
) => {
|
||||||
// center point for rotation
|
// center point for rotation
|
||||||
const cx = x + width / 2;
|
const cx = (x1 + x2) / 2;
|
||||||
const cy = y + height / 2;
|
const cy = (y1 + y2) / 2;
|
||||||
|
|
||||||
// rotation with current angle
|
// rotation with current angle
|
||||||
const [rotatedX, rotatedY] = rotate(xPointer, yPointer, cx, cy, -angle);
|
const [rotatedX, rotatedY] = rotate(xPointer, yPointer, cx, cy, -angle);
|
||||||
|
|
||||||
|
// XXX this might be slow with closure
|
||||||
|
const adjustWithOffsetPointer = (w: number) => {
|
||||||
|
if (w > offsetPointer) {
|
||||||
|
return w - offsetPointer;
|
||||||
|
} else if (w < -offsetPointer) {
|
||||||
|
return w + offsetPointer;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
let scaleX = 1;
|
let scaleX = 1;
|
||||||
let scaleY = 1;
|
let scaleY = 1;
|
||||||
if (side === "e" || side === "ne" || side === "se") {
|
if (side === "e" || side === "ne" || side === "se") {
|
||||||
scaleX = (rotatedX - offsetPointer - x) / width;
|
scaleX = adjustWithOffsetPointer(rotatedX - x1) / (x2 - x1);
|
||||||
}
|
}
|
||||||
if (side === "s" || side === "sw" || side === "se") {
|
if (side === "s" || side === "sw" || side === "se") {
|
||||||
scaleY = (rotatedY - offsetPointer - y) / height;
|
scaleY = adjustWithOffsetPointer(rotatedY - y1) / (y2 - y1);
|
||||||
}
|
}
|
||||||
if (side === "w" || side === "nw" || side === "sw") {
|
if (side === "w" || side === "nw" || side === "sw") {
|
||||||
scaleX = (x + width - offsetPointer - rotatedX) / width;
|
scaleX = adjustWithOffsetPointer(x2 - rotatedX) / (x2 - x1);
|
||||||
}
|
}
|
||||||
if (side === "n" || side === "nw" || side === "ne") {
|
if (side === "n" || side === "nw" || side === "ne") {
|
||||||
scaleY = (y + height - offsetPointer - rotatedY) / height;
|
scaleY = adjustWithOffsetPointer(y2 - rotatedY) / (y2 - y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let nextWidth = width * scaleX;
|
let nextWidth = elementWidth * scaleX;
|
||||||
let nextHeight = height * scaleY;
|
let nextHeight = elementHeight * scaleY;
|
||||||
if (sidesWithSameLength) {
|
if (sidesWithSameLength) {
|
||||||
nextWidth = nextHeight = Math.max(nextWidth, nextHeight);
|
nextWidth = nextHeight = Math.max(nextWidth, nextHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deltaX = (elementWidth - nextWidth) / 2;
|
||||||
|
const deltaY = (elementHeight - nextHeight) / 2;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
width: nextWidth,
|
width: nextWidth,
|
||||||
height: nextHeight,
|
height: nextHeight,
|
||||||
...adjustXYWithRotation(
|
...adjustXYWithRotation(
|
||||||
side,
|
side,
|
||||||
x - offsetX,
|
elementX,
|
||||||
y - offsetY,
|
elementY,
|
||||||
angle,
|
angle,
|
||||||
width - nextWidth,
|
deltaX,
|
||||||
height - nextHeight,
|
deltaY,
|
||||||
isResizeFromCenter,
|
isResizeFromCenter,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user