feat: improves mouse tracking

This commit is contained in:
Mark Mankarious
2023-03-22 22:01:09 +00:00
parent 5874aae6b2
commit 77e8c02c73
2 changed files with 54 additions and 23 deletions

View File

@@ -1,6 +1,6 @@
import React, { useContext } from "react";
import React, { useRef, useEffect, useContext } from "react";
import { observer } from "mobx-react";
import { useRef, useEffect, useState } from "react";
import Box from "@mui/material/Box";
import { Renderer } from "../renderer/Renderer";
import { useGlobalState } from "../hooks/useGlobalState";
import { useMouseInput } from "../hooks/useMouseInput";
@@ -21,10 +21,6 @@ export const RendererContainer = observer(() => {
setDomEl(rendererEl.current);
modeManager.setRenderer(renderer);
modeManager.activateMode(Select);
}, [setRenderer, setDomEl, modeManager]);
useEffect(() => {
if (!modeManager) return;
setCallbacks({
onMouseMove: (event) => {
@@ -43,7 +39,7 @@ export const RendererContainer = observer(() => {
modeManager.onMouseEvent("MOUSE_LEAVE", event);
},
});
}, [setCallbacks, modeManager]);
}, [setRenderer, setDomEl, modeManager]);
return (
<div

View File

@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useEffect, useState, useCallback } from "react";
interface MouseCoords {
x: number;
@@ -20,29 +20,64 @@ interface MouseEvents {
onMouseLeave: _MouseEvent;
}
const mouseEventToCoords = (e: MouseEvent) => {
return {
x: e.clientX,
y: e.clientY,
};
};
const getOffset = (domEl?: HTMLElement) => {
if (!domEl)
return {
top: 0,
left: 0,
};
const parseMousePosition = (e: MouseEvent, mousedown: MouseCoords | null) => {
const current = mouseEventToCoords(e);
const delta = mousedown
? { x: current.x - mousedown.x, y: current.y - mousedown.y }
: null;
const box = domEl.getBoundingClientRect();
return {
position: { x: current.x, y: current.y },
delta,
};
const body = document.body;
const docEl = document.documentElement;
const scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
const scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
const clientTop = docEl.clientTop || body.clientTop || 0;
const clientLeft = docEl.clientLeft || body.clientLeft || 0;
const top = box.top + scrollTop - clientTop;
const left = box.left + scrollLeft - clientLeft;
return { top: Math.round(top), left: Math.round(left) };
};
export const useMouseInput = () => {
const [domEl, setDomEl] = useState<HTMLDivElement>();
const [callbacks, setCallbacks] = useState<MouseEvents>();
const mouseEventToCoords = useCallback(
(e: MouseEvent) => {
const offset = getOffset(domEl);
return {
x: e.clientX - offset.left + window.scrollX,
y: e.clientY - offset.top + window.scrollY,
};
},
[domEl]
);
const parseMousePosition = useCallback(
(e: MouseEvent, mousedown: MouseCoords | null) => {
const current = mouseEventToCoords(e);
const delta = mousedown
? {
x: current.x - mousedown.x,
y: current.y - mousedown.y,
}
: null;
return {
position: { x: current.x, y: current.y },
delta,
};
},
[mouseEventToCoords]
);
useEffect(() => {
if (!callbacks || !domEl) return;