=> [
[0, 0],
@@ -156,16 +142,7 @@ const Diagnostic = styled(
[clientRectCallback]
);
- useEffect(() => {
- // Set the 'wheel' event listener directly on the element
- // React sets event listeners on the window and routes them back via event propagation. As of Chrome 73 or something, 'wheel' events on the 'window' are automatically treated as 'passive'. Seems weird, but whatever
- if (ref !== null) {
- ref.addEventListener('wheel', handleWheel);
- return () => {
- ref.removeEventListener('wheel', handleWheel);
- };
- }
- }, [handleWheel, ref]);
+ useNonPassiveWheelHandler(handleWheel, ref);
return (
@@ -182,6 +159,36 @@ const Diagnostic = styled(
position: relative;
`;
+const DiagnosticDot = styled(
+ React.memo(({ className, worldPosition }: { className?: string; worldPosition: Vector2 }) => {
+ const projectionMatrix = useSelector(selectors.projectionMatrix);
+ const [left, top] = applyMatrix3(worldPosition, projectionMatrix);
+ const style = {
+ left: (left - 20).toString() + 'px',
+ top: (top - 20).toString() + 'px',
+ };
+ return (
+
+ x: {worldPosition[0]}
+
+ y: {worldPosition[1]}
+
+ );
+ })
+)`
+ position: absolute;
+ width: 40px;
+ height: 40px;
+ text-align: left;
+ font-size: 10px;
+ user-select: none;
+ border: 1px solid black;
+ box-sizing: border-box;
+ border-radius: 10%;
+ padding: 4px;
+ white-space: nowrap;
+`;
+
/**
* Returns a DOMRect sometimes, and a `ref` callback. Put the `ref` as the `ref` property of an element, and
* DOMRect will be the result of getBoundingClientRect on it.
@@ -215,32 +222,22 @@ function useAutoUpdatingClientRect(): [DOMRect | undefined, (node: Element | nul
return [rect, ref];
}
-const DiagnosticDot = styled(
- React.memo(({ className, worldPosition }: { className?: string; worldPosition: Vector2 }) => {
- const projectionMatrix = useSelector(selectors.projectionMatrix);
- const [left, top] = applyMatrix3(worldPosition, projectionMatrix);
- const style = {
- left: (left - 20).toString() + 'px',
- top: (top - 20).toString() + 'px',
- };
- return (
-
- x: {worldPosition[0]}
-
- y: {worldPosition[1]}
-
- );
- })
-)`
- position: absolute;
- width: 40px;
- height: 40px;
- text-align: left;
- font-size: 10px;
- user-select: none;
- border: 1px solid black;
- box-sizing: border-box;
- border-radius: 10%;
- padding: 4px;
- white-space: nowrap;
-`;
+/**
+ * Register an event handler directly on `elementRef` for the `wheel` event, with no options
+ * React sets native event listeners on the `window` and calls provided handlers via event propagation.
+ * As of Chrome 73, `'wheel'` events on `window` are automatically treated as 'passive'.
+ * If you don't need to call `event.preventDefault` then you should use regular React event handling instead.
+ */
+function useNonPassiveWheelHandler(
+ handler: (event: WheelEvent) => void,
+ elementRef: HTMLElement | null
+) {
+ useEffect(() => {
+ if (elementRef !== null) {
+ elementRef.addEventListener('wheel', handler);
+ return () => {
+ elementRef.removeEventListener('wheel', handler);
+ };
+ }
+ }, [elementRef, handler]);
+}