@react-three/drei 9.25.3 → 9.26.0

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
@@ -47,23 +47,24 @@ The `native` route of the library **does not** export `Html` or `Loader`. The de
47
47
  <li><a href="#controls">TrackballControls</a></li>
48
48
  <li><a href="#controls">ArcballControls</a></li>
49
49
  <li><a href="#controls">PointerLockControls</a></li>
50
- <li><a href="#controls">FirstPersonControls</a></li>
51
- <li><a href="#transformcontrols">TransformControls</a></li>
50
+ <li><a href="#controls">FirstPersonControls</a></li>
52
51
  <li><a href="#scrollcontrols">ScrollControls</a></li>
53
- <li><a href="#presentationcontrols">PresentationControls</a></li>
52
+ <li><a href="#presentationcontrols">PresentationControls</a></li>
53
+ </ul>
54
+ <li><a href="#gizmos">Gizmos</a></li>
55
+ <ul>
56
+ <li><a href="#gizmohelper">GizmoHelper</a></li>
57
+ <li><a href="#pivotcontrols">PivotControls</a></li>
58
+ <li><a href="#transformcontrols">TransformControls</a></li>
59
+ <li><a href="#usehelper">useHelper</a></li>
54
60
  </ul>
55
61
  <li><a href="#abstractions">Abstractions</a></li>
56
62
  <ul>
57
63
  <li><a href="#image">Image</a></li>
58
64
  <li><a href="#text">Text</a></li>
59
- <li><a href="#text3d">Text3D</a></li>
60
- <li><a href="#line">Line</a></li>
61
- <li><a href="#quadraticbezierline">QuadraticBezierLine</a></li>
62
- <li><a href="#cubicbezierline">CubicBezierLine</a></li>
63
- <li><a href="#catmullromline">CatmullRomLine</a></li>
65
+ <li><a href="#text3d">Text3D</a></li>
64
66
  <li><a href="#positionalaudio">PositionalAudio</a></li>
65
67
  <li><a href="#billboard">Billboard</a></li>
66
- <li><a href="#gizmohelper">GizmoHelper</a></li>
67
68
  <li><a href="#effects">Effects</a></li>
68
69
  <li><a href="#gradienttexture">GradientTexture</a></li>
69
70
  <li><a href="#edges">Edges</a></li>
@@ -102,15 +103,13 @@ The `native` route of the library **does not** export `Html` or `Loader`. The de
102
103
  <li><a href="#usecontextbridge">useContextBridge</a></li>
103
104
  <li><a href="#usefbo">useFBO</a></li>
104
105
  <li><a href="#usecamera">useCamera</a></li>
105
- <li><a href="#usedetectgpu">useDetectGPU</a></li>
106
- <li><a href="#usehelper">useHelper</a></li>
106
+ <li><a href="#usedetectgpu">useDetectGPU</a></li>
107
107
  <li><a href="#useaspect">useAspect</a></li>
108
108
  <li><a href="#usecursor">useCursor</a></li>
109
109
  <li><a href="#useintersect">useIntersect</a></li>
110
110
  <li><a href="#useboxprojectedenv">useBoxProjectedEnv</a></li>
111
111
  <li><a href="#useTrail">useTrail</a></li>
112
112
  <li><a href="#useSurfaceSampler">useSurfaceSampler</a></li>
113
- <li><a href="#BBAnchor">BBAnchor</a></li>
114
113
  </ul>
115
114
  <li><a href="#loading">Loaders</a></li>
116
115
  <ul>
@@ -168,10 +167,15 @@ The `native` route of the library **does not** export `Html` or `Loader`. The de
168
167
  <li><a href="#shapes">Lathe</a></li>
169
168
  <li><a href="#roundedbox">RoundedBox</a></li>
170
169
  <li><a href="#screenquad">Screenquad</a></li>
170
+ <li><a href="#line">Line</a></li>
171
+ <li><a href="#quadraticbezierline">QuadraticBezierLine</a></li>
172
+ <li><a href="#cubicbezierline">CubicBezierLine</a></li>
173
+ <li><a href="#catmullromline">CatmullRomLine</a></li>
171
174
  </ul>
172
175
  <li><a href="#staging">Staging</a></li>
173
176
  <ul>
174
177
  <li><a href="#center">Center</a></li>
178
+ <li><a href="#BBAnchor">BBAnchor</a></li>
175
179
  <li><a href="#bounds">Bounds</a></li>
176
180
  <li><a href="#camerashake">CameraShake</a></li>
177
181
  <li><a href="#float">Float</a></li>
@@ -268,39 +272,7 @@ All controls react to the default camera. If you have a `<PerspectiveCamera make
268
272
 
269
273
  PointerLockControls additionally supports a `selector` prop, which enables the binding of `click` event handlers for control activation to other elements than `document` (e.g. a 'Click here to play' button). All elements matching the `selector` prop will activate the controls. It will also center raycast events by default, so regular onPointerOver/etc events on meshes will continue to work.
270
274
 
271
- # TransformControls
272
-
273
- [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/controls-transformcontrols--transform-controls-story)
274
-
275
- <p>
276
- <a href="https://codesandbox.io/s/btsbj"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/btsbj/screenshot.png" alt="Tranform controls"/></a>
277
- </p>
278
-
279
- An abstraction around [THREE.TransformControls](https://threejs.org/docs/#examples/en/controls/TransformControls).
280
-
281
- You can wrap objects which then receive a transform gizmo.
282
-
283
- ```jsx
284
- <TransformControls mode="translate">
285
- <mesh />
286
- </TransformControls>
287
- ```
288
-
289
- You could also reference the object which might make it easier to exchange the target. Now the object does not have to be part of the same sub-graph. References can be plain objects or React.MutableRefObjects.
290
-
291
- ```jsx
292
- <TransformControls object={mesh} mode="translate">
293
- <mesh ref={mesh} />
294
- ```
295
-
296
- If you are using other controls (Orbit, Trackball, etc), you will notice how they interfere, dragging one will affect the other. Default-controls will temporarily be disabled automatically when the user is pulling on the transform gizmo.
297
-
298
- ```jsx
299
- <TransformControls mode="translate" />
300
- <OrbitControls makeDefault />
301
- ```
302
-
303
- # ScrollControls
275
+ #### ScrollControls
304
276
 
305
277
  ![](https://img.shields.io/badge/-Dom only-red)
306
278
 
@@ -366,7 +338,7 @@ function Foo(props) {
366
338
  return <mesh ref={ref} {...props} />
367
339
  ```
368
340
 
369
- # PresentationControls
341
+ #### PresentationControls
370
342
 
371
343
  ![](https://img.shields.io/badge/-Dom only-red)
372
344
 
@@ -393,129 +365,179 @@ Semi-OrbitControls with spring-physics, polar zoom and snap-back, for presentati
393
365
  </PresentationControls>
394
366
  ```
395
367
 
396
- # Shapes
397
-
398
- [Buffer-geometry](https://threejs.org/docs/#api/en/core/BufferGeometry) short-cuts for Plane, Box, Sphere, Circle, Cone, Cylinder, Tube, Torus, TorusKnot, Ring, Tetrahedron, Polyhedron, Icosahedron, Octahedron, Dodecahedron, Extrude, Lathe.
368
+ # Gizmos
399
369
 
400
- ```jsx
401
- <Plane args={[2, 2]} />
402
- <Sphere>
403
- <meshBasicMaterial color="hotpink" />
404
- </Sphere>
405
- ```
370
+ #### GizmoHelper
406
371
 
407
- #### RoundedBox
372
+ [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.pmnd.rs/?path=/story/gizmos-gizmohelper--gizmo-helper-story)
408
373
 
409
- A box buffer geometry with rounded corners, done with extrusion.
374
+ Used by widgets that visualize and control camera position.
410
375
 
411
- ```jsx
412
- <RoundedBox args={[1, 1, 1]} radius={0.05} smoothness={4} {...meshProps}>
413
- <meshPhongMaterial color="#f3f3f3" wireframe />
414
- </RoundedBox>
415
- ```
376
+ Two example gizmos are included: GizmoViewport and GizmoViewcube, and `useGizmoContext` makes it easy to create your own.
416
377
 
417
- #### ScreenQuad
378
+ Make sure to set the `makeDefault` prop on your controls, in that case you do not have to define the onTarget and onUpdate props.
418
379
 
419
380
  ```jsx
420
- <ScreenQuad>
421
- <myMaterial />
422
- </ScreenQuad>
381
+ <GizmoHelper
382
+ alignment="bottom-right" // widget alignment within scene
383
+ margin={[80, 80]} // widget margins (X, Y)
384
+ onUpdate={/* called during camera animation */}
385
+ onTarget={/* return current camera target (e.g. from orbit controls) to center animation */}
386
+ renderPriority={/* use renderPriority to prevent the helper from disappearing if there is another useFrame(..., 1)*/}
387
+ >
388
+ <GizmoViewport axisColors={['red', 'green', 'blue']} labelColor="black" />
389
+ {/* alternative: <GizmoViewcube /> */}
390
+ </GizmoHelper>
423
391
  ```
424
392
 
425
- A triangle that fills the screen, ideal for full-screen fragment shader work (raymarching, postprocessing).
426
- 👉 [Why a triangle?](https://www.cginternals.com/en/blog/2018-01-10-screen-aligned-quads-and-triangles.html)
427
- 👉 [Use as a post processing mesh](https://medium.com/@luruke/simple-postprocessing-in-three-js-91936ecadfb7)
428
-
429
- # Abstractions
393
+ #### PivotControls
430
394
 
431
- #### Image
395
+ ![](https://img.shields.io/badge/-Dom only-red)
432
396
 
433
397
  <p>
434
- <a href="https://codesandbox.io/s/l4klb"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/l4klb/screenshot.png" alt="Horizontal tiles"/></a>
435
- <a href="https://codesandbox.io/s/gsm1y"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/gsm1y/screenshot.png" alt="useIntersect"/></a>
436
- <a href="https://codesandbox.io/s/x8gvs"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/x8gvs/screenshot.png" alt="Infinite scroll"/></a>
437
- <a href="https://codesandbox.io/s/yjhzv"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/yjhzv/screenshot.png" alt="Vertical scroll"/></a>
398
+ <a href="https://codesandbox.io/s/om2ff8"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/om2ff8/screenshot.png" alt="demo"/></a>
438
399
  </p>
439
400
 
440
- A shader-based image component with auto-cover (similar to css/background: cover).
401
+ Controls for rotating and translating objects. These controls will stick to the object the transform and by offsetting or anchoring it forms a pivot. This control has HTLM annotations for some transforms and supports `[tab]` for rounded values while dragging.
441
402
 
442
- ```jsx
443
- function Foo() {
444
- const ref = useRef()
445
- useFrame(() => {
446
- ref.current.material.zoom = ... // 1 and higher
447
- ref.current.material.grayscale = ... // between 0 and 1
448
- ref.current.material.color.set(...) // mix-in color
449
- })
450
- return <Image ref={ref} url="/file.jpg" />
403
+ ```tsx
404
+ type PivotControlsProps = {
405
+ /** Scale of the gizmo, 1 */
406
+ scale?: number
407
+ /** Width of the gizmo lines, this is a THREE.Line2 prop, 2.5 */
408
+ lineWidth?: number
409
+ /** If fixed is true is remains constant in size, scale is now in pixels, false */
410
+ fixed?: boolean
411
+ /** Pivot does not act as a group, it won't shift contents but can offset in position */
412
+ offset?: [number, number, number]
413
+ /** Starting rotation */
414
+ rotation?: [number, number, number]
415
+ /** Starting matrix */
416
+ matrix?: THREE.Matrix4
417
+ /** Anchor point, like BBAnchor, each axis can be between -1/0/+1 */
418
+ anchor?: [number, number, number]
419
+ /** If autoTransform is true, automatically apply the local transform on drag, true */
420
+ autoTransform?: boolean
421
+ /** Allows you to switch individual axes off */
422
+ activeAxes?: [boolean, boolean, boolean]
423
+ /** RGB colors */
424
+ axisColors?: [string | number, string | number, string | number]
425
+ /** Color of the hovered item */
426
+ hoveredColor?: string | number
427
+ /** CSS Classname applied to the HTML annotations */
428
+ annotationsClass?: string
429
+ /** Drag start event */
430
+ onDragStart?: () => void
431
+ /** Drag event */
432
+ onDrag?: (l: THREE.Matrix4, deltaL: THREE.Matrix4, w: THREE.Matrix4, deltaW: THREE.Matrix4) => void
433
+ /** Drag end event */
434
+ onDragEnd?: () => void
435
+ /** Set this to false if you want the gizmo to be visible through faces */
436
+ depthTest?: boolean
437
+ opacity?: number
438
+ visible?: boolean
439
+ userData?: { [key: string]: any }
440
+ children?: React.ReactNode
451
441
  }
452
442
  ```
453
443
 
454
- To make the material transparent:
444
+ ```jsx
445
+ <PivotControls>
446
+ <mesh />
447
+ </PivotControls>
448
+ ```
449
+
450
+ You can use Pivot as a controlled component, switch `autoTransform` off in that case and now you are responsible for applying the matrix transform yourself. You can also leave `autoTransform` on and apply the matrix to foreign objects, in that case Pivot will be able to control objects that are not parented within.
455
451
 
456
452
  ```jsx
457
- <Image url="/file.jpg" transparent opacity={0.5} />
453
+ const matrix = new THREE.Matrix4()
454
+ return (
455
+ <PivotControls
456
+ ref={ref}
457
+ matrix={matrix}
458
+ autoTransform={false}
459
+ onDrag={({ matrix: matrix_ }) => matrix.copy(matrix_)}
458
460
  ```
459
461
 
460
- #### Text
462
+ #### TransformControls
461
463
 
462
- [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/abstractions-text--text-st) ![](https://img.shields.io/badge/-suspense-brightgreen)
464
+ [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/controls-transformcontrols--transform-controls-story)
463
465
 
464
466
  <p>
465
- <a href="https://codesandbox.io/s/yup2o"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/yup2o/screenshot.png" alt="Demo"/></a>
467
+ <a href="https://codesandbox.io/s/btsbj"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/btsbj/screenshot.png" alt="Tranform controls"/></a>
466
468
  </p>
467
469
 
468
- Hi-quality text rendering w/ signed distance fields (SDF) and antialiasing, using [troika-3d-text](https://github.com/protectwise/troika/tree/master/packages/troika-3d-text). All of troikas props are valid! Text is suspense-based!
470
+ An abstraction around [THREE.TransformControls](https://threejs.org/docs/#examples/en/controls/TransformControls).
471
+
472
+ You can wrap objects which then receive a transform gizmo.
469
473
 
470
474
  ```jsx
471
- <Text color="black" anchorX="center" anchorY="middle">
472
- hello world!
473
- </Text>
475
+ <TransformControls mode="translate">
476
+ <mesh />
477
+ </TransformControls>
474
478
  ```
475
479
 
476
- Text will suspend while loading the font data, but in order to completely avoid FOUC you can pass the characters it needs to render.
480
+ You could also reference the object which might make it easier to exchange the target. Now the object does not have to be part of the same sub-graph. References can be plain objects or React.MutableRefObjects.
477
481
 
478
482
  ```jsx
479
- <Text font={fontUrl} characters="abcdefghijklmnopqrstuvwxyz0123456789!">
480
- hello world!
481
- </Text>
483
+ <TransformControls object={mesh} mode="translate">
484
+ <mesh ref={mesh} />
482
485
  ```
483
486
 
484
- #### Text3D
487
+ If you are using other controls (Orbit, Trackball, etc), you will notice how they interfere, dragging one will affect the other. Default-controls will temporarily be disabled automatically when the user is pulling on the transform gizmo.
485
488
 
486
- [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/abstractions-text3d--text-3-d-st) ![](https://img.shields.io/badge/-suspense-brightgreen)
489
+ ```jsx
490
+ <TransformControls mode="translate" />
491
+ <OrbitControls makeDefault />
492
+ ```
487
493
 
488
- <p>
489
- <a href="https://codesandbox.io/s/x6obrb"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/x6obrb/screenshot.png" alt="Demo"/></a>
490
- </p>
494
+ #### useHelper
491
495
 
492
- Render 3D text using ThreeJS's `TextGeometry`.
496
+ [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/misc-usehelper--default-story)
493
497
 
494
- Text3D will suspend while loading the font data. Text3D requires fonts in JSON format generated through (typeface.json)[http://gero3.github.io/facetype.js], either as a path to a JSON file or a JSON object. If you face display issues try checking "Reverse font direction" in the typeface tool.
498
+ A hook for a quick way to add helpers to existing nodes in the scene. It handles removal of the helper on unmount and auto-updates it by default.
495
499
 
496
500
  ```jsx
497
- <Text3D font={fontUrl} {...textOptions}>
498
- Hello world!
499
- <meshNormalMaterial />
500
- </Text3D>
501
+ const mesh = useRef()
502
+ useHelper(mesh, BoxHelper, 'cyan')
503
+ useHelper(condition && mesh, BoxHelper, 'red') // you can passe false instead of the object ref to hide the helper
504
+
505
+ <mesh ref={mesh} ... />
501
506
  ```
502
507
 
503
- You can use any material. `textOptions` are options you'd pass to the `TextGeometry` constructor. Find more information about available options [here](https://threejs.org/docs/index.html?q=textg#examples/en/geometries/TextGeometry).
508
+ # Shapes
504
509
 
505
- You can align the text using the `<Center>` component.
510
+ [Buffer-geometry](https://threejs.org/docs/#api/en/core/BufferGeometry) short-cuts for Plane, Box, Sphere, Circle, Cone, Cylinder, Tube, Torus, TorusKnot, Ring, Tetrahedron, Polyhedron, Icosahedron, Octahedron, Dodecahedron, Extrude, Lathe.
506
511
 
507
512
  ```jsx
508
- <Center top left>
509
- <Text3D>hello</Text3D>
510
- </Center>
513
+ <Plane args={[2, 2]} />
514
+ <Sphere>
515
+ <meshBasicMaterial color="hotpink" />
516
+ </Sphere>
511
517
  ```
512
518
 
513
- It adds two properties that do not exist in the priginal `TextGeometry`, `lineHeight` and `letterSpacing`. The former a factor that is `1` by default, the latter is in threejs units and `0` by default.
519
+ #### RoundedBox
520
+
521
+ A box buffer geometry with rounded corners, done with extrusion.
514
522
 
515
523
  ```jsx
516
- <Text3D lineHeight={0.5} letterSpacing={-0.025}>{`hello\nworld`}</Text3D>
524
+ <RoundedBox args={[1, 1, 1]} radius={0.05} smoothness={4} {...meshProps}>
525
+ <meshPhongMaterial color="#f3f3f3" wireframe />
526
+ </RoundedBox>
517
527
  ```
518
528
 
529
+ #### ScreenQuad
530
+
531
+ ```jsx
532
+ <ScreenQuad>
533
+ <myMaterial />
534
+ </ScreenQuad>
535
+ ```
536
+
537
+ A triangle that fills the screen, ideal for full-screen fragment shader work (raymarching, postprocessing).
538
+ 👉 [Why a triangle?](https://www.cginternals.com/en/blog/2018-01-10-screen-aligned-quads-and-triangles.html)
539
+ 👉 [Use as a post processing mesh](https://medium.com/@luruke/simple-postprocessing-in-three-js-91936ecadfb7)
540
+
519
541
  #### Line
520
542
 
521
543
  [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/abstractions-line--basic-line)
@@ -615,63 +637,94 @@ Renders a THREE.Line2 using THREE.CatmullRomCurve3 for interpolation.
615
637
  />
616
638
  ```
617
639
 
618
- #### PositionalAudio
640
+ # Abstractions
641
+
642
+ #### Image
619
643
 
620
644
  <p>
621
- <a href="https://codesandbox.io/s/gkfhr"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/gkfhr/screenshot.png" alt="Demo"/></a>
645
+ <a href="https://codesandbox.io/s/l4klb"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/l4klb/screenshot.png" alt="Horizontal tiles"/></a>
646
+ <a href="https://codesandbox.io/s/gsm1y"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/gsm1y/screenshot.png" alt="useIntersect"/></a>
647
+ <a href="https://codesandbox.io/s/x8gvs"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/x8gvs/screenshot.png" alt="Infinite scroll"/></a>
648
+ <a href="https://codesandbox.io/s/yjhzv"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/yjhzv/screenshot.png" alt="Vertical scroll"/></a>
622
649
  </p>
623
650
 
624
- [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/abstractions-positionalaudio--positional-audio-scene-st) ![](https://img.shields.io/badge/-suspense-brightgreen)
651
+ A shader-based image component with auto-cover (similar to css/background: cover).
625
652
 
626
- A wrapper around [THREE.PositionalAudio](https://threejs.org/docs/#api/en/audio/PositionalAudio). Add this to groups or meshes to tie them to a sound that plays when the camera comes near.
653
+ ```jsx
654
+ function Foo() {
655
+ const ref = useRef()
656
+ useFrame(() => {
657
+ ref.current.material.zoom = ... // 1 and higher
658
+ ref.current.material.grayscale = ... // between 0 and 1
659
+ ref.current.material.color.set(...) // mix-in color
660
+ })
661
+ return <Image ref={ref} url="/file.jpg" />
662
+ }
663
+ ```
664
+
665
+ To make the material transparent:
627
666
 
628
667
  ```jsx
629
- <PositionalAudio
630
- url="/sound.mp3"
631
- distance={1}
632
- loop
633
- {...props} // All THREE.PositionalAudio props are valid
634
- />
668
+ <Image url="/file.jpg" transparent opacity={0.5} />
635
669
  ```
636
670
 
637
- #### Billboard
671
+ #### Text
638
672
 
639
- [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.pmnd.rs/?path=/story/abstractions-billboard--billboard-st)
673
+ [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/abstractions-text--text-st) ![](https://img.shields.io/badge/-suspense-brightgreen)
640
674
 
641
- Adds a `<group />` that always faces the camera.
675
+ <p>
676
+ <a href="https://codesandbox.io/s/yup2o"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/yup2o/screenshot.png" alt="Demo"/></a>
677
+ </p>
678
+
679
+ Hi-quality text rendering w/ signed distance fields (SDF) and antialiasing, using [troika-3d-text](https://github.com/protectwise/troika/tree/master/packages/troika-3d-text). All of troikas props are valid! Text is suspense-based!
642
680
 
643
681
  ```jsx
644
- <Billboard
645
- follow={true}
646
- lockX={false}
647
- lockY={false}
648
- lockZ={false} // Lock the rotation on the z axis (default=false)
649
- >
650
- <Text fontSize={1}>I'm a billboard</Text>
651
- </Billboard>
682
+ <Text color="black" anchorX="center" anchorY="middle">
683
+ hello world!
684
+ </Text>
652
685
  ```
653
686
 
654
- #### GizmoHelper
687
+ Text will suspend while loading the font data, but in order to completely avoid FOUC you can pass the characters it needs to render.
655
688
 
656
- [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.pmnd.rs/?path=/story/gizmos-gizmohelper--gizmo-helper-story)
689
+ ```jsx
690
+ <Text font={fontUrl} characters="abcdefghijklmnopqrstuvwxyz0123456789!">
691
+ hello world!
692
+ </Text>
693
+ ```
657
694
 
658
- Used by widgets that visualize and control camera position.
695
+ #### Text3D
659
696
 
660
- Two example gizmos are included: GizmoViewport and GizmoViewcube, and `useGizmoContext` makes it easy to create your own.
697
+ [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/abstractions-text3d--text-3-d-st) ![](https://img.shields.io/badge/-suspense-brightgreen)
661
698
 
662
- Make sure to set the `makeDefault` prop on your controls, in that case you do not have to define the onTarget and onUpdate props.
699
+ <p>
700
+ <a href="https://codesandbox.io/s/x6obrb"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/x6obrb/screenshot.png" alt="Demo"/></a>
701
+ </p>
702
+
703
+ Render 3D text using ThreeJS's `TextGeometry`.
704
+
705
+ Text3D will suspend while loading the font data. Text3D requires fonts in JSON format generated through (typeface.json)[http://gero3.github.io/facetype.js], either as a path to a JSON file or a JSON object. If you face display issues try checking "Reverse font direction" in the typeface tool.
663
706
 
664
707
  ```jsx
665
- <GizmoHelper
666
- alignment="bottom-right" // widget alignment within scene
667
- margin={[80, 80]} // widget margins (X, Y)
668
- onUpdate={/* called during camera animation */}
669
- onTarget={/* return current camera target (e.g. from orbit controls) to center animation */}
670
- renderPriority={/* use renderPriority to prevent the helper from disappearing if there is another useFrame(..., 1)*/}
671
- >
672
- <GizmoViewport axisColors={['red', 'green', 'blue']} labelColor="black" />
673
- {/* alternative: <GizmoViewcube /> */}
674
- </GizmoHelper>
708
+ <Text3D font={fontUrl} {...textOptions}>
709
+ Hello world!
710
+ <meshNormalMaterial />
711
+ </Text3D>
712
+ ```
713
+
714
+ You can use any material. `textOptions` are options you'd pass to the `TextGeometry` constructor. Find more information about available options [here](https://threejs.org/docs/index.html?q=textg#examples/en/geometries/TextGeometry).
715
+
716
+ You can align the text using the `<Center>` component.
717
+
718
+ ```jsx
719
+ <Center top left>
720
+ <Text3D>hello</Text3D>
721
+ </Center>
722
+ ```
723
+
724
+ It adds two properties that do not exist in the priginal `TextGeometry`, `lineHeight` and `letterSpacing`. The former a factor that is `1` by default, the latter is in threejs units and `0` by default.
725
+
726
+ ```jsx
727
+ <Text3D lineHeight={0.5} letterSpacing={-0.025}>{`hello\nworld`}</Text3D>
675
728
  ```
676
729
 
677
730
  #### Effects
@@ -690,6 +743,42 @@ extend({ SSAOPass })
690
743
  </Effects>
691
744
  ```
692
745
 
746
+ #### PositionalAudio
747
+
748
+ <p>
749
+ <a href="https://codesandbox.io/s/gkfhr"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/gkfhr/screenshot.png" alt="Demo"/></a>
750
+ </p>
751
+
752
+ [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/abstractions-positionalaudio--positional-audio-scene-st) ![](https://img.shields.io/badge/-suspense-brightgreen)
753
+
754
+ A wrapper around [THREE.PositionalAudio](https://threejs.org/docs/#api/en/audio/PositionalAudio). Add this to groups or meshes to tie them to a sound that plays when the camera comes near.
755
+
756
+ ```jsx
757
+ <PositionalAudio
758
+ url="/sound.mp3"
759
+ distance={1}
760
+ loop
761
+ {...props} // All THREE.PositionalAudio props are valid
762
+ />
763
+ ```
764
+
765
+ #### Billboard
766
+
767
+ [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.pmnd.rs/?path=/story/abstractions-billboard--billboard-st)
768
+
769
+ Adds a `<group />` that always faces the camera.
770
+
771
+ ```jsx
772
+ <Billboard
773
+ follow={true}
774
+ lockX={false}
775
+ lockY={false}
776
+ lockZ={false} // Lock the rotation on the z axis (default=false)
777
+ >
778
+ <Text fontSize={1}>I'm a billboard</Text>
779
+ </Billboard>
780
+ ```
781
+
693
782
  #### GradientTexture
694
783
 
695
784
  <p>
@@ -1363,20 +1452,6 @@ A hook for the rare case when you are using non-default cameras for heads-up-dis
1363
1452
  <mesh raycast={useCamera(customCamera)} />
1364
1453
  ```
1365
1454
 
1366
- #### useHelper
1367
-
1368
- [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/misc-usehelper--default-story)
1369
-
1370
- A hook for a quick way to add helpers to existing nodes in the scene. It handles removal of the helper on unmount and auto-updates it by default.
1371
-
1372
- ```jsx
1373
- const mesh = useRef()
1374
- useHelper(mesh, BoxHelper, 'cyan')
1375
- useHelper(condition && mesh, BoxHelper, 'red') // you can passe false instead of the object ref to hide the helper
1376
-
1377
- <mesh ref={mesh} ... />
1378
- ```
1379
-
1380
1455
  #### useDetectGPU
1381
1456
 
1382
1457
  [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.pmnd.rs/?path=/story/misc-usedetectgpu)
@@ -1506,37 +1581,6 @@ const buffer = useSurfaceSampler(
1506
1581
  )
1507
1582
  ```
1508
1583
 
1509
- #### BBAnchor
1510
-
1511
- [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/misc-bbanchor--bb-anchor-with-html)
1512
-
1513
- A component using AABB (Axis-aligned bounding boxes) to offset children position by specified multipliers (`anchor` property) on each axis. You can use this component to change children positioning in regard of the parent's bounding box, eg. pinning [Html](#html) component to one of the parent's corners. Multipliers determine the offset value based on the `AABB`'s size:
1514
-
1515
- ```
1516
- childrenAnchor = boundingBoxPosition + (boundingBoxSize * anchor / 2)
1517
- ```
1518
-
1519
- ```jsx
1520
- <BBAnchor
1521
- anchor // THREE.Vector3 or [number, number, number]
1522
- {...groupProps} // All THREE.Group props are valid
1523
- >
1524
- {children}
1525
- </BBAnchor>
1526
- ```
1527
-
1528
- For instance, one could want the Html component to be pinned to `positive x`, `positive y`, and `positive z` corner of a [Box](#shapes) object:
1529
-
1530
- ```jsx
1531
- <Box>
1532
- <BBAnchor anchor={[1, 1, 1]}>
1533
- <Html center>
1534
- <span>Hello world!</span>
1535
- </Html>
1536
- </BBAnchor>
1537
- </Box>
1538
- ```
1539
-
1540
1584
  # Loading
1541
1585
 
1542
1586
  #### Loader
@@ -2214,6 +2258,37 @@ function ScaledModel() {
2214
2258
  </Center>
2215
2259
  ```
2216
2260
 
2261
+ #### BBAnchor
2262
+
2263
+ [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/misc-bbanchor--bb-anchor-with-html)
2264
+
2265
+ A component using AABB (Axis-aligned bounding boxes) to offset children position by specified multipliers (`anchor` property) on each axis. You can use this component to change children positioning in regard of the parent's bounding box, eg. pinning [Html](#html) component to one of the parent's corners. Multipliers determine the offset value based on the `AABB`'s size:
2266
+
2267
+ ```
2268
+ childrenAnchor = boundingBoxPosition + (boundingBoxSize * anchor / 2)
2269
+ ```
2270
+
2271
+ ```jsx
2272
+ <BBAnchor
2273
+ anchor // THREE.Vector3 or [number, number, number]
2274
+ {...groupProps} // All THREE.Group props are valid
2275
+ >
2276
+ {children}
2277
+ </BBAnchor>
2278
+ ```
2279
+
2280
+ For instance, one could want the Html component to be pinned to `positive x`, `positive y`, and `positive z` corner of a [Box](#shapes) object:
2281
+
2282
+ ```jsx
2283
+ <Box>
2284
+ <BBAnchor anchor={[1, 1, 1]}>
2285
+ <Html center>
2286
+ <span>Hello world!</span>
2287
+ </Html>
2288
+ </BBAnchor>
2289
+ </Box>
2290
+ ```
2291
+
2217
2292
  #### Bounds
2218
2293
 
2219
2294
  <p>
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("react"),r=require("three"),n=require("./Line.cjs.js");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function u(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)}require("three-stdlib");var s=o(e),c=u(t);const l=c.forwardRef((function({points:e,closed:t=!1,curveType:o="centripetal",tension:u=.5,segments:l=20,vertexColors:i,...f},a){const p=c.useMemo((()=>{const n=e.map((e=>e instanceof r.Vector3?e:new r.Vector3(...e)));return new r.CatmullRomCurve3(n,t,o,u)}),[e,t,o,u]),d=c.useMemo((()=>p.getPoints(l)),[p,l]),m=c.useMemo((()=>{if(!i||i.length<2)return;if(i.length===l+1)return i;const e=i.map((e=>e instanceof r.Color?e:new r.Color(...e)));t&&e.push(e[0].clone());const n=[e[0]],o=l/(e.length-1);for(let t=1;t<l;t++){const r=t%o/o,u=Math.floor(t/o);n.push(e[u].clone().lerp(e[u+1],r))}return n.push(e[e.length-1]),n}),[i,l]);return c.createElement(n.Line,s.default({ref:a,points:d,vertexColors:m},f))}));exports.CatmullRomLine=l;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("react"),r=require("three"),n=require("./Line.cjs.js");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function u(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)}require("@react-three/fiber"),require("three-stdlib");var s=o(e),c=u(t);const l=c.forwardRef((function({points:e,closed:t=!1,curveType:o="centripetal",tension:u=.5,segments:l=20,vertexColors:i,...f},a){const p=c.useMemo((()=>{const n=e.map((e=>e instanceof r.Vector3?e:new r.Vector3(...e)));return new r.CatmullRomCurve3(n,t,o,u)}),[e,t,o,u]),d=c.useMemo((()=>p.getPoints(l)),[p,l]),h=c.useMemo((()=>{if(!i||i.length<2)return;if(i.length===l+1)return i;const e=i.map((e=>e instanceof r.Color?e:new r.Color(...e)));t&&e.push(e[0].clone());const n=[e[0]],o=l/(e.length-1);for(let t=1;t<l;t++){const r=t%o/o,u=Math.floor(t/o);n.push(e[u].clone().lerp(e[u+1],r))}return n.push(e[e.length-1]),n}),[i,l]);return c.createElement(n.Line,s.default({ref:a,points:d,vertexColors:h},f))}));exports.CatmullRomLine=l;