From a9bd112f47f9ab9db426810e8ab6f9e3070d6095 Mon Sep 17 00:00:00 2001 From: Giovanni Giordano Date: Thu, 2 Jan 2020 12:43:04 +0100 Subject: [PATCH 1/3] Select element on click --- src/index.js | 103 +++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/src/index.js b/src/index.js index bce89ba8..115e979d 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,17 @@ import "./styles.css"; var elements = []; +function isInsideAnElement(x, y) { + return (element) => { + const x1 = getElementAbsoluteX1(element) + const x2 = getElementAbsoluteX2(element) + const y1 = getElementAbsoluteY1(element) + const y2 = getElementAbsoluteY2(element) + + return (x >= x1 && x <= x2) && (y >= y1 && y <= y2) + } +} + function newElement(type, x, y) { const element = { type: type, @@ -228,56 +239,55 @@ class App extends React.Component { onMouseDown={e => { const x = e.clientX - e.target.offsetLeft; const y = e.clientY - e.target.offsetTop; - const element = newElement(this.state.elementType, x, y); - let isDraggingElements = false; const cursorStyle = document.documentElement.style.cursor; if (this.state.elementType === "selection") { - isDraggingElements = elements.some(el => { - if (el.isSelected) { - const minX = Math.min(el.x, el.x + el.width); - const maxX = Math.max(el.x, el.x + el.width); - const minY = Math.min(el.y, el.y + el.height); - const maxY = Math.max(el.y, el.y + el.height); - return minX <= x && x <= maxX && minY <= y && y <= maxY; - } - }); + const selectedElement = elements.find(isInsideAnElement(x, y)) + + if (selectedElement) { + this.setState({ draggingElement: selectedElement }); + } + + isDraggingElements = elements.some(element => element.isSelected && isInsideAnElement(x, y)); + if (isDraggingElements) { document.documentElement.style.cursor = "move"; } - } - - if (this.state.elementType === "text") { - const text = prompt("What text do you want?"); - if (text === null) { - return; - } - element.text = text; - element.font = "20px Virgil"; - const font = context.font; - context.font = element.font; - element.measure = context.measureText(element.text); - context.font = font; - const height = - element.measure.actualBoundingBoxAscent + - element.measure.actualBoundingBoxDescent; - // Center the text - element.x -= element.measure.width / 2; - element.y -= element.measure.actualBoundingBoxAscent; - element.width = element.measure.width; - element.height = height; - } - - generateDraw(element); - elements.push(element); - if (this.state.elementType === "text") { - this.setState({ - draggingElement: null, - elementType: "selection" - }); - element.isSelected = true; } else { - this.setState({ draggingElement: element }); + const element = newElement(this.state.elementType, x, y); + + if (this.state.elementType === "text") { + const text = prompt("What text do you want?"); + if (text === null) { + return; + } + element.text = text; + element.font = "20px Virgil"; + const font = context.font; + context.font = element.font; + element.measure = context.measureText(element.text); + context.font = font; + const height = + element.measure.actualBoundingBoxAscent + + element.measure.actualBoundingBoxDescent; + // Center the text + element.x -= element.measure.width / 2; + element.y -= element.measure.actualBoundingBoxAscent; + element.width = element.measure.width; + element.height = height; + } + + generateDraw(element); + elements.push(element); + if (this.state.elementType === "text") { + this.setState({ + draggingElement: null, + elementType: "selection" + }); + element.isSelected = true; + } else { + this.setState({ draggingElement: element }); + } } let lastX = x; @@ -330,11 +340,8 @@ class App extends React.Component { if (this.state.elementType === "selection") { if (isDraggingElements) { isDraggingElements = false; - } else { - // Remove actual selection element - setSelection(draggingElement); - } - elements.pop(); + } + setSelection(draggingElement); } else { draggingElement.isSelected = true; } From 715efc054e8a0a4592519e7a2d692ba30c38ef14 Mon Sep 17 00:00:00 2001 From: Giovanni Giordano Date: Thu, 2 Jan 2020 15:56:34 +0100 Subject: [PATCH 2/3] Remove extra check for dragging --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 115e979d..7fe1e0dd 100644 --- a/src/index.js +++ b/src/index.js @@ -248,7 +248,7 @@ class App extends React.Component { this.setState({ draggingElement: selectedElement }); } - isDraggingElements = elements.some(element => element.isSelected && isInsideAnElement(x, y)); + isDraggingElements = elements.some(element => element.isSelected); if (isDraggingElements) { document.documentElement.style.cursor = "move"; From 61bdedaecf41564d62672d6f45783b1b74cd7dc3 Mon Sep 17 00:00:00 2001 From: Giovanni Giordano Date: Thu, 2 Jan 2020 16:07:04 +0100 Subject: [PATCH 3/3] Clear selection if no element is clicked --- src/index.js | 81 ++++++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/src/index.js b/src/index.js index 7c38695b..89c34d8f 100644 --- a/src/index.js +++ b/src/index.js @@ -327,6 +327,7 @@ class App extends React.Component { onMouseDown={e => { const x = e.clientX - e.target.offsetLeft; const y = e.clientY - e.target.offsetTop; + const element = newElement(this.state.elementType, x, y); let isDraggingElements = false; const cursorStyle = document.documentElement.style.cursor; if (this.state.elementType === "selection") { @@ -341,41 +342,39 @@ class App extends React.Component { if (isDraggingElements) { document.documentElement.style.cursor = "move"; } + } + + if (this.state.elementType === "text") { + const text = prompt("What text do you want?"); + if (text === null) { + return; + } + element.text = text; + element.font = "20px Virgil"; + const font = context.font; + context.font = element.font; + element.measure = context.measureText(element.text); + context.font = font; + const height = + element.measure.actualBoundingBoxAscent + + element.measure.actualBoundingBoxDescent; + // Center the text + element.x -= element.measure.width / 2; + element.y -= element.measure.actualBoundingBoxAscent; + element.width = element.measure.width; + element.height = height; + } + + generateDraw(element); + elements.push(element); + if (this.state.elementType === "text") { + this.setState({ + draggingElement: null, + elementType: "selection" + }); + element.isSelected = true; } else { - const element = newElement(this.state.elementType, x, y); - - if (this.state.elementType === "text") { - const text = prompt("What text do you want?"); - if (text === null) { - return; - } - element.text = text; - element.font = "20px Virgil"; - const font = context.font; - context.font = element.font; - element.measure = context.measureText(element.text); - context.font = font; - const height = - element.measure.actualBoundingBoxAscent + - element.measure.actualBoundingBoxDescent; - // Center the text - element.x -= element.measure.width / 2; - element.y -= element.measure.actualBoundingBoxAscent; - element.width = element.measure.width; - element.height = height; - } - - generateDraw(element); - elements.push(element); - if (this.state.elementType === "text") { - this.setState({ - draggingElement: null, - elementType: "selection" - }); - element.isSelected = true; - } else { - this.setState({ draggingElement: element }); - } + this.setState({ draggingElement: element }); } let lastX = x; @@ -417,22 +416,30 @@ class App extends React.Component { }; const onMouseUp = e => { + const { draggingElement, elementType } = this.state + window.removeEventListener("mousemove", onMouseMove); window.removeEventListener("mouseup", onMouseUp); + document.documentElement.style.cursor = cursorStyle; - const draggingElement = this.state.draggingElement; + // if no element is clicked, clear the selection and redraw if (draggingElement === null) { - return; + clearSelection() + drawScene(); + return } - if (this.state.elementType === "selection") { + + if (elementType === "selection") { if (isDraggingElements) { isDraggingElements = false; } + elements.pop() setSelection(draggingElement); } else { draggingElement.isSelected = true; } + this.setState({ draggingElement: null, elementType: "selection"