Initial project import
This commit is contained in:
104
node_modules/@react-three/drei/web/KeyboardControls.js
generated
vendored
Normal file
104
node_modules/@react-three/drei/web/KeyboardControls.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
import * as React from 'react';
|
||||
import { create } from 'zustand';
|
||||
import { subscribeWithSelector } from 'zustand/middleware';
|
||||
|
||||
// These are removed in Zustand v4
|
||||
// unknown
|
||||
|
||||
// Zustand v3 marked deprecations in 3.x, but there's no visible upgrade path
|
||||
|
||||
const context = /* @__PURE__ */React.createContext(null);
|
||||
function KeyboardControls({
|
||||
map,
|
||||
children,
|
||||
onChange,
|
||||
domElement
|
||||
}) {
|
||||
const key = map.map(item => item.name + item.keys).join('-');
|
||||
const useControls = React.useMemo(() => {
|
||||
return create(subscribeWithSelector(() => map.reduce((prev, cur) => ({
|
||||
...prev,
|
||||
[cur.name]: false
|
||||
}), {})));
|
||||
}, [key]);
|
||||
const api = React.useMemo(() => [useControls.subscribe, useControls.getState, useControls], [key]);
|
||||
const set = useControls.setState;
|
||||
React.useEffect(() => {
|
||||
const config = map.map(({
|
||||
name,
|
||||
keys,
|
||||
up
|
||||
}) => ({
|
||||
keys,
|
||||
up,
|
||||
fn: value => {
|
||||
// Set zustand state
|
||||
set({
|
||||
[name]: value
|
||||
});
|
||||
// Inform callback
|
||||
if (onChange) onChange(name, value, api[1]());
|
||||
}
|
||||
}));
|
||||
const keyMap = config.reduce((out, {
|
||||
keys,
|
||||
fn,
|
||||
up = true
|
||||
}) => {
|
||||
keys.forEach(key => out[key] = {
|
||||
fn,
|
||||
pressed: false,
|
||||
up
|
||||
});
|
||||
return out;
|
||||
}, {});
|
||||
const downHandler = ({
|
||||
key,
|
||||
code
|
||||
}) => {
|
||||
const obj = keyMap[key] || keyMap[code];
|
||||
if (!obj) return;
|
||||
const {
|
||||
fn,
|
||||
pressed,
|
||||
up
|
||||
} = obj;
|
||||
obj.pressed = true;
|
||||
if (up || !pressed) fn(true);
|
||||
};
|
||||
const upHandler = ({
|
||||
key,
|
||||
code
|
||||
}) => {
|
||||
const obj = keyMap[key] || keyMap[code];
|
||||
if (!obj) return;
|
||||
const {
|
||||
fn,
|
||||
up
|
||||
} = obj;
|
||||
obj.pressed = false;
|
||||
if (up) fn(false);
|
||||
};
|
||||
const source = domElement || window;
|
||||
source.addEventListener('keydown', downHandler, {
|
||||
passive: true
|
||||
});
|
||||
source.addEventListener('keyup', upHandler, {
|
||||
passive: true
|
||||
});
|
||||
return () => {
|
||||
source.removeEventListener('keydown', downHandler);
|
||||
source.removeEventListener('keyup', upHandler);
|
||||
};
|
||||
}, [domElement, key]);
|
||||
return /*#__PURE__*/React.createElement(context.Provider, {
|
||||
value: api,
|
||||
children: children
|
||||
});
|
||||
}
|
||||
function useKeyboardControls(sel) {
|
||||
const [sub, get, store] = React.useContext(context);
|
||||
if (sel) return store(sel);else return [sub, get];
|
||||
}
|
||||
|
||||
export { KeyboardControls, useKeyboardControls };
|
||||
Reference in New Issue
Block a user