@react-three/drei 9.84.0 → 9.84.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 CHANGED
@@ -754,54 +754,59 @@ useFrame((_, delta) => {
754
754
  #### MotionPathControls
755
755
 
756
756
  <p>
757
- <a href="https://codesandbox.io/s/drei-motion-path-controls-d9x4yf"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/drei-motion-path-n75jcq/screenshot.png" alt="Demo"/></a>
757
+ <a href="https://codesandbox.io/s/2y73c6"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/2y73c6/screenshot.png" alt="Demo"/></a>
758
758
  </p>
759
759
 
760
760
  Motion path controls, it takes a path of bezier curves or catmull-rom curves as input and animates the passed `object` along that path. It can be configured to look upon an external object for staging or presentation purposes by adding a `focusObject` property (ref).
761
761
 
762
762
  ```tsx
763
763
  type MotionPathProps = JSX.IntrinsicElements['group'] & {
764
- curves?: THREE.Curve[] // The curves from which the curve path is constructed, default: []
765
- debug?: boolean // show the path on which the object animates, default: false
766
- object?: React.MutableRefObject<THREE.Object3D> // default: default camera
767
- focus?: [x: number, y: number, z: number] | React.MutableRefObject<THREE.Object3D> // default: undefined
768
- offset?: number // manually progress the object along the path (0 - 1), default: undefined
769
- smooth?: boolean // whether or not to smooth out the curve path, default: false
770
- eps?: number // End of animation precision, default: 0.00001
771
- damping?: number // Approximate time to reach the target. A smaller value will reach the target faster. default: 0.1
772
- maxSpeed?: number // Optionally allows you to clamp the maximum speed. default: Infinity
764
+ /** An optional array of THREE curves */
765
+ curves?: THREE.Curve<THREE.Vector3>[]
766
+ /** Show debug helpers */
767
+ debug?: boolean
768
+ /** The target object that is moved, default: null (the default camera) */
769
+ object?: React.MutableRefObject<THREE.Object3D>
770
+ /** An object where the target looks towards, can also be a vector, default: null */
771
+ focus?: [x: number, y: number, z: number] | React.MutableRefObject<THREE.Object3D>
772
+ /** Position between 0 (start) and end (1), if this is not set useMotion().current must be used, default: null */
773
+ offset?: number
774
+ /** Optionally smooth the curve, default: false */
775
+ smooth?: boolean | number
776
+ /** Damping tolerance, default: 0.00001 */
777
+ eps?: number
778
+ /** Damping factor for movement along the curve, default: 0.1 */
779
+ damping?: number
780
+ /** Damping factor for lookAt, default: 0.1 */
781
+ focusDamping?: number
782
+ /** Damping maximum speed, default: Infinity */
783
+ maxSpeed?: number
773
784
  }
774
785
  ```
775
786
 
776
- ```jsx
777
- const poi = useRef()
778
-
779
- function Loop({ factor = 0.2 }) {
780
- const motion = useMotion()
781
- useFrame((state, delta) => (motion.current += delta * factor))
782
- }
783
-
784
- <MotionPathControls
785
- focus={poi}
786
- damping={0.2}
787
- >
788
- <cubicBezierCurve3 v0={[-5, -5, 0]} v1={[-10, 0, 0]} v2={[0, 3, 0]} v3={[6, 3, 0]} />
789
- <cubicBezierCurve3 v0={[6, 3, 0]} v1={[10, 5, 5]} v2={[5, 5, 5]} v3={[5, 5, 5]} />
790
- <Loop />
791
- </MotionPathControls>
792
-
793
- <Box args={[1, 1, 1]} ref={poi}/>
787
+ You can use MotionPathControls with declarative curves.
794
788
 
789
+ ```jsx
790
+ function App() {
791
+ const poi = useRef()
792
+ return (
793
+ <group>
794
+ <MotionPathControls offset={0} focus={poi} damping={0.2}>
795
+ <cubicBezierCurve3 v0={[-5, -5, 0]} v1={[-10, 0, 0]} v2={[0, 3, 0]} v3={[6, 3, 0]} />
796
+ <cubicBezierCurve3 v0={[6, 3, 0]} v1={[10, 5, 5]} v2={[5, 5, 5]} v3={[5, 5, 5]} />
797
+ </MotionPathControls>
798
+ <Box args={[1, 1, 1]} ref={poi}/>
795
799
  ```
796
800
 
797
- ```jsx
798
- const poi = useRef()
801
+ Or with imperative curves.
799
802
 
803
+ ```jsx
800
804
  <MotionPathControls
805
+ offset={0}
801
806
  focus={poi}
802
807
  damping={0.2}
803
808
  curves={[
804
- new THREE.CubicBezierCurve3(
809
+ new THREE.CubicBezierCurve3(
805
810
  new THREE.Vector3(-5, -5, 0),
806
811
  new THREE.Vector3(-10, 0, 0),
807
812
  new THREE.Vector3(0, 3, 0),
@@ -813,12 +818,50 @@ const poi = useRef()
813
818
  new THREE.Vector3(5, 3, 5),
814
819
  new THREE.Vector3(5, 5, 5)
815
820
  ),
816
- ]}
821
+ ]}
817
822
  />
823
+ ```
824
+
825
+ You can exert full control with the `useMotion` hook, it allows you to define the current position along the path for instance, or define your own lookAt. Keep in mind that MotionPathControls will still these values unless you set damping and focusDamping to 0. Then you can also employ your own easing.
818
826
 
819
- <Box args={[1, 1, 1]} ref={poi}/>
827
+ ```tsx
828
+ type MotionState = {
829
+ /** The user-defined, mutable, current goal position along the curve, it may be >1 or <0 */
830
+ current: number
831
+ /** The combined curve */
832
+ path: THREE.CurvePath<THREE.Vector3>
833
+ /** The focus object */
834
+ focus: React.MutableRefObject<THREE.Object3D<THREE.Event>> | [x: number, y: number, z: number] | undefined
835
+ /** The target object that is moved along the curve */
836
+ object: React.MutableRefObject<THREE.Object3D<THREE.Event>>
837
+ /** The automated, 0-1 normalised and damped current goal position along curve */
838
+ offset: number
839
+ /** The current point on the curve */
840
+ point: THREE.Vector3
841
+ /** The current tangent on the curve */
842
+ tangent: THREE.Vector3
843
+ /** The next point on the curve */
844
+ next: THREE.Vector3
845
+ }
846
+
847
+ const state: MotionState = useMotion()
820
848
  ```
821
849
 
850
+ ```jsx
851
+ function Loop() {
852
+ const motion = useMotion()
853
+ useFrame((state, delta) => {
854
+ // Set the current position along the curve, you can increment indiscriminately for a loop
855
+ motion.current += delta
856
+ // Look ahead on the curve
857
+ motion.object.lookAt(motion.next)
858
+ })
859
+ }
860
+
861
+ <MotionPathControls>
862
+ <cubicBezierCurve3 v0={[-5, -5, 0]} v1={[-10, 0, 0]} v2={[0, 3, 0]} v3={[6, 3, 0]} />
863
+ <Loop />
864
+ ```
822
865
 
823
866
  # Gizmos
824
867
 
@@ -1205,13 +1248,13 @@ export type FacemeshProps = {
1205
1248
  /** a landmark index (to get the position from) or a vec3 to be the origin of the mesh. default: undefined (ie. the bbox center) */
1206
1249
  origin?: number | THREE.Vector3
1207
1250
  /** A facial transformation matrix, as returned by FaceLandmarkerResult.facialTransformationMatrixes (see: https://developers.google.com/mediapipe/solutions/vision/face_landmarker/web_js#handle_and_display_results) */
1208
- facialTransformationMatrix?: typeof FacemeshDatas.SAMPLE_FACELANDMARKER_RESULT.facialTransformationMatrixes[0]
1251
+ facialTransformationMatrix?: (typeof FacemeshDatas.SAMPLE_FACELANDMARKER_RESULT.facialTransformationMatrixes)[0]
1209
1252
  /** Apply position offset extracted from `facialTransformationMatrix` */
1210
1253
  offset?: boolean
1211
1254
  /** Offset sensitivity factor, less is more sensible */
1212
1255
  offsetScalar?: number
1213
1256
  /** Fface blendshapes, as returned by FaceLandmarkerResult.faceBlendshapes (see: https://developers.google.com/mediapipe/solutions/vision/face_landmarker/web_js#handle_and_display_results) */
1214
- faceBlendshapes?: typeof FacemeshDatas.SAMPLE_FACELANDMARKER_RESULT.faceBlendshapes[0]
1257
+ faceBlendshapes?: (typeof FacemeshDatas.SAMPLE_FACELANDMARKER_RESULT.faceBlendshapes)[0]
1215
1258
  /** whether to enable eyes (nb. `faceBlendshapes` is required for), default: true */
1216
1259
  eyes?: boolean
1217
1260
  /** Force `origin` to be the middle of the 2 eyes (nb. `eyes` is required for), default: false */
@@ -2904,7 +2947,7 @@ function SuzanneFBX() {
2904
2947
  let fbx = useFBX('suzanne/suzanne.fbx')
2905
2948
  return <primitive object={fbx} />
2906
2949
  }
2907
- ````
2950
+ ```
2908
2951
 
2909
2952
  #### useTexture
2910
2953
 
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("three"),r=require("react"),n=require("@react-three/fiber"),o=require("maath");function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function c(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),a=c(t),i=c(r);const f=i.createContext(null);function l(){return i.useContext(f)}function p({points:e=50}){const{path:t}=l(),[r,n]=i.useState([]),[o]=i.useState((()=>new a.MeshBasicMaterial({color:"black"}))),[u]=i.useState((()=>new a.SphereGeometry(.025,16,16))),c=i.useRef([]);return i.useEffect((()=>{t.curves!==c.current&&(n(t.getPoints(e)),c.current=t.curves)})),i.createElement(i.Fragment,null,r.map(((e,t)=>i.createElement("mesh",{key:t,material:o,geometry:u,position:[e.x,e.y,e.z]}))))}const m=i.forwardRef((({children:e,curves:t=[],object:r,debug:u=!1,smooth:c=!1,focus:l,offset:m,eps:d=1e-5,damping:g=.1,lookupDamping:v=.1,maxSpeed:b=1/0,...h},j)=>{const{camera:y}=n.useThree(),P=i.useRef(),[w]=i.useState((()=>new a.CurvePath)),x=i.useRef(null!=m?m:0),O=i.useMemo((()=>({focus:l,object:(null==r?void 0:r.current)instanceof a.Object3D?r:{current:y},path:w,current:x.current,offset:x.current,point:new a.Vector3,tangent:new a.Vector3,next:new a.Vector3})),[l,r]);i.useLayoutEffect((()=>{var e;w.curves=[];const r=t.length>0?t:null==(e=P.current)?void 0:e.__r3f.objects;for(var n=0;n<r.length;n++)w.add(r[n]);if(c){const e=w.getPoints("number"==typeof c?c:1),t=new a.CatmullRomCurve3(e);w.curves=[t]}w.updateArcLengths()})),i.useImperativeHandle(j,(()=>P.current),[]),i.useLayoutEffect((()=>{x.current=o.misc.repeat(x.current,1)}),[m]);let E=0;const[C]=i.useState((()=>new a.Vector3));return n.useFrame(((e,t)=>{if(E=O.offset,o.easing.damp(x,"current",void 0!==m?m:O.current,g,t,b,void 0,d),O.offset=o.misc.repeat(x.current,1),w.getCurveLengths().length>0){w.getPointAt(O.offset,O.point),w.getTangentAt(O.offset,O.tangent).normalize(),w.getPointAt(o.misc.repeat(x.current-(E-O.offset),1),O.next);const e=(null==r?void 0:r.current)instanceof a.Object3D?r.current:y;e.position.copy(O.point),l&&o.easing.dampLookAt(e,(e=>(null==e?void 0:e.current)instanceof a.Object3D)(l)?l.current.getWorldPosition(C):l,v,t,b,void 0,d)}})),i.createElement("group",s.default({ref:P},h),i.createElement(f.Provider,{value:O},e,u&&i.createElement(p,null)))}));exports.MotionPathControls=m,exports.useMotion=l;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("three"),r=require("react"),n=require("@react-three/fiber"),o=require("maath");function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function c(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),a=c(t),i=c(r);const f=i.createContext(null);function l(){return i.useContext(f)}function p({points:e=50}){const{path:t}=l(),[r,n]=i.useState([]),[o]=i.useState((()=>new a.MeshBasicMaterial({color:"black"}))),[u]=i.useState((()=>new a.SphereGeometry(.025,16,16))),c=i.useRef([]);return i.useEffect((()=>{t.curves!==c.current&&(n(t.getPoints(e)),c.current=t.curves)})),i.createElement(i.Fragment,null,r.map(((e,t)=>i.createElement("mesh",{key:t,material:o,geometry:u,position:[e.x,e.y,e.z]}))))}const m=i.forwardRef((({children:e,curves:t=[],object:r,debug:u=!1,smooth:c=!1,focus:l,offset:m,eps:d=1e-5,damping:g=.1,focusDamping:v=.1,maxSpeed:b=1/0,...h},j)=>{const{camera:y}=n.useThree(),P=i.useRef(),[w]=i.useState((()=>new a.CurvePath)),x=i.useRef(null!=m?m:0),O=i.useMemo((()=>({focus:l,object:(null==r?void 0:r.current)instanceof a.Object3D?r:{current:y},path:w,current:x.current,offset:x.current,point:new a.Vector3,tangent:new a.Vector3,next:new a.Vector3})),[l,r]);i.useLayoutEffect((()=>{var e;w.curves=[];const r=t.length>0?t:null==(e=P.current)?void 0:e.__r3f.objects;for(var n=0;n<r.length;n++)w.add(r[n]);if(c){const e=w.getPoints("number"==typeof c?c:1),t=new a.CatmullRomCurve3(e);w.curves=[t]}w.updateArcLengths()})),i.useImperativeHandle(j,(()=>P.current),[]),i.useLayoutEffect((()=>{x.current=o.misc.repeat(x.current,1)}),[m]);let E=0;const[C]=i.useState((()=>new a.Vector3));return n.useFrame(((e,t)=>{if(E=O.offset,o.easing.damp(x,"current",void 0!==m?m:O.current,g,t,b,void 0,d),O.offset=o.misc.repeat(x.current,1),w.getCurveLengths().length>0){w.getPointAt(O.offset,O.point),w.getTangentAt(O.offset,O.tangent).normalize(),w.getPointAt(o.misc.repeat(x.current-(E-O.offset),1),O.next);const e=(null==r?void 0:r.current)instanceof a.Object3D?r.current:y;e.position.copy(O.point),l&&o.easing.dampLookAt(e,(e=>(null==e?void 0:e.current)instanceof a.Object3D)(l)?l.current.getWorldPosition(C):l,v,t,b,void 0,d)}})),i.createElement("group",s.default({ref:P},h),i.createElement(f.Provider,{value:O},e,u&&i.createElement(p,null)))}));exports.MotionPathControls=m,exports.useMotion=l;
@@ -1,10 +1,10 @@
1
1
  import * as THREE from 'three';
2
2
  import * as React from 'react';
3
3
  type MotionState = {
4
+ current: number;
4
5
  path: THREE.CurvePath<THREE.Vector3>;
5
6
  focus: React.MutableRefObject<THREE.Object3D<THREE.Event>> | [x: number, y: number, z: number] | undefined;
6
7
  object: React.MutableRefObject<THREE.Object3D<THREE.Event>>;
7
- current: number;
8
8
  offset: number;
9
9
  point: THREE.Vector3;
10
10
  tangent: THREE.Vector3;
@@ -12,7 +12,6 @@ function useMotion() {
12
12
  function Debug({
13
13
  points = 50
14
14
  }) {
15
- //@ts-ignore
16
15
  const {
17
16
  path
18
17
  } = useMotion();
@@ -45,7 +44,7 @@ const MotionPathControls = /*#__PURE__*/React.forwardRef(({
45
44
  offset = undefined,
46
45
  eps = 0.00001,
47
46
  damping = 0.1,
48
- lookupDamping = 0.1,
47
+ focusDamping = 0.1,
49
48
  maxSpeed = Infinity,
50
49
  ...props
51
50
  }, fref) => {
@@ -100,7 +99,7 @@ const MotionPathControls = /*#__PURE__*/React.forwardRef(({
100
99
  target.position.copy(state.point);
101
100
  //@ts-ignore
102
101
  if (focus) {
103
- easing.dampLookAt(target, isObject3DRef(focus) ? focus.current.getWorldPosition(vec) : focus, lookupDamping, delta, maxSpeed, undefined, eps);
102
+ easing.dampLookAt(target, isObject3DRef(focus) ? focus.current.getWorldPosition(vec) : focus, focusDamping, delta, maxSpeed, undefined, eps);
104
103
  }
105
104
  }
106
105
  });