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