diff --git a/src/element/resizeElements.ts b/src/element/resizeElements.ts index 0e35e162..e05e463e 100644 --- a/src/element/resizeElements.ts +++ b/src/element/resizeElements.ts @@ -140,7 +140,7 @@ export const resizeElements = ( const handleOffset = 4 / appState.zoom; // XXX import constant const dashedLinePadding = 4 / appState.zoom; // XXX import constant const offsetPointer = handleOffset + dashedLinePadding; - const minSize = handleOffset * 4; + const minSize = 0; if (selectedElements.length === 1) { const [element] = selectedElements; if (resizeHandle === "rotation") { @@ -182,15 +182,17 @@ export const resizeElements = ( lastY, ); } else if (resizeHandle) { - const [x1, y1] = getElementAbsoluteCoords(element); + const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); const resized = resizeXYWidthHightWithRotation( resizeHandle, x1, y1, + x2, + y2, element.width, element.height, - x1 - element.x, - y1 - element.y, + element.x, + element.y, element.angle, xPointer, yPointer, @@ -198,7 +200,10 @@ export const resizeElements = ( getResizeWithSidesSameLengthKey(event), getResizeCenterPointKey(event), ); - if (resized.width !== 0 && resized.height !== 0) { + if ( + Math.abs(resized.width) > minSize && + Math.abs(resized.height) > minSize + ) { mutateElement(element, { ...resized, ...(isLinearElement(element) diff --git a/src/math.ts b/src/math.ts index f7ebe800..f5a6e1e3 100644 --- a/src/math.ts +++ b/src/math.ts @@ -46,7 +46,7 @@ export function rotate( x2: number, y2: number, angle: number, -) { +): [number, number] { // π‘Žβ€²π‘₯=(π‘Žπ‘₯βˆ’π‘π‘₯)cosπœƒβˆ’(π‘Žπ‘¦βˆ’π‘π‘¦)sinπœƒ+𝑐π‘₯ // π‘Žβ€²π‘¦=(π‘Žπ‘₯βˆ’π‘π‘₯)sinπœƒ+(π‘Žπ‘¦βˆ’π‘π‘¦)cosπœƒ+𝑐𝑦. // 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 sin = Math.sin(angle); - deltaX /= 2; - deltaY /= 2; if (side === "e" || side === "ne" || side === "se") { if (isResizeFromCenter) { x += deltaX; @@ -106,12 +104,14 @@ const adjustXYWithRotation = ( export const resizeXYWidthHightWithRotation = ( side: "n" | "s" | "w" | "e" | "nw" | "ne" | "sw" | "se", - x: number, - y: number, - width: number, - height: number, - offsetX: number, - offsetY: number, + x1: number, + y1: number, + x2: number, + y2: number, + elementWidth: number, + elementHeight: number, + elementX: number, + elementY: number, angle: number, xPointer: number, yPointer: number, @@ -120,43 +120,56 @@ export const resizeXYWidthHightWithRotation = ( isResizeFromCenter: boolean, ) => { // center point for rotation - const cx = x + width / 2; - const cy = y + height / 2; + const cx = (x1 + x2) / 2; + const cy = (y1 + y2) / 2; // rotation with current 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 scaleY = 1; 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") { - scaleY = (rotatedY - offsetPointer - y) / height; + scaleY = adjustWithOffsetPointer(rotatedY - y1) / (y2 - y1); } 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") { - scaleY = (y + height - offsetPointer - rotatedY) / height; + scaleY = adjustWithOffsetPointer(y2 - rotatedY) / (y2 - y1); } - let nextWidth = width * scaleX; - let nextHeight = height * scaleY; + let nextWidth = elementWidth * scaleX; + let nextHeight = elementHeight * scaleY; if (sidesWithSameLength) { nextWidth = nextHeight = Math.max(nextWidth, nextHeight); } + const deltaX = (elementWidth - nextWidth) / 2; + const deltaY = (elementHeight - nextHeight) / 2; + return { width: nextWidth, height: nextHeight, ...adjustXYWithRotation( side, - x - offsetX, - y - offsetY, + elementX, + elementY, angle, - width - nextWidth, - height - nextHeight, + deltaX, + deltaY, isResizeFromCenter, ), };