@react-three/drei 9.31.2 → 9.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -4
- package/core/FlyControls.cjs.js +1 -1
- package/core/FlyControls.d.ts +1 -1
- package/core/FlyControls.js +15 -10
- package/core/MapControls.d.ts +1 -1
- package/core/TrackballControls.d.ts +1 -1
- package/core/useGLTF.d.ts +2 -2
- package/index.cjs.js +1 -1
- package/index.js +1 -0
- package/package.json +2 -2
- package/web/KeyboardControls.cjs.js +1 -0
- package/web/KeyboardControls.d.ts +19 -0
- package/web/KeyboardControls.js +101 -0
- package/web/index.cjs.js +1 -1
- package/web/index.d.ts +1 -0
- package/web/index.js +2 -0
package/README.md
CHANGED
|
@@ -48,7 +48,8 @@ The `native` route of the library **does not** export `Html` or `Loader`. The de
|
|
|
48
48
|
<li><a href="#controls">PointerLockControls</a></li>
|
|
49
49
|
<li><a href="#controls">FirstPersonControls</a></li>
|
|
50
50
|
<li><a href="#scrollcontrols">ScrollControls</a></li>
|
|
51
|
-
<li><a href="#presentationcontrols">PresentationControls</a></li>
|
|
51
|
+
<li><a href="#presentationcontrols">PresentationControls</a></li>
|
|
52
|
+
<li><a href="#keyboardcontrols">KeyboardControls</a></li>
|
|
52
53
|
</ul>
|
|
53
54
|
<li><a href="#gizmos">Gizmos</a></li>
|
|
54
55
|
<ul>
|
|
@@ -385,6 +386,79 @@ Semi-OrbitControls with spring-physics, polar zoom and snap-back, for presentati
|
|
|
385
386
|
</PresentationControls>
|
|
386
387
|
```
|
|
387
388
|
|
|
389
|
+
#### KeyboardControls
|
|
390
|
+
|
|
391
|
+

|
|
392
|
+
|
|
393
|
+
A rudimentary keyboard controller which distributes your defined data-model to the `useKeyboard` hook. It's a rather simple way to get started with keyboard input.
|
|
394
|
+
|
|
395
|
+
```tsx
|
|
396
|
+
type KeyboardControlsState = { [key: string]: boolean }
|
|
397
|
+
|
|
398
|
+
type KeyboardControlsEntry = {
|
|
399
|
+
/** Name of the action */
|
|
400
|
+
name: string
|
|
401
|
+
/** The keys that define it, you can use either event.key, or event.code */
|
|
402
|
+
keys: string[]
|
|
403
|
+
/** If the event receives the keyup event, true by default */
|
|
404
|
+
up?: boolean
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
type KeyboardControlsProps = {
|
|
408
|
+
/** A map of named keys */
|
|
409
|
+
map: KeyboardControlsEntry[]
|
|
410
|
+
/** All children will be able to useKeyboardControls */
|
|
411
|
+
children: React.ReactNode
|
|
412
|
+
/** Optional onchange event */
|
|
413
|
+
onChange: (name: string, pressed: boolean, state: KeyboardControlsState) => void
|
|
414
|
+
/** Optional event source */
|
|
415
|
+
domElement?: HTMLElement
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
You start by wrapping your app, or scene, into `<KeyboardControls>`.
|
|
420
|
+
|
|
421
|
+
```jsx
|
|
422
|
+
function App() {
|
|
423
|
+
return (
|
|
424
|
+
<KeyboardControls
|
|
425
|
+
map={[
|
|
426
|
+
{ name: 'forward', keys: ['ArrowUp', 'w', 'W'] },
|
|
427
|
+
{ name: 'backward', keys: ['ArrowDown', 's', 'S'] },
|
|
428
|
+
{ name: 'leftward', keys: ['ArrowLeft', 'a', 'A'] },
|
|
429
|
+
{ name: 'rightward', keys: ['ArrowRight', 'd', 'D'] },
|
|
430
|
+
{ name: 'jump', keys: ['Space'] },
|
|
431
|
+
]}>
|
|
432
|
+
<App />
|
|
433
|
+
</KeyboardControls>
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
You can either respond to input reactively, it uses zustand (width the `subscribeWithSelector` middleware) so all the rules apply:
|
|
437
|
+
|
|
438
|
+
```jsx
|
|
439
|
+
function Foo() {
|
|
440
|
+
const pressed = useKeyboardControls(state => foward)
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
Or transiently, either by `subscribe`, which is a function which returns a function to unsubscribe, so you can pair it with useEffect for cleanup, or `get`, which fetches fresh state non-reactively.
|
|
444
|
+
|
|
445
|
+
```jsx
|
|
446
|
+
function Foo() {
|
|
447
|
+
const [sub, get] = useKeyboardControls()
|
|
448
|
+
|
|
449
|
+
useEffect(() => {
|
|
450
|
+
return sub(state => state.forward, pressed => {
|
|
451
|
+
console.log('forward', pressed)
|
|
452
|
+
})
|
|
453
|
+
}, [])
|
|
454
|
+
|
|
455
|
+
useFrame(() => {
|
|
456
|
+
// Fetch fresh data from store
|
|
457
|
+
const pressed = get().backward
|
|
458
|
+
})
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
388
462
|
# Gizmos
|
|
389
463
|
|
|
390
464
|
#### GizmoHelper
|
|
@@ -2124,15 +2198,17 @@ function App() {
|
|
|
2124
2198
|
<PerformanceMonitor onIncline={() => setDpr(2)} onDecline={() => setDpr(1)} >
|
|
2125
2199
|
```
|
|
2126
2200
|
|
|
2127
|
-
You can also use the `onChange` callback to get notified when the average changes in whichever direction. This allows you to make gradual changes. It gives you a factor between 0 and 1, which is increased by incline and decreased by decline. The factor is initially 0.5 by default.
|
|
2201
|
+
You can also use the `onChange` callback to get notified when the average changes in whichever direction. This allows you to make gradual changes. It gives you a `factor` between 0 and 1, which is increased by incline and decreased by decline. The `factor` is initially 0.5 by default. If your app starts with lowest defaults and gradually increases quality set `factor` to 0. If it starts with highest defaults and decreases quality, set it to 1. If it starts in the middle and can either increase or decrease, set it to 0.5.
|
|
2202
|
+
|
|
2203
|
+
The following starts at the highest dpr (2) and clamps the gradual dpr between 0.5 at the lowest and 2 at the highest. If the app is in trouble it will reduce `factor` by `step` until it is either 0 or the app has found its sweet spot above that.
|
|
2128
2204
|
|
|
2129
2205
|
```jsx
|
|
2130
2206
|
import round from 'lodash/round'
|
|
2131
2207
|
|
|
2132
|
-
const [dpr, set] = useState(
|
|
2208
|
+
const [dpr, set] = useState(2)
|
|
2133
2209
|
return (
|
|
2134
2210
|
<Canvas dpr={dpr}>
|
|
2135
|
-
<PerformanceMonitor onChange={({ factor }) => setDpr(round(0.5 + 1.5 * factor, 1))} >
|
|
2211
|
+
<PerformanceMonitor factor={1} onChange={({ factor }) => setDpr(round(0.5 + 1.5 * factor, 1))} >
|
|
2136
2212
|
```
|
|
2137
2213
|
|
|
2138
2214
|
If you still experience flip flops despite the bounds you can define a limit of `flipflops`. If it is met `onFallback` will be triggered which typically sets a lowest possible baseline for the app. After the fallback has been called PerformanceMonitor will shut down.
|
package/core/FlyControls.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("@react-three/fiber"),r=require("react"),n=require("three-stdlib");function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("@react-three/fiber"),r=require("react"),n=require("three-stdlib");function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function o(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var s=u(e),c=o(r);const a=c.forwardRef((({domElement:e,...r},u)=>{const{onChange:o,...a}=r,i=t.useThree((e=>e.invalidate)),l=t.useThree((e=>e.camera)),f=t.useThree((e=>e.gl)),d=t.useThree((e=>e.events)),v=e||d.connected||f.domElement,b=c.useMemo((()=>new n.FlyControls(l)),[l]);return c.useEffect((()=>(b.connect(v),()=>{b.dispose()})),[v,b,i]),c.useEffect((()=>{const e=e=>{i(),o&&o(e)};return null==b.addEventListener||b.addEventListener("change",e),()=>null==b.removeEventListener?void 0:b.removeEventListener("change",e)}),[o,i]),t.useFrame(((e,t)=>b.update(t))),c.createElement("primitive",s.default({ref:u,object:b,args:[l,v]},a))}));exports.FlyControls=a;
|
package/core/FlyControls.d.ts
CHANGED
|
@@ -6,4 +6,4 @@ export declare type FlyControlsProps = ReactThreeFiber.Object3DNode<FlyControlsI
|
|
|
6
6
|
onChange?: (e?: THREE.Event) => void;
|
|
7
7
|
domElement?: HTMLElement;
|
|
8
8
|
};
|
|
9
|
-
export declare const FlyControls: React.ForwardRefExoticComponent<Pick<FlyControlsProps, "object" | "attach" | "args" | "children" | "key" | "onUpdate" | "position" | "up" | "scale" | "rotation" | "matrix" | "quaternion" | "layers" | "dispose" | "addEventListener" | "hasEventListener" | "removeEventListener" | "dispatchEvent" | "onChange" | keyof import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers | "update" | "domElement" | "movementSpeed" | "rollSpeed" | "dragToLook" | "autoForward"> & React.RefAttributes<FlyControlsImpl>>;
|
|
9
|
+
export declare const FlyControls: React.ForwardRefExoticComponent<Pick<FlyControlsProps, "object" | "attach" | "args" | "children" | "key" | "onUpdate" | "position" | "up" | "scale" | "rotation" | "matrix" | "quaternion" | "layers" | "dispose" | "addEventListener" | "hasEventListener" | "removeEventListener" | "dispatchEvent" | "onChange" | keyof import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers | "connect" | "update" | "domElement" | "movementSpeed" | "rollSpeed" | "dragToLook" | "autoForward"> & React.RefAttributes<FlyControlsImpl>>;
|
package/core/FlyControls.js
CHANGED
|
@@ -6,7 +6,7 @@ import { FlyControls as FlyControls$1 } from 'three-stdlib';
|
|
|
6
6
|
const FlyControls = /*#__PURE__*/React.forwardRef(({
|
|
7
7
|
domElement,
|
|
8
8
|
...props
|
|
9
|
-
},
|
|
9
|
+
}, fref) => {
|
|
10
10
|
const {
|
|
11
11
|
onChange,
|
|
12
12
|
...rest
|
|
@@ -16,21 +16,26 @@ const FlyControls = /*#__PURE__*/React.forwardRef(({
|
|
|
16
16
|
const gl = useThree(state => state.gl);
|
|
17
17
|
const events = useThree(state => state.events);
|
|
18
18
|
const explDomElement = domElement || events.connected || gl.domElement;
|
|
19
|
-
const
|
|
19
|
+
const controls = React.useMemo(() => new FlyControls$1(camera), [camera]);
|
|
20
|
+
React.useEffect(() => {
|
|
21
|
+
controls.connect(explDomElement);
|
|
22
|
+
return () => void controls.dispose();
|
|
23
|
+
}, [explDomElement, controls, invalidate]);
|
|
20
24
|
React.useEffect(() => {
|
|
21
25
|
const callback = e => {
|
|
22
26
|
invalidate();
|
|
23
27
|
if (onChange) onChange(e);
|
|
24
28
|
};
|
|
25
29
|
|
|
26
|
-
controls
|
|
27
|
-
return () => controls
|
|
28
|
-
}, [onChange,
|
|
29
|
-
useFrame((_, delta) => controls
|
|
30
|
-
return
|
|
31
|
-
ref:
|
|
32
|
-
object: controls
|
|
33
|
-
|
|
30
|
+
controls.addEventListener == null ? void 0 : controls.addEventListener('change', callback);
|
|
31
|
+
return () => controls.removeEventListener == null ? void 0 : controls.removeEventListener('change', callback);
|
|
32
|
+
}, [onChange, invalidate]);
|
|
33
|
+
useFrame((_, delta) => controls.update(delta));
|
|
34
|
+
return /*#__PURE__*/React.createElement("primitive", _extends({
|
|
35
|
+
ref: fref,
|
|
36
|
+
object: controls,
|
|
37
|
+
args: [camera, explDomElement]
|
|
38
|
+
}, rest));
|
|
34
39
|
});
|
|
35
40
|
|
|
36
41
|
export { FlyControls };
|
package/core/MapControls.d.ts
CHANGED
|
@@ -11,4 +11,4 @@ export declare type MapControlsProps = ReactThreeFiber.Overwrite<ReactThreeFiber
|
|
|
11
11
|
onEnd?: (e?: THREE.Event) => void;
|
|
12
12
|
domElement?: HTMLElement;
|
|
13
13
|
}>;
|
|
14
|
-
export declare const MapControls: React.ForwardRefExoticComponent<Pick<MapControlsProps, "object" | "attach" | "args" | "children" | "key" | "onUpdate" | "position" | "up" | "scale" | "rotation" | "matrix" | "quaternion" | "layers" | "dispose" | "addEventListener" | "hasEventListener" | "removeEventListener" | "dispatchEvent" | "onChange" | keyof import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers | "camera" | "reset" | "enabled" | "connect" | "update" | "target" | "onStart" | "keys" | "touches" | "
|
|
14
|
+
export declare const MapControls: React.ForwardRefExoticComponent<Pick<MapControlsProps, "object" | "attach" | "args" | "children" | "key" | "onUpdate" | "position" | "up" | "scale" | "rotation" | "matrix" | "quaternion" | "layers" | "dispose" | "addEventListener" | "hasEventListener" | "removeEventListener" | "dispatchEvent" | "onChange" | keyof import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers | "camera" | "reset" | "enabled" | "connect" | "update" | "target" | "onStart" | "keys" | "touches" | "domElement" | "makeDefault" | "minDistance" | "maxDistance" | "minZoom" | "maxZoom" | "minPolarAngle" | "maxPolarAngle" | "minAzimuthAngle" | "maxAzimuthAngle" | "enableDamping" | "dampingFactor" | "enableZoom" | "zoomSpeed" | "enableRotate" | "rotateSpeed" | "enablePan" | "panSpeed" | "screenSpacePanning" | "keyPanSpeed" | "autoRotate" | "autoRotateSpeed" | "reverseOrbit" | "mouseButtons" | "target0" | "position0" | "zoom0" | "_domElementKeyEvents" | "getPolarAngle" | "getAzimuthalAngle" | "setPolarAngle" | "setAzimuthalAngle" | "getDistance" | "listenToKeyEvents" | "saveState" | "onEnd"> & React.RefAttributes<MapControlsImpl>>;
|
|
@@ -12,4 +12,4 @@ export declare type TrackballControlsProps = ReactThreeFiber.Overwrite<ReactThre
|
|
|
12
12
|
onStart?: (e?: THREE.Event) => void;
|
|
13
13
|
onEnd?: (e?: THREE.Event) => void;
|
|
14
14
|
}>;
|
|
15
|
-
export declare const TrackballControls: React.ForwardRefExoticComponent<Pick<TrackballControlsProps, "object" | "attach" | "args" | "children" | "key" | "onUpdate" | "position" | "up" | "scale" | "rotation" | "matrix" | "quaternion" | "layers" | "dispose" | "addEventListener" | "hasEventListener" | "removeEventListener" | "dispatchEvent" | "onChange" | keyof import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers | "camera" | "screen" | "reset" | "enabled" | "connect" | "update" | "target" | "onStart" | "keys" | "
|
|
15
|
+
export declare const TrackballControls: React.ForwardRefExoticComponent<Pick<TrackballControlsProps, "object" | "attach" | "args" | "children" | "key" | "onUpdate" | "position" | "up" | "scale" | "rotation" | "matrix" | "quaternion" | "layers" | "dispose" | "addEventListener" | "hasEventListener" | "removeEventListener" | "dispatchEvent" | "onChange" | keyof import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers | "camera" | "screen" | "reset" | "enabled" | "connect" | "update" | "target" | "onStart" | "keys" | "domElement" | "makeDefault" | "minDistance" | "maxDistance" | "zoomSpeed" | "rotateSpeed" | "panSpeed" | "mouseButtons" | "onEnd" | "regress" | "noRotate" | "noZoom" | "noPan" | "staticMoving" | "dynamicDampingFactor" | "cursorZoom" | "handleResize"> & React.RefAttributes<TrackballControlsImpl>>;
|
package/core/useGLTF.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { GLTFLoader
|
|
2
|
-
export declare function useGLTF<T extends string | string[]>(path: T, useDraco?: boolean | string, useMeshOpt?: boolean, extendLoader?: (loader: GLTFLoader) => void): T extends any[] ? GLTF[] : GLTF;
|
|
1
|
+
import { GLTFLoader } from 'three-stdlib';
|
|
2
|
+
export declare function useGLTF<T extends string | string[]>(path: T, useDraco?: boolean | string, useMeshOpt?: boolean, extendLoader?: (loader: GLTFLoader) => void): T extends any[] ? (import("three/examples/jsm/loaders/GLTFLoader").GLTF & import("@react-three/fiber").ObjectMap)[] : import("three/examples/jsm/loaders/GLTFLoader").GLTF & import("@react-three/fiber").ObjectMap;
|
|
3
3
|
export declare namespace useGLTF {
|
|
4
4
|
var preload: (path: string | string[], useDraco?: string | boolean, useMeshOpt?: boolean, extendLoader?: ((loader: GLTFLoader) => void) | undefined) => undefined;
|
|
5
5
|
var clear: (input: string | string[]) => void;
|