| 
					
				 | 
			
			
				@@ -170,6 +170,39 @@ function hitTest(element: ExcalidrawElement, x: number, y: number): boolean { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function resizeTest( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  element: ExcalidrawElement, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  x: number, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  y: number, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sceneState: SceneState 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+): string | false { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (element.type === "text" || element.type === "arrow") return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const x1 = getElementAbsoluteX1(element); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const x2 = getElementAbsoluteX2(element); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const y1 = getElementAbsoluteY1(element); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const y2 = getElementAbsoluteY2(element); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const handlers = handlerRectangles(x1, x2, y1, y2, sceneState); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const filter = Object.keys(handlers).filter(key => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const handler = handlers[key]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      x + sceneState.scrollX >= handler[0] && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      x + sceneState.scrollX <= handler[0] + handler[2] && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      y + sceneState.scrollY >= handler[1] && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      y + sceneState.scrollY <= handler[1] + handler[3] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (filter.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return filter[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function newElement( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   type: string, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   x: number, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -243,6 +276,77 @@ function getScrollbars( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function handlerRectangles( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  elementX1: number, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  elementX2: number, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  elementY1: number, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  elementY2: number, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sceneState: SceneState 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const margin = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const minimumSize = 40; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const handlers: { [handler: string]: number[] } = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (elementX2 - elementX1 > minimumSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    handlers["n"] = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      elementX1 + (elementX2 - elementX1) / 2 + sceneState.scrollX - 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      elementY1 - margin + sceneState.scrollY - 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    handlers["s"] = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      elementX1 + (elementX2 - elementX1) / 2 + sceneState.scrollX - 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      elementY2 - margin + sceneState.scrollY + 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (elementY2 - elementY1 > minimumSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    handlers["w"] = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      elementX1 - margin + sceneState.scrollX - 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      elementY1 + (elementY2 - elementY1) / 2 + sceneState.scrollY - 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    handlers["e"] = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      elementX2 - margin + sceneState.scrollX + 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      elementY1 + (elementY2 - elementY1) / 2 + sceneState.scrollY - 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  handlers["nw"] = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    elementX1 - margin + sceneState.scrollX - 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    elementY1 - margin + sceneState.scrollY - 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ]; // nw 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  handlers["ne"] = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    elementX2 - margin + sceneState.scrollX + 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    elementY1 - margin + sceneState.scrollY - 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ]; // ne 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  handlers["sw"] = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    elementX1 - margin + sceneState.scrollX - 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    elementY2 - margin + sceneState.scrollY + 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ]; // sw 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  handlers["se"] = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    elementX2 - margin + sceneState.scrollX + 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    elementY2 - margin + sceneState.scrollY + 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ]; // se 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return handlers; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function renderScene( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   rc: RoughCanvas, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   context: CanvasRenderingContext2D, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -259,6 +363,8 @@ function renderScene( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   context.fillStyle = fillStyle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const selectedIndices = getSelectedIndices(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   elements.forEach(element => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     element.draw(rc, context, sceneState); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (element.isSelected) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -277,6 +383,23 @@ function renderScene( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         elementY2 - elementY1 + margin * 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       context.setLineDash(lineDash); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        element.type !== "text" && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        element.type !== "arrow" && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        selectedIndices.length === 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const handlers = handlerRectangles( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          elementX1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          elementX2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          elementY1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          elementY2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sceneState 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.values(handlers).forEach(handler => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          context.strokeRect(handler[0], handler[1], handler[2], handler[3]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -595,6 +718,7 @@ function restore() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type AppState = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   draggingElement: ExcalidrawElement | null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  resizingElement: ExcalidrawElement | null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   elementType: string; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   exportBackground: boolean; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   exportVisibleOnly: boolean; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -693,6 +817,7 @@ class App extends React.Component<{}, AppState> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   public state: AppState = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     draggingElement: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    resizingElement: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     elementType: "selection", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     exportBackground: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     exportVisibleOnly: true, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1018,40 +1143,65 @@ class App extends React.Component<{}, AppState> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               this.state.currentItemStrokeColor, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               this.state.currentItemBackgroundColor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let resizeHandle: string | false = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let isDraggingElements = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let isResizingElements = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             const cursorStyle = document.documentElement.style.cursor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (this.state.elementType === "selection") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              let hitElement = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              // We need to to hit testing from front (end of the array) to back (beginning of the array) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              for (let i = elements.length - 1; i >= 0; --i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (hitTest(elements[i], x, y)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  hitElement = elements[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              const resizeElement = elements.find(element => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return resizeTest(element, x, y, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  scrollX: this.state.scrollX, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  scrollY: this.state.scrollY, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  viewBackgroundColor: this.state.viewBackgroundColor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.setState({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                resizingElement: resizeElement ? resizeElement : null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (resizeElement) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                resizeHandle = resizeTest(resizeElement, x, y, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  scrollX: this.state.scrollX, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  scrollY: this.state.scrollY, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  viewBackgroundColor: this.state.viewBackgroundColor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                document.documentElement.style.cursor = `${resizeHandle}-resize`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                isResizingElements = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let hitElement = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // We need to to hit testing from front (end of the array) to back (beginning of the array) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for (let i = elements.length - 1; i >= 0; --i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  if (hitTest(elements[i], x, y)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    hitElement = elements[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              // If we click on something 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (hitElement) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (hitElement.isSelected) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  // If that element is not already selected, do nothing, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  // we're likely going to drag it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  // We unselect every other elements unless shift is pressed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  if (!e.shiftKey) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    clearSelection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // If we click on something 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (hitElement) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  if (hitElement.isSelected) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // If that element is not already selected, do nothing, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // we're likely going to drag it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // We unselect every other elements unless shift is pressed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (!e.shiftKey) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      clearSelection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // No matter what, we select it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    hitElement.isSelected = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  // No matter what, we select it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  hitElement.isSelected = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  // If we don't click on anything, let's remove all the selected elements 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  clearSelection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // If we don't click on anything, let's remove all the selected elements 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                clearSelection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              isDraggingElements = someElementIsSelected(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                isDraggingElements = someElementIsSelected(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (isDraggingElements) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                document.documentElement.style.cursor = "move"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (isDraggingElements) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  document.documentElement.style.cursor = "move"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1100,6 +1250,65 @@ class App extends React.Component<{}, AppState> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (isResizingElements && this.state.resizingElement) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const el = this.state.resizingElement; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const selectedElements = elements.filter(el => el.isSelected); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (selectedElements.length === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  const x = e.clientX - target.offsetLeft - this.state.scrollX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  const y = e.clientY - target.offsetTop - this.state.scrollY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  selectedElements.forEach(element => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    switch (resizeHandle) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      case "nw": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.width += element.x - lastX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.height += element.y - lastY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.x = lastX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.y = lastY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      case "ne": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.width = lastX - element.x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.height += element.y - lastY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.y = lastY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      case "sw": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.width += element.x - lastX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.x = lastX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.height = lastY - element.y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      case "se": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.width += x - lastX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (e.shiftKey) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          element.height = element.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          element.height += y - lastY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      case "n": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.height += element.y - lastY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.y = lastY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      case "w": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.width += element.x - lastX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.x = lastX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      case "s": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.height = lastY - element.y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      case "e": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        element.width = lastX - element.x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    el.x = element.x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    el.y = element.y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    generateDraw(el); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  lastX = x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  lastY = y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  this.forceUpdate(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               if (isDraggingElements) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 const selectedElements = elements.filter(el => el.isSelected); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (selectedElements.length) { 
			 |