@react-three/drei 9.74.11 → 9.74.13

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.
Files changed (189) hide show
  1. package/core/CatmullRomLine.js +2 -0
  2. package/core/Cloud.js +3 -0
  3. package/core/CubeCamera.js +1 -0
  4. package/core/CubicBezierLine.js +2 -0
  5. package/core/Environment.js +1 -0
  6. package/core/Example.js +6 -0
  7. package/core/FaceControls.cjs.js +1 -1
  8. package/core/FaceControls.js +2 -0
  9. package/core/FaceLandmarker.cjs.js +1 -1
  10. package/core/FaceLandmarker.js +3 -2
  11. package/core/Facemesh.js +2 -0
  12. package/core/GizmoHelper.js +3 -0
  13. package/core/GizmoViewcube.js +4 -0
  14. package/core/GizmoViewport.js +4 -0
  15. package/core/Gltf.js +4 -0
  16. package/core/MeshDiscardMaterial.js +2 -0
  17. package/core/MeshDistortMaterial.js +2 -1
  18. package/core/MeshReflectorMaterial.js +1 -0
  19. package/core/MeshRefractionMaterial.js +2 -0
  20. package/core/MeshTransmissionMaterial.js +1 -0
  21. package/core/OrthographicCamera.js +1 -0
  22. package/core/PerspectiveCamera.js +1 -0
  23. package/core/QuadraticBezierLine.js +2 -0
  24. package/core/Reflector.js +1 -0
  25. package/core/SpotLight.js +2 -1
  26. package/core/Stage.js +7 -0
  27. package/core/Text3D.js +1 -0
  28. package/core/Wireframe.js +1 -0
  29. package/core/index.cjs.js +1 -1
  30. package/core/index.js +0 -1
  31. package/core/useKTX2.js +1 -0
  32. package/core/useMatcapTexture.js +2 -0
  33. package/core/useNormalTexture.js +1 -0
  34. package/index.cjs.js +1 -1
  35. package/materials/DiscardMaterial.js +1 -0
  36. package/materials/MeshRefractionMaterial.js +1 -1
  37. package/native/index.cjs.js +1 -1
  38. package/native/index.js +0 -1
  39. package/package.json +9 -9
  40. package/src/core/AccumulativeShadows.js +311 -0
  41. package/src/core/AdaptiveDpr.js +28 -0
  42. package/src/core/AdaptiveEvents.js +20 -0
  43. package/src/core/ArcballControls.js +67 -0
  44. package/src/core/AsciiRenderer.js +60 -0
  45. package/src/core/BBAnchor.js +37 -0
  46. package/src/core/Backdrop.js +36 -0
  47. package/src/core/BakeShadows.js +16 -0
  48. package/src/core/Billboard.js +41 -0
  49. package/src/core/Bounds.js +245 -0
  50. package/src/core/CameraControls.js +92 -0
  51. package/src/core/CameraShake.js +61 -0
  52. package/src/core/CatmullRomLine.js +44 -0
  53. package/src/core/Caustics.js +375 -0
  54. package/src/core/Center.js +66 -0
  55. package/src/core/Clone.js +102 -0
  56. package/src/core/Cloud.js +59 -0
  57. package/src/core/ComputedAttribute.js +34 -0
  58. package/src/core/ContactShadows.js +114 -0
  59. package/src/core/CubeCamera.js +43 -0
  60. package/src/core/CubicBezierLine.js +28 -0
  61. package/src/core/CurveModifier.js +34 -0
  62. package/src/core/Decal.js +92 -0
  63. package/src/core/Detailed.js +34 -0
  64. package/src/core/DeviceOrientationControls.js +51 -0
  65. package/src/core/Edges.js +36 -0
  66. package/src/core/Effects.js +93 -0
  67. package/src/core/Environment.js +132 -0
  68. package/src/core/Example.js +42 -0
  69. package/src/core/FaceControls.js +315 -0
  70. package/src/core/FaceLandmarker.js +43 -0
  71. package/src/core/Facemesh.js +4545 -0
  72. package/src/core/FirstPersonControls.js +38 -0
  73. package/src/core/Float.js +36 -0
  74. package/src/core/FlyControls.js +55 -0
  75. package/src/core/GizmoHelper.js +111 -0
  76. package/src/core/GizmoViewcube.js +152 -0
  77. package/src/core/GizmoViewport.js +152 -0
  78. package/src/core/Gltf.js +20 -0
  79. package/src/core/GradientTexture.js +33 -0
  80. package/src/core/Grid.js +112 -0
  81. package/src/core/Hud.js +58 -0
  82. package/src/core/Image.js +119 -0
  83. package/src/core/Instances.js +215 -0
  84. package/src/core/Lightformer.js +51 -0
  85. package/src/core/Line.js +68 -0
  86. package/src/core/MapControls.js +64 -0
  87. package/src/core/MarchingCubes.js +76 -0
  88. package/src/core/Mask.js +42 -0
  89. package/src/core/MeshDiscardMaterial.js +15 -0
  90. package/src/core/MeshDistortMaterial.js +79 -0
  91. package/src/core/MeshPortalMaterial.js +381 -0
  92. package/src/core/MeshReflectorMaterial.js +182 -0
  93. package/src/core/MeshRefractionMaterial.js +79 -0
  94. package/src/core/MeshTransmissionMaterial.js +395 -0
  95. package/src/core/MeshWobbleMaterial.js +65 -0
  96. package/src/core/OrbitControls.js +82 -0
  97. package/src/core/OrthographicCamera.js +77 -0
  98. package/src/core/PerformanceMonitor.js +121 -0
  99. package/src/core/PerspectiveCamera.js +73 -0
  100. package/src/core/PointMaterial.js +36 -0
  101. package/src/core/PointerLockControls.js +90 -0
  102. package/src/core/Points.js +227 -0
  103. package/src/core/PositionalAudio.js +51 -0
  104. package/src/core/Preload.js +45 -0
  105. package/src/core/QuadraticBezierLine.js +44 -0
  106. package/src/core/Reflector.js +182 -0
  107. package/src/core/RenderTexture.js +96 -0
  108. package/src/core/Resize.js +39 -0
  109. package/src/core/RoundedBox.js +52 -0
  110. package/src/core/Sampler.js +85 -0
  111. package/src/core/ScreenQuad.js +24 -0
  112. package/src/core/ScreenSpace.js +25 -0
  113. package/src/core/Segments.js +102 -0
  114. package/src/core/Shadow.js +42 -0
  115. package/src/core/Sky.js +39 -0
  116. package/src/core/Sparkles.js +139 -0
  117. package/src/core/SpotLight.js +231 -0
  118. package/src/core/SpriteAnimator.js +342 -0
  119. package/src/core/Stage.js +135 -0
  120. package/src/core/Stars.js +108 -0
  121. package/src/core/Stats.js +30 -0
  122. package/src/core/Svg.js +59 -0
  123. package/src/core/Text.js +58 -0
  124. package/src/core/Text3D.js +76 -0
  125. package/src/core/TrackballControls.js +72 -0
  126. package/src/core/Trail.js +161 -0
  127. package/src/core/TransformControls.js +106 -0
  128. package/src/core/Wireframe.js +185 -0
  129. package/src/core/meshBounds.js +38 -0
  130. package/src/core/shaderMaterial.js +39 -0
  131. package/src/core/shapes.js +68 -0
  132. package/src/core/softShadows.js +161 -0
  133. package/src/core/useAnimations.js +56 -0
  134. package/src/core/useAspect.js +10 -0
  135. package/src/core/useBVH.js +90 -0
  136. package/src/core/useBoxProjectedEnv.js +98 -0
  137. package/src/core/useCamera.js +27 -0
  138. package/src/core/useContextBridge.js +21 -0
  139. package/src/core/useCubeCamera.js +49 -0
  140. package/src/core/useCubeTexture.js +18 -0
  141. package/src/core/useDepthBuffer.js +38 -0
  142. package/src/core/useDetectGPU.js +6 -0
  143. package/src/core/useEnvironment.js +48 -0
  144. package/src/core/useFBO.js +53 -0
  145. package/src/core/useFBX.js +12 -0
  146. package/src/core/useFont.js +20 -0
  147. package/src/core/useGLTF.js +37 -0
  148. package/src/core/useHelper.js +31 -0
  149. package/src/core/useIntersect.js +39 -0
  150. package/src/core/useKTX2.js +38 -0
  151. package/src/core/useMatcapTexture.js +45 -0
  152. package/src/core/useNormalTexture.js +30 -0
  153. package/src/core/useProgress.js +50 -0
  154. package/src/core/useTexture.js +35 -0
  155. package/src/core/useTrailTexture.js +164 -0
  156. package/src/core/useVideoTexture.js +41 -0
  157. package/src/helpers/environment-assets.js +14 -0
  158. package/src/helpers/useEffectfulState.js +18 -0
  159. package/src/materials/BlurPass.js +75 -0
  160. package/src/materials/ConvolutionMaterial.js +99 -0
  161. package/src/materials/DiscardMaterial.js +5 -0
  162. package/src/materials/MeshReflectorMaterial.js +290 -0
  163. package/src/materials/MeshRefractionMaterial.js +171 -0
  164. package/src/materials/SpotLightMaterial.js +111 -0
  165. package/src/materials/WireframeMaterial.js +235 -0
  166. package/src/web/CycleRaycast.js +97 -0
  167. package/src/web/Html.js +417 -0
  168. package/src/web/KeyboardControls.js +101 -0
  169. package/src/web/Loader.js +98 -0
  170. package/src/web/PresentationControls.js +86 -0
  171. package/src/web/ScrollControls.js +246 -0
  172. package/src/web/Select.js +175 -0
  173. package/src/web/View.js +206 -0
  174. package/src/web/pivotControls/AxisArrow.js +202 -0
  175. package/src/web/pivotControls/AxisRotator.js +235 -0
  176. package/src/web/pivotControls/PlaneSlider.js +211 -0
  177. package/src/web/pivotControls/context.js +5 -0
  178. package/src/web/pivotControls/index.js +223 -0
  179. package/src/web/useCursor.js +12 -0
  180. package/web/Loader.js +2 -0
  181. package/web/index.cjs.js +1 -1
  182. package/web/index.js +0 -1
  183. package/web/pivotControls/AxisArrow.js +3 -0
  184. package/web/pivotControls/AxisRotator.js +3 -0
  185. package/web/pivotControls/PlaneSlider.js +3 -0
  186. package/web/pivotControls/index.js +5 -0
  187. /package/{helpers → src/helpers}/glsl/DefaultSpotlightShadowShadows.glsl.js +0 -0
  188. /package/{helpers → src/helpers}/glsl/distort.vert.glsl.js +0 -0
  189. /package/{index.js → src/index.js} +0 -0
@@ -0,0 +1,246 @@
1
+ import _extends from '@babel/runtime/helpers/esm/extends';
2
+ import * as React from 'react';
3
+ import * as ReactDOM from 'react-dom/client';
4
+ import { useThree, useFrame, context as context$1 } from '@react-three/fiber';
5
+ import mergeRefs from 'react-merge-refs';
6
+ import { easing } from 'maath';
7
+
8
+ const context = /*#__PURE__*/React.createContext(null);
9
+ function useScroll() {
10
+ return React.useContext(context);
11
+ }
12
+ function ScrollControls({
13
+ eps = 0.00001,
14
+ enabled = true,
15
+ infinite,
16
+ horizontal,
17
+ pages = 1,
18
+ distance = 1,
19
+ damping = 0.25,
20
+ maxSpeed = Infinity,
21
+ style = {},
22
+ children
23
+ }) {
24
+ const {
25
+ get,
26
+ setEvents,
27
+ gl,
28
+ size,
29
+ invalidate,
30
+ events
31
+ } = useThree();
32
+ const [el] = React.useState(() => document.createElement('div'));
33
+ const [fill] = React.useState(() => document.createElement('div'));
34
+ const [fixed] = React.useState(() => document.createElement('div'));
35
+ const target = gl.domElement.parentNode;
36
+ const scroll = React.useRef(0);
37
+ const state = React.useMemo(() => {
38
+ const state = {
39
+ el,
40
+ eps,
41
+ fill,
42
+ fixed,
43
+ horizontal,
44
+ damping,
45
+ offset: 0,
46
+ delta: 0,
47
+ scroll,
48
+ pages,
49
+
50
+ // 0-1 for a range between from -> from + distance
51
+ range(from, distance, margin = 0) {
52
+ const start = from - margin;
53
+ const end = start + distance + margin * 2;
54
+ return this.offset < start ? 0 : this.offset > end ? 1 : (this.offset - start) / (end - start);
55
+ },
56
+
57
+ // 0-1-0 for a range between from -> from + distance
58
+ curve(from, distance, margin = 0) {
59
+ return Math.sin(this.range(from, distance, margin) * Math.PI);
60
+ },
61
+
62
+ // true/false for a range between from -> from + distance
63
+ visible(from, distance, margin = 0) {
64
+ const start = from - margin;
65
+ const end = start + distance + margin * 2;
66
+ return this.offset >= start && this.offset <= end;
67
+ }
68
+
69
+ };
70
+ return state;
71
+ }, [eps, damping, horizontal, pages]);
72
+ React.useEffect(() => {
73
+ el.style.position = 'absolute';
74
+ el.style.width = '100%';
75
+ el.style.height = '100%';
76
+ el.style[horizontal ? 'overflowX' : 'overflowY'] = 'auto';
77
+ el.style[horizontal ? 'overflowY' : 'overflowX'] = 'hidden';
78
+ el.style.top = '0px';
79
+ el.style.left = '0px';
80
+
81
+ for (const key in style) {
82
+ el.style[key] = style[key];
83
+ }
84
+
85
+ fixed.style.position = 'sticky';
86
+ fixed.style.top = '0px';
87
+ fixed.style.left = '0px';
88
+ fixed.style.width = '100%';
89
+ fixed.style.height = '100%';
90
+ fixed.style.overflow = 'hidden';
91
+ el.appendChild(fixed);
92
+ fill.style.height = horizontal ? '100%' : `${pages * distance * 100}%`;
93
+ fill.style.width = horizontal ? `${pages * distance * 100}%` : '100%';
94
+ fill.style.pointerEvents = 'none';
95
+ el.appendChild(fill);
96
+ target.appendChild(el); // Init scroll one pixel in to allow upward/leftward scroll
97
+
98
+ el[horizontal ? 'scrollLeft' : 'scrollTop'] = 1;
99
+ const oldTarget = events.connected || gl.domElement;
100
+ requestAnimationFrame(() => events.connect == null ? void 0 : events.connect(el));
101
+ const oldCompute = get().events.compute;
102
+ setEvents({
103
+ compute(event, state) {
104
+ // we are using boundingClientRect because we could not rely on target.offsetTop as canvas could be positioned anywhere in dom
105
+ const {
106
+ left,
107
+ top
108
+ } = target.getBoundingClientRect();
109
+ const offsetX = event.clientX - left;
110
+ const offsetY = event.clientY - top;
111
+ state.pointer.set(offsetX / state.size.width * 2 - 1, -(offsetY / state.size.height) * 2 + 1);
112
+ state.raycaster.setFromCamera(state.pointer, state.camera);
113
+ }
114
+
115
+ });
116
+ return () => {
117
+ target.removeChild(el);
118
+ setEvents({
119
+ compute: oldCompute
120
+ });
121
+ events.connect == null ? void 0 : events.connect(oldTarget);
122
+ };
123
+ }, [pages, distance, horizontal, el, fill, fixed, target]);
124
+ React.useEffect(() => {
125
+ if (events.connected === el) {
126
+ const containerLength = size[horizontal ? 'width' : 'height'];
127
+ const scrollLength = el[horizontal ? 'scrollWidth' : 'scrollHeight'];
128
+ const scrollThreshold = scrollLength - containerLength;
129
+ let current = 0;
130
+ let disableScroll = true;
131
+ let firstRun = true;
132
+
133
+ const onScroll = () => {
134
+ // Prevent first scroll because it is indirectly caused by the one pixel offset
135
+ if (!enabled || firstRun) return;
136
+ invalidate();
137
+ current = el[horizontal ? 'scrollLeft' : 'scrollTop'];
138
+ scroll.current = current / scrollThreshold;
139
+
140
+ if (infinite) {
141
+ if (!disableScroll) {
142
+ if (current >= scrollThreshold) {
143
+ const damp = 1 - state.offset;
144
+ el[horizontal ? 'scrollLeft' : 'scrollTop'] = 1;
145
+ scroll.current = state.offset = -damp;
146
+ disableScroll = true;
147
+ } else if (current <= 0) {
148
+ const damp = 1 + state.offset;
149
+ el[horizontal ? 'scrollLeft' : 'scrollTop'] = scrollLength;
150
+ scroll.current = state.offset = damp;
151
+ disableScroll = true;
152
+ }
153
+ }
154
+
155
+ if (disableScroll) setTimeout(() => disableScroll = false, 40);
156
+ }
157
+ };
158
+
159
+ el.addEventListener('scroll', onScroll, {
160
+ passive: true
161
+ });
162
+ requestAnimationFrame(() => firstRun = false);
163
+
164
+ const onWheel = e => el.scrollLeft += e.deltaY / 2;
165
+
166
+ if (horizontal) el.addEventListener('wheel', onWheel, {
167
+ passive: true
168
+ });
169
+ return () => {
170
+ el.removeEventListener('scroll', onScroll);
171
+ if (horizontal) el.removeEventListener('wheel', onWheel);
172
+ };
173
+ }
174
+ }, [el, events, size, infinite, state, invalidate, horizontal, enabled]);
175
+ let last = 0;
176
+ useFrame((_, delta) => {
177
+ last = state.offset;
178
+ easing.damp(state, 'offset', scroll.current, damping, delta, maxSpeed, undefined, eps);
179
+ easing.damp(state, 'delta', Math.abs(last - state.offset), damping, delta, maxSpeed, undefined, eps);
180
+ if (state.delta > eps) invalidate();
181
+ });
182
+ return /*#__PURE__*/React.createElement(context.Provider, {
183
+ value: state
184
+ }, children);
185
+ }
186
+ const ScrollCanvas = /*#__PURE__*/React.forwardRef(({
187
+ children
188
+ }, ref) => {
189
+ const group = React.useRef(null);
190
+ const state = useScroll();
191
+ const {
192
+ width,
193
+ height
194
+ } = useThree(state => state.viewport);
195
+ useFrame(() => {
196
+ group.current.position.x = state.horizontal ? -width * (state.pages - 1) * state.offset : 0;
197
+ group.current.position.y = state.horizontal ? 0 : height * (state.pages - 1) * state.offset;
198
+ });
199
+ return /*#__PURE__*/React.createElement("group", {
200
+ ref: mergeRefs([ref, group])
201
+ }, children);
202
+ });
203
+ const ScrollHtml = /*#__PURE__*/React.forwardRef(({
204
+ children,
205
+ style,
206
+ ...props
207
+ }, ref) => {
208
+ const state = useScroll();
209
+ const group = React.useRef(null);
210
+ const {
211
+ width,
212
+ height
213
+ } = useThree(state => state.size);
214
+ const fiberState = React.useContext(context$1);
215
+ const root = React.useMemo(() => ReactDOM.createRoot(state.fixed), [state.fixed]);
216
+ useFrame(() => {
217
+ if (state.delta > state.eps) {
218
+ group.current.style.transform = `translate3d(${state.horizontal ? -width * (state.pages - 1) * state.offset : 0}px,${state.horizontal ? 0 : height * (state.pages - 1) * -state.offset}px,0)`;
219
+ }
220
+ });
221
+ root.render( /*#__PURE__*/React.createElement("div", _extends({
222
+ ref: mergeRefs([ref, group]),
223
+ style: { ...style,
224
+ position: 'absolute',
225
+ top: 0,
226
+ left: 0,
227
+ willChange: 'transform'
228
+ }
229
+ }, props), /*#__PURE__*/React.createElement(context.Provider, {
230
+ value: state
231
+ }, /*#__PURE__*/React.createElement(context$1.Provider, {
232
+ value: fiberState
233
+ }, children))));
234
+ return null;
235
+ });
236
+ const Scroll = /*#__PURE__*/React.forwardRef(({
237
+ html,
238
+ ...props
239
+ }, ref) => {
240
+ const El = html ? ScrollHtml : ScrollCanvas;
241
+ return /*#__PURE__*/React.createElement(El, _extends({
242
+ ref: ref
243
+ }, props));
244
+ });
245
+
246
+ export { Scroll, ScrollControls, useScroll };
@@ -0,0 +1,175 @@
1
+ import _extends from '@babel/runtime/helpers/esm/extends';
2
+ import * as React from 'react';
3
+ import * as THREE from 'three';
4
+ import { SelectionBox } from 'three-stdlib';
5
+ import { useThree } from '@react-three/fiber';
6
+ import shallow from 'zustand/shallow';
7
+
8
+ const context = /*#__PURE__*/React.createContext([]);
9
+ function Select({
10
+ box,
11
+ multiple,
12
+ children,
13
+ onChange,
14
+ onChangePointerUp,
15
+ border = '1px solid #55aaff',
16
+ backgroundColor = 'rgba(75, 160, 255, 0.1)',
17
+ filter: customFilter = item => item,
18
+ ...props
19
+ }) {
20
+ const [downed, down] = React.useState(false);
21
+ const {
22
+ setEvents,
23
+ camera,
24
+ raycaster,
25
+ gl,
26
+ controls,
27
+ size,
28
+ get
29
+ } = useThree();
30
+ const [hovered, hover] = React.useState(false);
31
+ const [active, dispatch] = React.useReducer((state, {
32
+ object,
33
+ shift
34
+ }) => {
35
+ if (object === undefined) return [];else if (Array.isArray(object)) return object;else if (!shift) return state[0] === object ? [] : [object];else if (state.includes(object)) return state.filter(o => o !== object);else return [object, ...state];
36
+ }, []);
37
+ React.useEffect(() => {
38
+ if (downed) onChange == null ? void 0 : onChange(active);else onChangePointerUp == null ? void 0 : onChangePointerUp(active);
39
+ }, [active, downed]);
40
+ const onClick = React.useCallback(e => {
41
+ e.stopPropagation();
42
+ dispatch({
43
+ object: customFilter([e.object])[0],
44
+ shift: multiple && e.shiftKey
45
+ });
46
+ }, []);
47
+ const onPointerMissed = React.useCallback(e => !hovered && dispatch({}), [hovered]);
48
+ const ref = React.useRef(null);
49
+ React.useEffect(() => {
50
+ if (!box || !multiple) return;
51
+ const selBox = new SelectionBox(camera, ref.current);
52
+ const element = document.createElement('div');
53
+ element.style.pointerEvents = 'none';
54
+ element.style.border = border;
55
+ element.style.backgroundColor = backgroundColor;
56
+ element.style.position = 'fixed';
57
+ const startPoint = new THREE.Vector2();
58
+ const pointTopLeft = new THREE.Vector2();
59
+ const pointBottomRight = new THREE.Vector2();
60
+ const oldRaycasterEnabled = get().events.enabled;
61
+ const oldControlsEnabled = controls == null ? void 0 : controls.enabled;
62
+ let isDown = false;
63
+
64
+ function prepareRay(event, vec) {
65
+ const {
66
+ offsetX,
67
+ offsetY
68
+ } = event;
69
+ const {
70
+ width,
71
+ height
72
+ } = size;
73
+ vec.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
74
+ }
75
+
76
+ function onSelectStart(event) {
77
+ var _gl$domElement$parent;
78
+
79
+ if (controls) controls.enabled = false;
80
+ setEvents({
81
+ enabled: false
82
+ });
83
+ down(isDown = true);
84
+ (_gl$domElement$parent = gl.domElement.parentElement) == null ? void 0 : _gl$domElement$parent.appendChild(element);
85
+ element.style.left = `${event.clientX}px`;
86
+ element.style.top = `${event.clientY}px`;
87
+ element.style.width = '0px';
88
+ element.style.height = '0px';
89
+ startPoint.x = event.clientX;
90
+ startPoint.y = event.clientY;
91
+ }
92
+
93
+ function onSelectMove(event) {
94
+ pointBottomRight.x = Math.max(startPoint.x, event.clientX);
95
+ pointBottomRight.y = Math.max(startPoint.y, event.clientY);
96
+ pointTopLeft.x = Math.min(startPoint.x, event.clientX);
97
+ pointTopLeft.y = Math.min(startPoint.y, event.clientY);
98
+ element.style.left = `${pointTopLeft.x}px`;
99
+ element.style.top = `${pointTopLeft.y}px`;
100
+ element.style.width = `${pointBottomRight.x - pointTopLeft.x}px`;
101
+ element.style.height = `${pointBottomRight.y - pointTopLeft.y}px`;
102
+ }
103
+
104
+ function onSelectOver() {
105
+ if (isDown) {
106
+ var _element$parentElemen;
107
+
108
+ if (controls) controls.enabled = oldControlsEnabled;
109
+ setEvents({
110
+ enabled: oldRaycasterEnabled
111
+ });
112
+ down(isDown = false);
113
+ (_element$parentElemen = element.parentElement) == null ? void 0 : _element$parentElemen.removeChild(element);
114
+ }
115
+ }
116
+
117
+ function pointerDown(event) {
118
+ if (event.shiftKey) {
119
+ onSelectStart(event);
120
+ prepareRay(event, selBox.startPoint);
121
+ }
122
+ }
123
+
124
+ let previous = [];
125
+
126
+ function pointerMove(event) {
127
+ if (isDown) {
128
+ onSelectMove(event);
129
+ prepareRay(event, selBox.endPoint);
130
+ const allSelected = selBox.select().sort(o => o.uuid).filter(o => o.isMesh);
131
+
132
+ if (!shallow(allSelected, previous)) {
133
+ previous = allSelected;
134
+ dispatch({
135
+ object: customFilter(allSelected)
136
+ });
137
+ }
138
+ }
139
+ }
140
+
141
+ function pointerUp(event) {
142
+ if (isDown) onSelectOver();
143
+ }
144
+
145
+ document.addEventListener('pointerdown', pointerDown, {
146
+ passive: true
147
+ });
148
+ document.addEventListener('pointermove', pointerMove, {
149
+ passive: true,
150
+ capture: true
151
+ });
152
+ document.addEventListener('pointerup', pointerUp, {
153
+ passive: true
154
+ });
155
+ return () => {
156
+ document.removeEventListener('pointerdown', pointerDown);
157
+ document.removeEventListener('pointermove', pointerMove);
158
+ document.removeEventListener('pointerup', pointerUp);
159
+ };
160
+ }, [size.width, size.height, raycaster, camera, controls, gl]);
161
+ return /*#__PURE__*/React.createElement("group", _extends({
162
+ ref: ref,
163
+ onClick: onClick,
164
+ onPointerOver: () => hover(true),
165
+ onPointerOut: () => hover(false),
166
+ onPointerMissed: onPointerMissed
167
+ }, props), /*#__PURE__*/React.createElement(context.Provider, {
168
+ value: active
169
+ }, children));
170
+ }
171
+ function useSelect() {
172
+ return React.useContext(context);
173
+ }
174
+
175
+ export { Select, useSelect };
@@ -0,0 +1,206 @@
1
+ import * as React from 'react';
2
+ import * as THREE from 'three';
3
+ import { useThree, createPortal, useFrame } from '@react-three/fiber';
4
+
5
+ const isOrthographicCamera = def => def && def.isOrthographicCamera;
6
+
7
+ const col = new THREE.Color();
8
+ /**
9
+ * In `@react-three/fiber` after `v8.0.0` but prior to `v8.1.0`, `state.size` contained only dimension
10
+ * information. After `v8.1.0`, position information (`top`, `left`) was added
11
+ *
12
+ * @todo remove this when drei supports v9 and up
13
+ */
14
+
15
+ function isNonLegacyCanvasSize(size) {
16
+ return 'top' in size;
17
+ }
18
+
19
+ function computeContainerPosition(canvasSize, trackRect) {
20
+ const {
21
+ right,
22
+ top,
23
+ left: trackLeft,
24
+ bottom: trackBottom,
25
+ width,
26
+ height
27
+ } = trackRect;
28
+ const isOffscreen = trackRect.bottom < 0 || top > canvasSize.height || right < 0 || trackRect.left > canvasSize.width;
29
+
30
+ if (isNonLegacyCanvasSize(canvasSize)) {
31
+ const canvasBottom = canvasSize.top + canvasSize.height;
32
+ const bottom = canvasBottom - trackBottom;
33
+ const left = trackLeft - canvasSize.left;
34
+ return {
35
+ position: {
36
+ width,
37
+ height,
38
+ left,
39
+ top,
40
+ bottom,
41
+ right
42
+ },
43
+ isOffscreen
44
+ };
45
+ } // Fall back on old behavior if r3f < 8.1.0
46
+
47
+
48
+ const bottom = canvasSize.height - trackBottom;
49
+ return {
50
+ position: {
51
+ width,
52
+ height,
53
+ top,
54
+ left: trackLeft,
55
+ bottom,
56
+ right
57
+ },
58
+ isOffscreen
59
+ };
60
+ }
61
+
62
+ function Container({
63
+ canvasSize,
64
+ scene,
65
+ index,
66
+ children,
67
+ frames,
68
+ rect,
69
+ track
70
+ }) {
71
+ const get = useThree(state => state.get);
72
+ const camera = useThree(state => state.camera);
73
+ const virtualScene = useThree(state => state.scene);
74
+ const setEvents = useThree(state => state.setEvents);
75
+ let frameCount = 0;
76
+ useFrame(state => {
77
+ if (frames === Infinity || frameCount <= frames) {
78
+ var _track$current;
79
+
80
+ rect.current = (_track$current = track.current) == null ? void 0 : _track$current.getBoundingClientRect();
81
+ frameCount++;
82
+ }
83
+
84
+ if (rect.current) {
85
+ const {
86
+ position: {
87
+ left,
88
+ bottom,
89
+ width,
90
+ height
91
+ },
92
+ isOffscreen
93
+ } = computeContainerPosition(canvasSize, rect.current);
94
+ const aspect = width / height;
95
+
96
+ if (isOrthographicCamera(camera)) {
97
+ if (camera.left !== width / -2 || camera.right !== width / 2 || camera.top !== height / 2 || camera.bottom !== height / -2) {
98
+ Object.assign(camera, {
99
+ left: width / -2,
100
+ right: width / 2,
101
+ top: height / 2,
102
+ bottom: height / -2
103
+ });
104
+ camera.updateProjectionMatrix();
105
+ }
106
+ } else if (camera.aspect !== aspect) {
107
+ camera.aspect = aspect;
108
+ camera.updateProjectionMatrix();
109
+ }
110
+
111
+ state.gl.setViewport(left, bottom, width, height);
112
+ state.gl.setScissor(left, bottom, width, height);
113
+ state.gl.setScissorTest(true);
114
+
115
+ if (isOffscreen) {
116
+ state.gl.getClearColor(col);
117
+ state.gl.setClearColor(col, state.gl.getClearAlpha());
118
+ state.gl.clear(true, true);
119
+ } else {
120
+ // When children are present render the portalled scene, otherwise the default scene
121
+ state.gl.render(children ? virtualScene : scene, camera);
122
+ } // Restore the default state
123
+
124
+
125
+ state.gl.setScissorTest(true);
126
+ }
127
+ }, index);
128
+ React.useEffect(() => {
129
+ // Connect the event layer to the tracking element
130
+ const old = get().events.connected;
131
+ setEvents({
132
+ connected: track.current
133
+ });
134
+ return () => setEvents({
135
+ connected: old
136
+ });
137
+ }, []);
138
+ React.useEffect(() => {
139
+ if (isNonLegacyCanvasSize(canvasSize)) {
140
+ return;
141
+ }
142
+
143
+ console.warn('Detected @react-three/fiber canvas size does not include position information. <View /> may not work as expected. ' + 'Upgrade to @react-three/fiber ^8.1.0 for support.\n See https://github.com/pmndrs/drei/issues/944');
144
+ }, []);
145
+ return /*#__PURE__*/React.createElement(React.Fragment, null, children);
146
+ }
147
+
148
+ const View = ({
149
+ track,
150
+ index = 1,
151
+ frames = Infinity,
152
+ children
153
+ }) => {
154
+ var _rect$current, _rect$current2;
155
+
156
+ const rect = React.useRef(null);
157
+ const {
158
+ size,
159
+ scene
160
+ } = useThree();
161
+ const [virtualScene] = React.useState(() => new THREE.Scene());
162
+ const compute = React.useCallback((event, state) => {
163
+ if (rect.current && track.current && event.target === track.current) {
164
+ const {
165
+ width,
166
+ height,
167
+ left,
168
+ top
169
+ } = rect.current;
170
+ const x = event.clientX - left;
171
+ const y = event.clientY - top;
172
+ state.pointer.set(x / width * 2 - 1, -(y / height) * 2 + 1);
173
+ state.raycaster.setFromCamera(state.pointer, state.camera);
174
+ }
175
+ }, [rect, track]);
176
+ const [ready, toggle] = React.useReducer(() => true, false);
177
+ React.useEffect(() => {
178
+ var _track$current2;
179
+
180
+ // We need the tracking elements bounds beforehand in order to inject it into the portal
181
+ rect.current = (_track$current2 = track.current) == null ? void 0 : _track$current2.getBoundingClientRect(); // And now we can proceed
182
+
183
+ toggle();
184
+ }, [track]);
185
+ return /*#__PURE__*/React.createElement(React.Fragment, null, ready && createPortal( /*#__PURE__*/React.createElement(Container, {
186
+ canvasSize: size,
187
+ frames: frames,
188
+ scene: scene,
189
+ track: track,
190
+ rect: rect,
191
+ index: index
192
+ }, children, /*#__PURE__*/React.createElement("group", {
193
+ onPointerOver: () => null
194
+ })), virtualScene, {
195
+ events: {
196
+ compute,
197
+ priority: index
198
+ },
199
+ size: {
200
+ width: (_rect$current = rect.current) == null ? void 0 : _rect$current.width,
201
+ height: (_rect$current2 = rect.current) == null ? void 0 : _rect$current2.height
202
+ }
203
+ }));
204
+ };
205
+
206
+ export { View };