Mouse move tracked outside window!

This commit is contained in:
Christopher Chedeau 2020-01-01 21:46:42 -08:00
parent 9aaaa24426
commit 457800caa3

View File

@ -150,10 +150,9 @@ function clearSelection() {
}); });
} }
function App() { class App extends React.Component {
const [draggingElement, setDraggingElement] = React.useState(null); componentDidMount() {
const [elementType, setElementType] = React.useState("selection"); this.onKeyDown = event => {
const onKeyDown = React.useCallback(event => {
if (event.key === "Backspace") { if (event.key === "Backspace") {
for (var i = elements.length - 1; i >= 0; --i) { for (var i = elements.length - 1; i >= 0; --i) {
if (elements[i].isSelected) { if (elements[i].isSelected) {
@ -180,22 +179,31 @@ function App() {
drawScene(); drawScene();
event.preventDefault(); event.preventDefault();
} }
}, []);
React.useEffect(() => {
document.addEventListener("keydown", onKeyDown, false);
return () => {
document.removeEventListener("keydown", onKeyDown, false);
}; };
}, [onKeyDown]); document.addEventListener("keydown", this.onKeyDown, false);
}
function ElementOption({ type, children }) { componentWillUnmount() {
document.removeEventListener("keydown", this.onKeyDown, false);
}
constructor() {
super();
this.state = {
draggingElement: null,
elementType: "selection"
};
}
render() {
const ElementOption = ({ type, children }) => {
return ( return (
<label> <label>
<input <input
type="radio" type="radio"
checked={elementType === type} checked={this.state.elementType === type}
onChange={() => { onChange={() => {
setElementType(type); this.setState({ elementType: type });
clearSelection(); clearSelection();
drawScene(); drawScene();
}} }}
@ -203,7 +211,8 @@ function App() {
{children} {children}
</label> </label>
); );
} };
return ( return (
<div> <div>
{/* Can't use the <ElementOption> form because ElementOption is re-defined {/* Can't use the <ElementOption> form because ElementOption is re-defined
@ -219,15 +228,12 @@ function App() {
id="canvas" id="canvas"
width={window.innerWidth} width={window.innerWidth}
height={window.innerHeight} height={window.innerHeight}
onClick={e => {
console.log("click");
}}
onMouseDown={e => { onMouseDown={e => {
const x = e.clientX - e.target.offsetLeft; const x = e.clientX - e.target.offsetLeft;
const y = e.clientY - e.target.offsetTop; const y = e.clientY - e.target.offsetTop;
const element = newElement(elementType, x, y); const element = newElement(this.state.elementType, x, y);
if (elementType === "text") { if (this.state.elementType === "text") {
const text = prompt("What text do you want?"); const text = prompt("What text do you want?");
if (text === null) { if (text === null) {
return; return;
@ -250,30 +256,17 @@ function App() {
generateDraw(element); generateDraw(element);
elements.push(element); elements.push(element);
if (elementType === "text") { if (this.state.elementType === "text") {
setDraggingElement(null); this.setState({ draggingElement: null });
element.isSelected = true; element.isSelected = true;
} else { } else {
setDraggingElement(element); this.setState({ draggingElement: element });
} }
drawScene();
}} const onMouseMove = e => {
onMouseUp={e => { // It is very important to read this.state within each move event,
if (draggingElement === null) { // otherwise we would read a stale one!
return; const draggingElement = this.state.draggingElement;
}
if (elementType === "selection") {
// Remove actual selection element
elements.pop();
setSelection(draggingElement);
} else {
draggingElement.isSelected = true;
}
setDraggingElement(null);
setElementType("selection");
drawScene();
}}
onMouseMove={e => {
if (!draggingElement) return; if (!draggingElement) return;
let width = e.clientX - e.target.offsetLeft - draggingElement.x; let width = e.clientX - e.target.offsetLeft - draggingElement.x;
let height = e.clientY - e.target.offsetTop - draggingElement.y; let height = e.clientY - e.target.offsetTop - draggingElement.y;
@ -283,15 +276,43 @@ function App() {
generateDraw(draggingElement); generateDraw(draggingElement);
if (elementType === "selection") { if (this.state.elementType === "selection") {
setSelection(draggingElement); setSelection(draggingElement);
} }
drawScene();
};
const onMouseUp = e => {
window.removeEventListener("mousemove", onMouseMove);
window.removeEventListener("mouseup", onMouseUp);
const draggingElement = this.state.draggingElement;
if (draggingElement === null) {
return;
}
if (this.state.elementType === "selection") {
// Remove actual selection element
elements.pop();
setSelection(draggingElement);
} else {
draggingElement.isSelected = true;
}
this.setState({ draggingElement: null });
this.setState({ elementType: "selection" });
drawScene();
};
window.addEventListener("mousemove", onMouseMove);
window.addEventListener("mouseup", onMouseUp);
drawScene(); drawScene();
}} }}
/> />
</div> </div>
); );
}
} }
const rootElement = document.getElementById("root"); const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement); ReactDOM.render(<App />, rootElement);
const canvas = document.getElementById("canvas"); const canvas = document.getElementById("canvas");