Initial project import
This commit is contained in:
93
node_modules/@react-three/drei/web/CycleRaycast.js
generated
vendored
Normal file
93
node_modules/@react-three/drei/web/CycleRaycast.js
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
import * as React from 'react';
|
||||
import { useThree } from '@react-three/fiber';
|
||||
|
||||
function CycleRaycast({
|
||||
onChanged,
|
||||
portal,
|
||||
preventDefault = true,
|
||||
scroll = true,
|
||||
keyCode = 9
|
||||
}) {
|
||||
const cycle = React.useRef(0);
|
||||
const setEvents = useThree(state => state.setEvents);
|
||||
const get = useThree(state => state.get);
|
||||
const gl = useThree(state => state.gl);
|
||||
React.useEffect(() => {
|
||||
var _portal$current;
|
||||
let hits = [];
|
||||
let lastEvent = undefined;
|
||||
const prev = get().events.filter;
|
||||
const target = (_portal$current = portal == null ? void 0 : portal.current) !== null && _portal$current !== void 0 ? _portal$current : gl.domElement.parentNode;
|
||||
|
||||
// Render custom status
|
||||
const renderStatus = () => target && onChanged && onChanged(hits, Math.round(cycle.current) % hits.length);
|
||||
|
||||
// Overwrite the raycasters custom filter (this only exists in r3f)
|
||||
setEvents({
|
||||
filter: (intersections, state) => {
|
||||
// Reset cycle when the intersections change
|
||||
let clone = [...intersections];
|
||||
if (clone.length !== hits.length || !hits.every(hit => clone.map(e => e.object.uuid).includes(hit.object.uuid))) {
|
||||
cycle.current = 0;
|
||||
hits = clone;
|
||||
renderStatus();
|
||||
}
|
||||
// Run custom filter if there is one
|
||||
if (prev) clone = prev(clone, state);
|
||||
// Cycle through the actual raycast intersects
|
||||
for (let i = 0; i < Math.round(cycle.current) % clone.length; i++) {
|
||||
const first = clone.shift();
|
||||
clone = [...clone, first];
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
});
|
||||
|
||||
// Cycle, refresh events and render status
|
||||
const refresh = fn => {
|
||||
var _get$events$handlers, _get$events$handlers2;
|
||||
cycle.current = fn(cycle.current);
|
||||
// Cancel hovered elements and fake a pointer-move
|
||||
(_get$events$handlers = get().events.handlers) == null || _get$events$handlers.onPointerCancel(undefined);
|
||||
(_get$events$handlers2 = get().events.handlers) == null || _get$events$handlers2.onPointerMove(lastEvent);
|
||||
renderStatus();
|
||||
};
|
||||
|
||||
// Key events
|
||||
const tabEvent = event => {
|
||||
if ((event.keyCode || event.which) === keyCode) {
|
||||
if (preventDefault) event.preventDefault();
|
||||
if (hits.length > 1) refresh(current => current + 1);
|
||||
}
|
||||
};
|
||||
|
||||
// Wheel events
|
||||
const wheelEvent = event => {
|
||||
if (preventDefault) event.preventDefault();
|
||||
let delta = 0;
|
||||
if (!event) event = window.event;
|
||||
if (event.wheelDelta) delta = event.wheelDelta / 120;else if (event.detail) delta = -event.detail / 3;
|
||||
if (hits.length > 1) refresh(current => Math.abs(current - delta));
|
||||
};
|
||||
|
||||
// Catch last move event and position custom status
|
||||
const moveEvent = event => lastEvent = event;
|
||||
document.addEventListener('pointermove', moveEvent, {
|
||||
passive: true
|
||||
});
|
||||
if (scroll) document.addEventListener('wheel', wheelEvent);
|
||||
if (keyCode !== undefined) document.addEventListener('keydown', tabEvent);
|
||||
return () => {
|
||||
// Clean up
|
||||
setEvents({
|
||||
filter: prev
|
||||
});
|
||||
if (keyCode !== undefined) document.removeEventListener('keydown', tabEvent);
|
||||
if (scroll) document.removeEventListener('wheel', wheelEvent);
|
||||
document.removeEventListener('pointermove', moveEvent);
|
||||
};
|
||||
}, [gl, get, setEvents, preventDefault, scroll, keyCode]);
|
||||
return null;
|
||||
}
|
||||
|
||||
export { CycleRaycast };
|
||||
Reference in New Issue
Block a user