From 65be7973be42dfa5daa7299bbd68cab05f961f0e Mon Sep 17 00:00:00 2001 From: Daishi Kato Date: Thu, 2 Apr 2020 17:40:26 +0900 Subject: [PATCH] Rotation support (#1099) * rotate rectanble with fixed angle * rotate dashed rectangle with fixed angle * fix rotate handler rect * fix canvas size with rotation * angle in element base * fix bug in calculating canvas size * trial only for rectangle * hitTest for rectangle rotation * properly resize rotated rectangle * fix canvas size calculation * giving up... workaround for now * **experimental** handler to rotate rectangle * remove rotation on copy for debugging * update snapshots * better rotation handler with atan2 * rotate when drawImage * add rotation handler * hitTest for any shapes * fix hitTest for curved lines * rotate text element * rotation locking * hint messaage for rotating * show proper handlers on mobile (a workaround, there should be a better way) * refactor hitTest * support exporting png * support exporting svg * fix rotating curved line * refactor drawElementFromCanvas with getElementAbsoluteCoords * fix export png and svg * adjust resize positions for lines (N, E, S, W) * do not make handlers big on mobile * Update src/locales/en.json Alright! Co-Authored-By: Lipis * do not show rotation/resizing hints on mobile * proper calculation for N and W positions * simplify calculation * use "rotation" as property name for clarification (may increase bundle size) * update snapshots excluding rotation handle * refactor with adjustPositionWithRotation * refactor with adjustXYWithRotation * forgot to rename rotation * rename internal function * initialize element angle on restore * rotate wysiwyg editor * fix shift-rotate around 270deg * improve rotation locking * refactor adjustXYWithRotation * avoid rotation degree becomes >=360 * refactor with generateHandler Co-authored-by: Lipis Co-authored-by: dwelle --- src/appState.ts | 2 + src/components/App.tsx | 70 ++-- src/components/HintViewer.tsx | 8 +- src/data/restore.ts | 1 + src/element/bounds.ts | 15 +- src/element/collision.ts | 18 +- src/element/handlerRectangles.ts | 92 ++++- src/element/newElement.ts | 3 + src/element/resizeTest.ts | 43 ++- src/element/textWysiwyg.tsx | 6 +- src/element/types.ts | 1 + src/locales/en.json | 3 +- src/math.ts | 27 ++ src/renderer/renderElement.ts | 61 ++-- src/renderer/renderScene.ts | 86 ++++- .../__snapshots__/dragCreate.test.tsx.snap | 5 + src/tests/__snapshots__/move.test.tsx.snap | 3 + .../multiPointCreate.test.tsx.snap | 2 + .../regressionTests.test.tsx.snap | 317 ++++++++++++++++++ src/tests/__snapshots__/resize.test.tsx.snap | 2 + .../__snapshots__/selection.test.tsx.snap | 5 + src/tests/regressionTests.test.tsx | 1 + src/types.ts | 1 + 23 files changed, 664 insertions(+), 108 deletions(-) diff --git a/src/appState.ts b/src/appState.ts index de55b6c5..021e58e2 100644 --- a/src/appState.ts +++ b/src/appState.ts @@ -29,6 +29,7 @@ export function getDefaultAppState(): AppState { name: `excalidraw-${getDateTime()}`, isCollaborating: false, isResizing: false, + isRotating: false, selectionElement: null, zoom: 1, openMenu: null, @@ -47,6 +48,7 @@ export function clearAppStateForLocalStorage(appState: AppState) { editingElement, selectionElement, isResizing, + isRotating, collaborators, isCollaborating, isLoading, diff --git a/src/components/App.tsx b/src/components/App.tsx index 3a52ec86..a5524f2f 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -4,6 +4,7 @@ import socketIOClient from "socket.io-client"; import rough from "roughjs/bin/rough"; import { RoughCanvas } from "roughjs/bin/canvas"; import { FlooredNumber } from "../types"; +import { getElementAbsoluteCoords } from "../element/bounds"; import { newElement, @@ -50,6 +51,7 @@ import { restore } from "../data/restore"; import { renderScene } from "../renderer"; import { AppState, GestureEvent, Gesture } from "../types"; import { ExcalidrawElement, ExcalidrawLinearElement } from "../element/types"; +import { rotate, adjustXYWithRotation } from "../math"; import { isWritableElement, @@ -1208,6 +1210,7 @@ export class App extends React.Component { font: element.font, opacity: this.state.currentItemOpacity, zoom: this.state.zoom, + angle: element.angle, onSubmit: (text) => { if (text) { globalSceneState.replaceAllElements([ @@ -1703,6 +1706,7 @@ export class App extends React.Component { opacity: this.state.currentItemOpacity, font: this.state.currentItemFont, zoom: this.state.zoom, + angle: 0, onSubmit: (text) => { if (text) { globalSceneState.replaceAllElements([ @@ -1974,7 +1978,10 @@ export class App extends React.Component { } if (isResizingElements && this.state.resizingElement) { - this.setState({ isResizing: true }); + this.setState({ + isResizing: resizeHandle !== "rotation", + isRotating: resizeHandle === "rotation", + }); const el = this.state.resizingElement; const selectedElements = getSelectedElements( globalSceneState.getAllElements(), @@ -1987,9 +1994,10 @@ export class App extends React.Component { this.canvas, window.devicePixelRatio, ); - const deltaX = x - lastX; - const deltaY = y - lastY; const element = selectedElements[0]; + const angle = element.angle; + // reverse rotate delta + const [deltaX, deltaY] = rotate(x - lastX, y - lastY, 0, 0, -angle); switch (resizeHandle) { case "nw": if (isLinearElement(element) && element.points.length === 2) { @@ -2005,16 +2013,12 @@ export class App extends React.Component { resizeArrowFn(element, 1, deltaX, deltaY, x, y, event.shiftKey); } else { const width = element.width - deltaX; - const height = event.shiftKey - ? element.width - : element.height - deltaY; + const height = event.shiftKey ? width : element.height - deltaY; + const dY = element.height - height; mutateElement(element, { - x: element.x + deltaX, - y: event.shiftKey - ? element.y + element.height - element.width - : element.y + deltaY, width, height, + ...adjustXYWithRotation("nw", element, deltaX, dY, angle), ...(isLinearElement(element) && width >= 0 && height >= 0 ? { points: rescalePoints( @@ -2041,12 +2045,11 @@ export class App extends React.Component { } else { const width = element.width + deltaX; const height = event.shiftKey ? width : element.height - deltaY; + const dY = element.height - height; mutateElement(element, { - y: event.shiftKey - ? element.y + element.height - width - : element.y + deltaY, width, height, + ...adjustXYWithRotation("ne", element, deltaX, dY, angle), ...(isLinearElement(element) && width >= 0 && height >= 0 ? { points: rescalePoints( @@ -2072,13 +2075,12 @@ export class App extends React.Component { resizeArrowFn(element, 1, deltaX, deltaY, x, y, event.shiftKey); } else { const width = element.width - deltaX; - const height = event.shiftKey - ? element.width - : element.height + deltaY; + const height = event.shiftKey ? width : element.height + deltaY; + const dY = height - element.height; mutateElement(element, { - x: element.x + deltaX, width, height, + ...adjustXYWithRotation("sw", element, deltaX, dY, angle), ...(isLinearElement(element) && width >= 0 && height >= 0 ? { points: rescalePoints( @@ -2104,12 +2106,12 @@ export class App extends React.Component { resizeArrowFn(element, 1, deltaX, deltaY, x, y, event.shiftKey); } else { const width = element.width + deltaX; - const height = event.shiftKey - ? element.width - : element.height + deltaY; + const height = event.shiftKey ? width : element.height + deltaY; + const dY = height - element.height; mutateElement(element, { width, height, + ...adjustXYWithRotation("se", element, deltaX, dY, angle), ...(isLinearElement(element) && width >= 0 && height >= 0 ? { points: rescalePoints( @@ -2133,13 +2135,13 @@ export class App extends React.Component { } mutateElement(element, { height, - y: element.y + deltaY, + ...adjustXYWithRotation("n", element, 0, deltaY, angle), points: rescalePoints(1, height, element.points), }); } else { mutateElement(element, { height, - y: element.y + deltaY, + ...adjustXYWithRotation("n", element, 0, deltaY, angle), }); } @@ -2157,13 +2159,13 @@ export class App extends React.Component { mutateElement(element, { width, - x: element.x + deltaX, + ...adjustXYWithRotation("w", element, deltaX, 0, angle), points: rescalePoints(0, width, element.points), }); } else { mutateElement(element, { width, - x: element.x + deltaX, + ...adjustXYWithRotation("w", element, deltaX, 0, angle), }); } break; @@ -2179,11 +2181,13 @@ export class App extends React.Component { } mutateElement(element, { height, + ...adjustXYWithRotation("s", element, 0, deltaY, angle), points: rescalePoints(1, height, element.points), }); } else { mutateElement(element, { height, + ...adjustXYWithRotation("s", element, 0, deltaY, angle), }); } break; @@ -2199,15 +2203,32 @@ export class App extends React.Component { } mutateElement(element, { width, + ...adjustXYWithRotation("e", element, deltaX, 0, angle), points: rescalePoints(0, width, element.points), }); } else { mutateElement(element, { width, + ...adjustXYWithRotation("e", element, deltaX, 0, angle), }); } break; } + case "rotation": { + const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); + const cx = (x1 + x2) / 2; + const cy = (y1 + y2) / 2; + let angle = (5 * Math.PI) / 2 + Math.atan2(y - cy, x - cx); + if (event.shiftKey) { + angle += Math.PI / 16; + angle -= angle % (Math.PI / 8); + } + if (angle >= 2 * Math.PI) { + angle -= 2 * Math.PI; + } + mutateElement(element, { angle }); + break; + } } if (resizeHandle) { @@ -2351,6 +2372,7 @@ export class App extends React.Component { this.setState({ isResizing: false, + isRotating: false, resizingElement: null, selectionElement: null, editingElement: multiElement ? this.state.editingElement : null, diff --git a/src/components/HintViewer.tsx b/src/components/HintViewer.tsx index cb79cf9e..d88b2705 100644 --- a/src/components/HintViewer.tsx +++ b/src/components/HintViewer.tsx @@ -13,7 +13,7 @@ interface Hint { } const getHints = ({ appState, elements }: Hint) => { - const { elementType, isResizing } = appState; + const { elementType, isResizing, isRotating, lastPointerDownWith } = appState; const multiMode = appState.multiElement !== null; if (elementType === "arrow" || elementType === "line") { if (!multiMode) { @@ -22,7 +22,7 @@ const getHints = ({ appState, elements }: Hint) => { return t("hints.linearElementMulti"); } - if (isResizing) { + if (isResizing && lastPointerDownWith === "mouse") { const selectedElements = getSelectedElements(elements, appState); const targetElement = selectedElements[0]; if (isLinearElement(targetElement) && targetElement.points.length > 2) { @@ -31,6 +31,10 @@ const getHints = ({ appState, elements }: Hint) => { return t("hints.resize"); } + if (isRotating && lastPointerDownWith === "mouse") { + return t("hints.rotate"); + } + return null; }; diff --git a/src/data/restore.ts b/src/data/restore.ts index ddbd4554..4365fd41 100644 --- a/src/data/restore.ts +++ b/src/data/restore.ts @@ -70,6 +70,7 @@ export function restore( element.opacity === null || element.opacity === undefined ? 100 : element.opacity, + angle: element.angle ?? 0, }; }); diff --git a/src/element/bounds.ts b/src/element/bounds.ts index 9ab52e16..bee744fb 100644 --- a/src/element/bounds.ts +++ b/src/element/bounds.ts @@ -194,10 +194,17 @@ export function getCommonBounds(elements: readonly ExcalidrawElement[]) { elements.forEach((element) => { const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); - minX = Math.min(minX, x1); - minY = Math.min(minY, y1); - maxX = Math.max(maxX, x2); - maxY = Math.max(maxY, y2); + const angle = element.angle; + const cx = (x1 + x2) / 2; + const cy = (y1 + y2) / 2; + const [x11, y11] = rotate(x1, y1, cx, cy, angle); + const [x12, y12] = rotate(x1, y2, cx, cy, angle); + const [x22, y22] = rotate(x2, y2, cx, cy, angle); + const [x21, y21] = rotate(x2, y1, cx, cy, angle); + minX = Math.min(minX, x11, x12, x22, x21); + minY = Math.min(minY, y11, y12, y22, y21); + maxX = Math.max(maxX, x11, x12, x22, x21); + maxY = Math.max(maxY, y11, y12, y22, y21); }); return [minX, minY, maxX, maxY]; diff --git a/src/element/collision.ts b/src/element/collision.ts index 1424db01..06be5d11 100644 --- a/src/element/collision.ts +++ b/src/element/collision.ts @@ -2,16 +2,13 @@ import { distanceBetweenPointAndSegment } from "../math"; import { ExcalidrawElement } from "./types"; -import { - getDiamondPoints, - getElementAbsoluteCoords, - getLinearElementAbsoluteBounds, -} from "./bounds"; +import { getDiamondPoints, getElementAbsoluteCoords } from "./bounds"; import { Point } from "../types"; import { Drawable, OpSet } from "roughjs/bin/core"; import { AppState } from "../types"; import { getShapeForElement } from "../renderer/renderElement"; import { isLinearElement } from "./typeChecks"; +import { rotate } from "../math"; function isElementDraggableFromInside( element: ExcalidrawElement, @@ -34,6 +31,12 @@ export function hitTest( // of the click is less than x pixels of any of the lines that the shape is composed of const lineThreshold = 10 / zoom; + const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); + const cx = (x1 + x2) / 2; + const cy = (y1 + y2) / 2; + // reverse rotate the pointer + [x, y] = rotate(x, y, cx, cy, -element.angle); + if (element.type === "ellipse") { // https://stackoverflow.com/a/46007540/232122 const px = Math.abs(x - element.x - element.width / 2); @@ -75,8 +78,6 @@ export function hitTest( } return Math.hypot(a * tx - px, b * ty - py) < lineThreshold; } else if (element.type === "rectangle") { - const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); - if (isElementDraggableFromInside(element, appState)) { return ( x > x1 - lineThreshold && @@ -165,7 +166,6 @@ export function hitTest( } const shape = getShapeForElement(element) as Drawable[]; - const [x1, y1, x2, y2] = getLinearElementAbsoluteBounds(element); if ( x < x1 - lineThreshold || y < y1 - lineThreshold || @@ -183,8 +183,6 @@ export function hitTest( hitTestRoughShape(subshape.sets, relX, relY, lineThreshold), ); } else if (element.type === "text") { - const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); - return x >= x1 && x <= x2 && y >= y1 && y <= y2; } else if (element.type === "selection") { console.warn("This should not happen, we need to investigate why it does."); diff --git a/src/element/handlerRectangles.ts b/src/element/handlerRectangles.ts index 9e610d3a..3ff00636 100644 --- a/src/element/handlerRectangles.ts +++ b/src/element/handlerRectangles.ts @@ -1,8 +1,9 @@ import { ExcalidrawElement, PointerType } from "./types"; import { getElementAbsoluteCoords } from "./bounds"; +import { rotate } from "../math"; -type Sides = "n" | "s" | "w" | "e" | "nw" | "ne" | "sw" | "se"; +type Sides = "n" | "s" | "w" | "e" | "nw" | "ne" | "sw" | "se" | "rotation"; const handleSizes: { [k in PointerType]: number } = { mouse: 8, @@ -10,6 +11,21 @@ const handleSizes: { [k in PointerType]: number } = { touch: 28, }; +const ROTATION_HANDLER_GAP = 16; + +function generateHandler( + x: number, + y: number, + width: number, + height: number, + cx: number, + cy: number, + angle: number, +): [number, number, number, number] { + const [xx, yy] = rotate(x + width / 2, y + height / 2, cx, cy, angle); + return [xx - width / 2, yy - height / 2, width, height]; +} + export function handlerRectangles( element: ExcalidrawElement, zoom: number, @@ -28,67 +44,107 @@ export function handlerRectangles( const elementWidth = elementX2 - elementX1; const elementHeight = elementY2 - elementY1; + const cx = (elementX1 + elementX2) / 2; + const cy = (elementY1 + elementY2) / 2; + const angle = element.angle; const dashedLineMargin = 4 / zoom; const centeringOffset = (size - 8) / (2 * zoom); const handlers = { - nw: [ + nw: generateHandler( elementX1 - dashedLineMargin - handlerMarginX + centeringOffset, elementY1 - dashedLineMargin - handlerMarginY + centeringOffset, handlerWidth, handlerHeight, - ], - ne: [ + cx, + cy, + angle, + ), + ne: generateHandler( elementX2 + dashedLineMargin - centeringOffset, elementY1 - dashedLineMargin - handlerMarginY + centeringOffset, handlerWidth, handlerHeight, - ], - sw: [ + cx, + cy, + angle, + ), + sw: generateHandler( elementX1 - dashedLineMargin - handlerMarginX + centeringOffset, elementY2 + dashedLineMargin - centeringOffset, handlerWidth, handlerHeight, - ], - se: [ + cx, + cy, + angle, + ), + se: generateHandler( elementX2 + dashedLineMargin - centeringOffset, elementY2 + dashedLineMargin - centeringOffset, handlerWidth, handlerHeight, - ], - } as { [T in Sides]: number[] }; + cx, + cy, + angle, + ), + rotation: generateHandler( + elementX1 + elementWidth / 2 - handlerWidth / 2, + elementY1 - + dashedLineMargin - + handlerMarginY + + centeringOffset - + ROTATION_HANDLER_GAP, + handlerWidth, + handlerHeight, + cx, + cy, + angle, + ), + } as { [T in Sides]: [number, number, number, number] }; // We only want to show height handlers (all cardinal directions) above a certain size const minimumSizeForEightHandlers = (5 * size) / zoom; if (Math.abs(elementWidth) > minimumSizeForEightHandlers) { - handlers["n"] = [ + handlers["n"] = generateHandler( elementX1 + elementWidth / 2 - handlerWidth / 2, elementY1 - dashedLineMargin - handlerMarginY + centeringOffset, handlerWidth, handlerHeight, - ]; - handlers["s"] = [ + cx, + cy, + angle, + ); + handlers["s"] = generateHandler( elementX1 + elementWidth / 2 - handlerWidth / 2, elementY2 + dashedLineMargin - centeringOffset, handlerWidth, handlerHeight, - ]; + cx, + cy, + angle, + ); } if (Math.abs(elementHeight) > minimumSizeForEightHandlers) { - handlers["w"] = [ + handlers["w"] = generateHandler( elementX1 - dashedLineMargin - handlerMarginX + centeringOffset, elementY1 + elementHeight / 2 - handlerHeight / 2, handlerWidth, handlerHeight, - ]; - handlers["e"] = [ + cx, + cy, + angle, + ); + handlers["e"] = generateHandler( elementX2 + dashedLineMargin - centeringOffset, elementY1 + elementHeight / 2 - handlerHeight / 2, handlerWidth, handlerHeight, - ]; + cx, + cy, + angle, + ); } if (element.type === "arrow" || element.type === "line") { diff --git a/src/element/newElement.ts b/src/element/newElement.ts index 23a1036a..9c58ed4b 100644 --- a/src/element/newElement.ts +++ b/src/element/newElement.ts @@ -18,6 +18,7 @@ type ElementConstructorOpts = { opacity: ExcalidrawGenericElement["opacity"]; width?: ExcalidrawGenericElement["width"]; height?: ExcalidrawGenericElement["height"]; + angle?: ExcalidrawGenericElement["angle"]; }; function _newElementBase( @@ -33,6 +34,7 @@ function _newElementBase( opacity, width = 0, height = 0, + angle = 0, ...rest }: ElementConstructorOpts & Partial, ) { @@ -43,6 +45,7 @@ function _newElementBase( y, width, height, + angle, strokeColor, backgroundColor, fillStyle, diff --git a/src/element/resizeTest.ts b/src/element/resizeTest.ts index 3702ab05..e5828d44 100644 --- a/src/element/resizeTest.ts +++ b/src/element/resizeTest.ts @@ -6,6 +6,19 @@ import { isLinearElement } from "./typeChecks"; type HandlerRectanglesRet = keyof ReturnType; +function isInHandlerRect( + handler: [number, number, number, number], + x: number, + y: number, +) { + return ( + x >= handler[0] && + x <= handler[0] + handler[2] && + y >= handler[1] && + y <= handler[1] + handler[3] + ); +} + export function resizeTest( element: ExcalidrawElement, appState: AppState, @@ -14,24 +27,31 @@ export function resizeTest( zoom: number, pointerType: PointerType, ): HandlerRectanglesRet | false { - if (!appState.selectedElementIds[element.id] || element.type === "text") { + if (!appState.selectedElementIds[element.id]) { return false; } - const handlers = handlerRectangles(element, zoom, pointerType); + const { rotation: rotationHandler, ...handlers } = handlerRectangles( + element, + zoom, + pointerType, + ); + + if (rotationHandler && isInHandlerRect(rotationHandler, x, y)) { + return "rotation" as HandlerRectanglesRet; + } + + if (element.type === "text") { + // can't resize text elements + return false; + } const filter = Object.keys(handlers).filter((key) => { - const handler = handlers[key as HandlerRectanglesRet]!; + const handler = handlers[key as Exclude]!; if (!handler) { return false; } - - return ( - x >= handler[0] && - x <= handler[0] + handler[2] && - y >= handler[1] && - y <= handler[1] + handler[3] - ); + return isInHandlerRect(handler, x, y); }); if (filter.length > 0) { @@ -94,6 +114,9 @@ export function getCursorForResizingElement(resizingElement: { cursor = "nesw"; } break; + case "rotation": + cursor = "ew"; + break; } return cursor ? `${cursor}-resize` : ""; diff --git a/src/element/textWysiwyg.tsx b/src/element/textWysiwyg.tsx index 2bc75fc9..c6b680b7 100644 --- a/src/element/textWysiwyg.tsx +++ b/src/element/textWysiwyg.tsx @@ -20,6 +20,7 @@ type TextWysiwygParams = { font: string; opacity: number; zoom: number; + angle: number; onSubmit: (text: string) => void; onCancel: () => void; }; @@ -32,6 +33,7 @@ export function textWysiwyg({ font, opacity, zoom, + angle, onSubmit, onCancel, }: TextWysiwygParams) { @@ -45,13 +47,15 @@ export function textWysiwyg({ editable.innerText = initText; editable.dataset.type = "wysiwyg"; + const degree = (180 * angle) / Math.PI; + Object.assign(editable.style, { color: strokeColor, position: "fixed", opacity: opacity / 100, top: `${y}px`, left: `${x}px`, - transform: `translate(-50%, -50%) scale(${zoom})`, + transform: `translate(-50%, -50%) scale(${zoom}) rotate(${degree}deg)`, textAlign: "left", display: "inline-block", font: font, diff --git a/src/element/types.ts b/src/element/types.ts index 52117891..daea434c 100644 --- a/src/element/types.ts +++ b/src/element/types.ts @@ -12,6 +12,7 @@ type _ExcalidrawElementBase = Readonly<{ opacity: number; width: number; height: number; + angle: number; seed: number; version: number; versionNonce: number; diff --git a/src/locales/en.json b/src/locales/en.json index 5c905b6b..2d7adce4 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -98,7 +98,8 @@ "hints": { "linearElement": "Click to start multiple points, drag for single line", "linearElementMulti": "Click on last point or press Escape or Enter to finish", - "resize": "You can constraint proportions by holding SHIFT while resizing" + "resize": "You can constrain proportions by holding SHIFT while resizing", + "rotate": "You can constrain angles by holding SHIFT while rotating" }, "errorSplash": { "headingMain_pre": "Encountered an error. Try ", diff --git a/src/math.ts b/src/math.ts index 87472ee1..7b6e6555 100644 --- a/src/math.ts +++ b/src/math.ts @@ -55,6 +55,33 @@ export function rotate( ]; } +export function adjustXYWithRotation( + side: "n" | "s" | "w" | "e" | "nw" | "ne" | "sw" | "se", + position: { x: number; y: number }, + deltaX: number, + deltaY: number, + angle: number, +) { + let { x, y } = position; + if (side === "e" || side === "ne" || side === "se") { + x -= (deltaX / 2) * (1 - Math.cos(angle)); + y -= (deltaX / 2) * -Math.sin(angle); + } + if (side === "s" || side === "sw" || side === "se") { + x -= (deltaY / 2) * Math.sin(angle); + y -= (deltaY / 2) * (1 - Math.cos(angle)); + } + if (side === "w" || side === "nw" || side === "sw") { + x += (deltaX / 2) * (1 + Math.cos(angle)); + y += (deltaX / 2) * Math.sin(angle); + } + if (side === "n" || side === "nw" || side === "ne") { + x += (deltaY / 2) * -Math.sin(angle); + y += (deltaY / 2) * (1 + Math.cos(angle)); + } + return { x, y }; +} + export const getPointOnAPath = (point: Point, path: Point[]) => { const [px, py] = point; const [start, ...other] = path; diff --git a/src/renderer/renderElement.ts b/src/renderer/renderElement.ts index e72e57db..afe7c047 100644 --- a/src/renderer/renderElement.ts +++ b/src/renderer/renderElement.ts @@ -263,30 +263,24 @@ function drawElementFromCanvas( context: CanvasRenderingContext2D, sceneState: SceneState, ) { + const element = elementWithCanvas.element; + const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); + const cx = ((x1 + x2) / 2 + sceneState.scrollX) * window.devicePixelRatio; + const cy = ((y1 + y2) / 2 + sceneState.scrollY) * window.devicePixelRatio; context.scale(1 / window.devicePixelRatio, 1 / window.devicePixelRatio); - context.translate( - -CANVAS_PADDING / elementWithCanvas.canvasZoom, - -CANVAS_PADDING / elementWithCanvas.canvasZoom, - ); + context.translate(cx, cy); + context.rotate(element.angle); context.drawImage( elementWithCanvas.canvas!, - Math.floor( - -elementWithCanvas.canvasOffsetX + - (Math.floor(elementWithCanvas.element.x) + sceneState.scrollX) * - window.devicePixelRatio, - ), - Math.floor( - -elementWithCanvas.canvasOffsetY + - (Math.floor(elementWithCanvas.element.y) + sceneState.scrollY) * - window.devicePixelRatio, - ), + (-(x2 - x1) / 2) * window.devicePixelRatio - + CANVAS_PADDING / elementWithCanvas.canvasZoom, + (-(y2 - y1) / 2) * window.devicePixelRatio - + CANVAS_PADDING / elementWithCanvas.canvasZoom, elementWithCanvas.canvas!.width / elementWithCanvas.canvasZoom, elementWithCanvas.canvas!.height / elementWithCanvas.canvasZoom, ); - context.translate( - CANVAS_PADDING / elementWithCanvas.canvasZoom, - CANVAS_PADDING / elementWithCanvas.canvasZoom, - ); + context.rotate(-element.angle); + context.translate(-cx, -cy); context.scale(window.devicePixelRatio, window.devicePixelRatio); } @@ -325,11 +319,18 @@ export function renderElement( if (renderOptimizations) { drawElementFromCanvas(elementWithCanvas, rc, context, sceneState); } else { - const offsetX = Math.floor(element.x + sceneState.scrollX); - const offsetY = Math.floor(element.y + sceneState.scrollY); - context.translate(offsetX, offsetY); + const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); + const cx = (x1 + x2) / 2 + sceneState.scrollX; + const cy = (y1 + y2) / 2 + sceneState.scrollY; + const shiftX = (x2 - x1) / 2 - (element.x - x1); + const shiftY = (y2 - y1) / 2 - (element.y - y1); + context.translate(cx, cy); + context.rotate(element.angle); + context.translate(-shiftX, -shiftY); drawElementOnCanvas(element, rc, context); - context.translate(-offsetX, -offsetY); + context.translate(shiftX, shiftY); + context.rotate(-element.angle); + context.translate(-cx, -cy); } break; } @@ -347,6 +348,10 @@ export function renderElementToSvg( offsetX?: number, offsetY?: number, ) { + const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); + const cx = (x2 - x1) / 2 - (element.x - x1); + const cy = (y2 - y1) / 2 - (element.y - y1); + const degree = (180 * element.angle) / Math.PI; const generator = rsvg.generator; switch (element.type) { case "selection": { @@ -366,7 +371,9 @@ export function renderElementToSvg( } node.setAttribute( "transform", - `translate(${offsetX || 0} ${offsetY || 0})`, + `translate(${offsetX || 0} ${ + offsetY || 0 + }) rotate(${degree} ${cx} ${cy})`, ); svgRoot.appendChild(node); break; @@ -384,7 +391,9 @@ export function renderElementToSvg( } node.setAttribute( "transform", - `translate(${offsetX || 0} ${offsetY || 0})`, + `translate(${offsetX || 0} ${ + offsetY || 0 + }) rotate(${degree} ${cx} ${cy})`, ); group.appendChild(node); }); @@ -401,7 +410,9 @@ export function renderElementToSvg( } node.setAttribute( "transform", - `translate(${offsetX || 0} ${offsetY || 0})`, + `translate(${offsetX || 0} ${ + offsetY || 0 + }) rotate(${degree} ${cx} ${cy})`, ); const lines = element.text.replace(/\r\n?/g, "\n").split("\n"); const lineHeight = element.height / lines.length; diff --git a/src/renderer/renderScene.ts b/src/renderer/renderScene.ts index 569c5396..6bbb21b5 100644 --- a/src/renderer/renderScene.ts +++ b/src/renderer/renderScene.ts @@ -17,6 +17,8 @@ import { getSelectedElements } from "../scene/selection"; import { renderElement, renderElementToSvg } from "./renderElement"; import colors from "../colors"; +type HandlerRectanglesRet = keyof ReturnType; + function colorsForClientId(clientId: string) { // Naive way of getting an integer out of the clientId const sum = clientId.split("").reduce((a, str) => a + str.charCodeAt(0), 0); @@ -26,6 +28,40 @@ function colorsForClientId(clientId: string) { }; } +function strokeRectWithRotation( + context: CanvasRenderingContext2D, + x: number, + y: number, + width: number, + height: number, + cx: number, + cy: number, + angle: number, + fill?: boolean, +) { + context.translate(cx, cy); + context.rotate(angle); + if (fill) { + context.fillRect(x - cx, y - cy, width, height); + } + context.strokeRect(x - cx, y - cy, width, height); + context.rotate(-angle); + context.translate(-cx, -cy); +} + +function strokeCircle( + context: CanvasRenderingContext2D, + x: number, + y: number, + width: number, + height: number, +) { + context.beginPath(); + context.arc(x + width / 2, y + height / 2, width / 2, 0, Math.PI * 2); + context.fill(); + context.stroke(); +} + export function renderScene( allElements: readonly ExcalidrawElement[], appState: AppState, @@ -113,7 +149,7 @@ export function renderScene( // Pain selected elements if (renderSelection) { const selectedElements = getSelectedElements(elements, appState); - const dashledLinePadding = 4 / sceneState.zoom; + const dashedLinePadding = 4 / sceneState.zoom; context.translate(sceneState.scrollX, sceneState.scrollY); selectedElements.forEach((element) => { @@ -131,11 +167,15 @@ export function renderScene( context.setLineDash([8 / sceneState.zoom, 4 / sceneState.zoom]); const lineWidth = context.lineWidth; context.lineWidth = 1 / sceneState.zoom; - context.strokeRect( - elementX1 - dashledLinePadding, - elementY1 - dashledLinePadding, - elementWidth + dashledLinePadding * 2, - elementHeight + dashledLinePadding * 2, + strokeRectWithRotation( + context, + elementX1 - dashedLinePadding, + elementY1 - dashedLinePadding, + elementWidth + dashedLinePadding * 2, + elementHeight + dashedLinePadding * 2, + elementX1 + elementWidth / 2, + elementY1 + elementHeight / 2, + element.angle, ); context.lineWidth = lineWidth; context.setLineDash(initialLineDash); @@ -143,19 +183,39 @@ export function renderScene( context.translate(-sceneState.scrollX, -sceneState.scrollY); // Paint resize handlers - if (selectedElements.length === 1 && selectedElements[0].type !== "text") { + if (selectedElements.length === 1) { context.translate(sceneState.scrollX, sceneState.scrollY); context.fillStyle = "#fff"; const handlers = handlerRectangles(selectedElements[0], sceneState.zoom); - Object.values(handlers) - .filter((handler) => handler !== undefined) - .forEach((handler) => { + Object.keys(handlers).forEach((key) => { + const handler = handlers[key as HandlerRectanglesRet]; + if (handler !== undefined) { const lineWidth = context.lineWidth; context.lineWidth = 1 / sceneState.zoom; - context.fillRect(handler[0], handler[1], handler[2], handler[3]); - context.strokeRect(handler[0], handler[1], handler[2], handler[3]); + if (key === "rotation") { + strokeCircle( + context, + handler[0], + handler[1], + handler[2], + handler[3], + ); + } else if (selectedElements[0].type !== "text") { + strokeRectWithRotation( + context, + handler[0], + handler[1], + handler[2], + handler[3], + handler[0] + handler[2] / 2, + handler[1] + handler[3] / 2, + selectedElements[0].angle, + true, // fill before stroke + ); + } context.lineWidth = lineWidth; - }); + } + }); context.translate(-sceneState.scrollX, -sceneState.scrollY); } } diff --git a/src/tests/__snapshots__/dragCreate.test.tsx.snap b/src/tests/__snapshots__/dragCreate.test.tsx.snap index cc8b2bc7..4532d739 100644 --- a/src/tests/__snapshots__/dragCreate.test.tsx.snap +++ b/src/tests/__snapshots__/dragCreate.test.tsx.snap @@ -4,6 +4,7 @@ exports[`add element to the scene when pointer dragging long enough arrow 1`] = exports[`add element to the scene when pointer dragging long enough arrow 2`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, @@ -38,6 +39,7 @@ exports[`add element to the scene when pointer dragging long enough diamond 1`] exports[`add element to the scene when pointer dragging long enough diamond 2`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, @@ -61,6 +63,7 @@ exports[`add element to the scene when pointer dragging long enough ellipse 1`] exports[`add element to the scene when pointer dragging long enough ellipse 2`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, @@ -82,6 +85,7 @@ Object { exports[`add element to the scene when pointer dragging long enough line 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, @@ -116,6 +120,7 @@ exports[`add element to the scene when pointer dragging long enough rectangle 1` exports[`add element to the scene when pointer dragging long enough rectangle 2`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, diff --git a/src/tests/__snapshots__/move.test.tsx.snap b/src/tests/__snapshots__/move.test.tsx.snap index 964fd52f..d2b14fcf 100644 --- a/src/tests/__snapshots__/move.test.tsx.snap +++ b/src/tests/__snapshots__/move.test.tsx.snap @@ -2,6 +2,7 @@ exports[`duplicate element on move when ALT is clicked rectangle 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, @@ -23,6 +24,7 @@ Object { exports[`duplicate element on move when ALT is clicked rectangle 2`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, @@ -44,6 +46,7 @@ Object { exports[`move element rectangle 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, diff --git a/src/tests/__snapshots__/multiPointCreate.test.tsx.snap b/src/tests/__snapshots__/multiPointCreate.test.tsx.snap index cee17976..8cbd48a9 100644 --- a/src/tests/__snapshots__/multiPointCreate.test.tsx.snap +++ b/src/tests/__snapshots__/multiPointCreate.test.tsx.snap @@ -2,6 +2,7 @@ exports[`multi point mode in linear elements arrow 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 110, @@ -41,6 +42,7 @@ Object { exports[`multi point mode in linear elements line 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 110, diff --git a/src/tests/__snapshots__/regressionTests.test.tsx.snap b/src/tests/__snapshots__/regressionTests.test.tsx.snap index 63eb39d4..2909bf1d 100644 --- a/src/tests/__snapshots__/regressionTests.test.tsx.snap +++ b/src/tests/__snapshots__/regressionTests.test.tsx.snap @@ -20,6 +20,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -41,6 +42,7 @@ Object { exports[`regression tests alt-drag duplicates an element: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -62,6 +64,7 @@ Object { exports[`regression tests alt-drag duplicates an element: [end of test] element 1 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -101,6 +104,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -135,6 +139,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -153,6 +158,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -200,6 +206,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -220,6 +227,7 @@ Object { exports[`regression tests arrow keys: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -259,6 +267,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -306,6 +315,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -326,6 +336,7 @@ Object { exports[`regression tests change the properties of a shape: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "#fa5252", "fillStyle": "hachure", "height": 10, @@ -365,6 +376,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -399,6 +411,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -433,6 +446,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "#fa5252", "fillStyle": "hachure", "height": 10, @@ -467,6 +481,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "#fa5252", "fillStyle": "hachure", "height": 10, @@ -501,6 +516,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "#fa5252", "fillStyle": "hachure", "height": 10, @@ -548,6 +564,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -569,6 +586,7 @@ Object { exports[`regression tests click on an element and drag it: [dragged] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -608,6 +626,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -642,6 +661,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -689,6 +709,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -711,6 +732,7 @@ Object { exports[`regression tests click on an element and drag it: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -750,6 +772,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -784,6 +807,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -818,6 +842,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -865,6 +890,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -886,6 +912,7 @@ Object { exports[`regression tests click to select a shape: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -907,6 +934,7 @@ Object { exports[`regression tests click to select a shape: [end of test] element 1 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -946,6 +974,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -980,6 +1009,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -998,6 +1028,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1045,6 +1076,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -1067,6 +1099,7 @@ Object { exports[`regression tests click-drag to select a group: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1088,6 +1121,7 @@ Object { exports[`regression tests click-drag to select a group: [end of test] element 1 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1109,6 +1143,7 @@ Object { exports[`regression tests click-drag to select a group: [end of test] element 2 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1148,6 +1183,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1182,6 +1218,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1200,6 +1237,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1234,6 +1272,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1252,6 +1291,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1270,6 +1310,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1317,6 +1358,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -1335,6 +1377,7 @@ Object { exports[`regression tests draw every type of shape: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1356,6 +1399,7 @@ Object { exports[`regression tests draw every type of shape: [end of test] element 1 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1377,6 +1421,7 @@ Object { exports[`regression tests draw every type of shape: [end of test] element 2 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1398,6 +1443,7 @@ Object { exports[`regression tests draw every type of shape: [end of test] element 3 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1430,6 +1476,7 @@ Object { exports[`regression tests draw every type of shape: [end of test] element 4 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1495,6 +1542,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1529,6 +1577,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1547,6 +1596,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1581,6 +1631,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1599,6 +1650,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1617,6 +1669,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1651,6 +1704,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1669,6 +1723,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1687,6 +1742,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1705,6 +1761,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1750,6 +1807,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1768,6 +1826,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1786,6 +1845,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1804,6 +1864,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1833,6 +1894,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1891,6 +1953,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -1911,6 +1974,7 @@ Object { exports[`regression tests hotkey 2 selects rectangle tool: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1950,6 +2014,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -1997,6 +2062,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -2017,6 +2083,7 @@ Object { exports[`regression tests hotkey 3 selects diamond tool: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2056,6 +2123,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2103,6 +2171,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -2123,6 +2192,7 @@ Object { exports[`regression tests hotkey 4 selects ellipse tool: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2162,6 +2232,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2209,6 +2280,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -2229,6 +2301,7 @@ Object { exports[`regression tests hotkey 5 selects arrow tool: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2279,6 +2352,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2337,6 +2411,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -2357,6 +2432,7 @@ Object { exports[`regression tests hotkey 6 selects line tool: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2407,6 +2483,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2465,6 +2542,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -2485,6 +2563,7 @@ Object { exports[`regression tests hotkey a selects arrow tool: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2535,6 +2614,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2593,6 +2673,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -2613,6 +2694,7 @@ Object { exports[`regression tests hotkey d selects diamond tool: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2652,6 +2734,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2699,6 +2782,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -2719,6 +2803,7 @@ Object { exports[`regression tests hotkey e selects ellipse tool: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2758,6 +2843,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2805,6 +2891,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -2825,6 +2912,7 @@ Object { exports[`regression tests hotkey l selects line tool: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2875,6 +2963,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2933,6 +3022,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -2953,6 +3043,7 @@ Object { exports[`regression tests hotkey r selects rectangle tool: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -2992,6 +3083,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3039,6 +3131,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "touch", "multiElement": null, "name": "excalidraw-201933152653", @@ -3089,6 +3182,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -3125,6 +3219,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3164,6 +3259,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3198,6 +3294,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -3232,6 +3329,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3266,6 +3364,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -3300,6 +3399,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3334,6 +3434,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -3368,6 +3469,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3402,6 +3504,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -3436,6 +3539,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3470,6 +3574,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -3504,6 +3609,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3538,6 +3644,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -3572,6 +3679,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3606,6 +3714,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -3640,6 +3749,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3674,6 +3784,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -3708,6 +3819,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3755,6 +3867,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -3782,6 +3895,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle ne (+5, +5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -3821,6 +3935,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3855,6 +3970,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -3889,6 +4005,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3923,6 +4040,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -3957,6 +4075,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -3991,6 +4110,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -4025,6 +4145,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -4059,6 +4180,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -4106,6 +4228,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -4131,6 +4254,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle ne (-5, -5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -4170,6 +4294,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -4204,6 +4329,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -4238,6 +4364,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -4272,6 +4399,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -4306,6 +4434,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -4340,6 +4469,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -4387,6 +4517,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -4410,6 +4541,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle nw (+5, +5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -4449,6 +4581,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -4483,6 +4616,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -4517,6 +4651,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -4551,6 +4686,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -4598,6 +4734,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -4619,6 +4756,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle nw (-5, -5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -4658,6 +4796,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -4692,6 +4831,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -4739,6 +4879,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -4774,6 +4915,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle se (+5, +5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -4813,6 +4955,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -4847,6 +4990,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -4881,6 +5025,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -4915,6 +5060,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -4949,6 +5095,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -4983,6 +5130,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -5017,6 +5165,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5051,6 +5200,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -5085,6 +5235,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5119,6 +5270,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -5153,6 +5305,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5187,6 +5340,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -5221,6 +5375,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5255,6 +5410,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -5289,6 +5445,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5323,6 +5480,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -5370,6 +5528,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -5403,6 +5562,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle se (-5, -5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -5442,6 +5602,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5476,6 +5637,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -5510,6 +5672,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5544,6 +5707,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -5578,6 +5742,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5612,6 +5777,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -5646,6 +5812,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5680,6 +5847,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -5714,6 +5882,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5748,6 +5917,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -5782,6 +5952,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5816,6 +5987,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -5850,6 +6022,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -5884,6 +6057,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -5931,6 +6105,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -5962,6 +6137,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle sw (+5, +5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -6001,6 +6177,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6035,6 +6212,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -6069,6 +6247,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6103,6 +6282,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -6137,6 +6317,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6171,6 +6352,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -6205,6 +6387,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6239,6 +6422,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -6273,6 +6457,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6307,6 +6492,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -6341,6 +6527,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6375,6 +6562,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -6422,6 +6610,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -6451,6 +6640,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [resize handle sw (-5, -5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -6490,6 +6680,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6524,6 +6715,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -6558,6 +6750,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6592,6 +6785,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -6626,6 +6820,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6660,6 +6855,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -6694,6 +6890,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6728,6 +6925,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -6762,6 +6960,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6796,6 +6995,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -6843,6 +7043,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -6871,6 +7072,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle ne (+5, +5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6910,6 +7112,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -6944,6 +7147,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -6978,6 +7182,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7012,6 +7217,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -7046,6 +7252,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7080,6 +7287,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -7114,6 +7322,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7148,6 +7357,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -7182,6 +7392,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7229,6 +7440,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -7255,6 +7467,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle ne (-5, -5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7294,6 +7507,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7328,6 +7542,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -7362,6 +7577,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7396,6 +7612,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -7430,6 +7647,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7464,6 +7682,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -7498,6 +7717,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7545,6 +7765,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -7569,6 +7790,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle nw (+5, +5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7608,6 +7830,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7642,6 +7865,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -7676,6 +7900,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7710,6 +7935,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -7744,6 +7970,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7791,6 +8018,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -7813,6 +8041,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle nw (-5, -5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7852,6 +8081,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7886,6 +8116,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -7920,6 +8151,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -7967,6 +8199,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -8003,6 +8236,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle se (+5, +5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8042,6 +8276,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8076,6 +8311,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -8110,6 +8346,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8144,6 +8381,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -8178,6 +8416,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8212,6 +8451,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -8246,6 +8486,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8280,6 +8521,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -8314,6 +8556,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8348,6 +8591,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -8382,6 +8626,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8416,6 +8661,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -8450,6 +8696,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8484,6 +8731,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -8518,6 +8766,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8552,6 +8801,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -8586,6 +8836,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8633,6 +8884,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -8667,6 +8919,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle se (-5, -5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8706,6 +8959,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8740,6 +8994,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -8774,6 +9029,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8808,6 +9064,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -8842,6 +9099,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8876,6 +9134,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -8910,6 +9169,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -8944,6 +9204,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -8978,6 +9239,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9012,6 +9274,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -9046,6 +9309,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9080,6 +9344,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -9114,6 +9379,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9148,6 +9414,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -9182,6 +9449,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9229,6 +9497,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -9261,6 +9530,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle sw (+5, +5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9300,6 +9570,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9334,6 +9605,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -9368,6 +9640,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9402,6 +9675,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -9436,6 +9710,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9470,6 +9745,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -9504,6 +9780,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9538,6 +9815,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -9572,6 +9850,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9606,6 +9885,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -9640,6 +9920,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9674,6 +9955,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -9708,6 +9990,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9755,6 +10038,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -9785,6 +10069,7 @@ Object { exports[`regression tests resize an element, trying every resize handle: [unresize handle sw (-5, -5)] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9824,6 +10109,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9858,6 +10144,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -9892,6 +10179,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9926,6 +10214,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -9960,6 +10249,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -9994,6 +10284,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 15, @@ -10028,6 +10319,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10062,6 +10354,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -10096,6 +10389,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10130,6 +10424,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 5, @@ -10164,6 +10459,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10211,6 +10507,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -10235,6 +10532,7 @@ Object { exports[`regression tests shift-click to select a group, then drag: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10256,6 +10554,7 @@ Object { exports[`regression tests shift-click to select a group, then drag: [end of test] element 1 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10295,6 +10594,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10329,6 +10629,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10347,6 +10648,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10381,6 +10683,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10399,6 +10702,7 @@ Object { "y": 20, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10446,6 +10750,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -10494,6 +10799,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -10544,6 +10850,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", @@ -10564,6 +10871,7 @@ Object { exports[`regression tests undo/redo drawing an element: [end of test] element 0 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10585,6 +10893,7 @@ Object { exports[`regression tests undo/redo drawing an element: [end of test] element 1 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10606,6 +10915,7 @@ Object { exports[`regression tests undo/redo drawing an element: [end of test] element 2 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10644,6 +10954,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10662,6 +10973,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10680,6 +10992,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10716,6 +11029,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10750,6 +11064,7 @@ Object { }, "elements": Array [ Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10768,6 +11083,7 @@ Object { "y": 10, }, Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 10, @@ -10815,6 +11131,7 @@ Object { "isCollaborating": false, "isLoading": false, "isResizing": false, + "isRotating": false, "lastPointerDownWith": "mouse", "multiElement": null, "name": "excalidraw-201933152653", diff --git a/src/tests/__snapshots__/resize.test.tsx.snap b/src/tests/__snapshots__/resize.test.tsx.snap index 50042682..ed987aa2 100644 --- a/src/tests/__snapshots__/resize.test.tsx.snap +++ b/src/tests/__snapshots__/resize.test.tsx.snap @@ -2,6 +2,7 @@ exports[`resize element rectangle 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, @@ -23,6 +24,7 @@ Object { exports[`resize element with aspect ratio when SHIFT is clicked rectangle 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, diff --git a/src/tests/__snapshots__/selection.test.tsx.snap b/src/tests/__snapshots__/selection.test.tsx.snap index 2dc0a0bb..0ee3f156 100644 --- a/src/tests/__snapshots__/selection.test.tsx.snap +++ b/src/tests/__snapshots__/selection.test.tsx.snap @@ -2,6 +2,7 @@ exports[`select single element on the scene arrow 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, @@ -34,6 +35,7 @@ Object { exports[`select single element on the scene arrow escape 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, @@ -66,6 +68,7 @@ Object { exports[`select single element on the scene diamond 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, @@ -87,6 +90,7 @@ Object { exports[`select single element on the scene ellipse 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, @@ -108,6 +112,7 @@ Object { exports[`select single element on the scene rectangle 1`] = ` Object { + "angle": 0, "backgroundColor": "transparent", "fillStyle": "hachure", "height": 50, diff --git a/src/tests/regressionTests.test.tsx b/src/tests/regressionTests.test.tsx index 7a155998..6821f5b4 100644 --- a/src/tests/regressionTests.test.tsx +++ b/src/tests/regressionTests.test.tsx @@ -322,6 +322,7 @@ describe("regression tests", () => { pointerUp(); const resizeHandles = getResizeHandles(); + delete resizeHandles.rotation; // exclude rotation handle for (const handlePos in resizeHandles) { const [x, y] = resizeHandles[handlePos as keyof typeof resizeHandles]; const { width: prevWidth, height: prevHeight } = getSelectedElement(); diff --git a/src/types.ts b/src/types.ts index ca7123d8..3d4ee82f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -37,6 +37,7 @@ export type AppState = { name: string; isCollaborating: boolean; isResizing: boolean; + isRotating: boolean; zoom: number; openMenu: "canvas" | "shape" | null; lastPointerDownWith: PointerType;