@@ -2,54 +2,70 @@ import * as React from 'react';
2
2
import 'react-app-polyfill/ie11' ;
3
3
import * as ReactDOM from 'react-dom' ;
4
4
import { animated } from 'react-spring' ;
5
- import { a } from 'react-spring/three' ;
6
- import { Canvas } from 'react-three-fiber' ;
5
+ import { a } from '@ react-spring/three' ;
6
+ import { Canvas , useLoader } from 'react-three-fiber' ;
7
7
import * as THREE from 'three' ;
8
- import { Controls , useControl } from '../src' ;
8
+ import { Controls , ControlsProvider , useControl , BaseControl } from '../src' ;
9
9
import fontFile from './resources/unknown' ;
10
+ import { useEffect } from 'react' ;
10
11
11
12
function Text ( { children, size = 1 , letterSpacing = 0.01 , color = '#000000' } ) {
12
- const [ font ] = React . useState ( ( ) => new THREE . FontLoader ( ) . parse ( fontFile ) )
13
+ const [ font ] = React . useState ( ( ) => new THREE . FontLoader ( ) . parse ( fontFile ) ) ;
13
14
const [ shapes , [ x , y ] ] = React . useMemo ( ( ) => {
14
15
let x = 0 ,
15
- y = 0
16
- let letters = [ ...children ]
17
- let mat = new THREE . MeshBasicMaterial ( { color, opacity : 1 , transparent : true } )
16
+ y = 0 ;
17
+ let letters = [ ...children ] ;
18
+ let mat = new THREE . MeshBasicMaterial ( {
19
+ color,
20
+ opacity : 1 ,
21
+ transparent : true ,
22
+ } ) ;
18
23
return [
19
24
letters . map ( letter => {
20
- const geom = new THREE . ShapeGeometry ( font . generateShapes ( letter , size , 1 ) )
21
- geom . computeBoundingBox ( )
22
- const mesh = new THREE . Mesh ( geom , mat )
23
- mesh . position . x = x
24
- x += geom . boundingBox . max . x + letterSpacing
25
- y = Math . max ( y , geom . boundingBox . max . y )
26
- return mesh
25
+ const geom = new THREE . ShapeGeometry ( font . generateShapes ( letter , size ) ) ;
26
+ geom . computeBoundingBox ( ) ;
27
+ const mesh = new THREE . Mesh ( geom , mat ) ;
28
+ mesh . position . x = x ;
29
+ x += geom . boundingBox ? .max ?. x ! + letterSpacing ;
30
+ y = Math . max ( y , geom . boundingBox ? .max ?. y ! ) ;
31
+ return mesh ;
27
32
} ) ,
28
33
[ x , y ] ,
29
- ]
30
- } , [ children ] )
34
+ ] ;
35
+ } , [ children ] ) ;
31
36
32
37
return (
33
38
< group position = { [ - x / 2 , - y / 2 , 0 ] } >
34
39
{ shapes . map ( ( shape , index ) => (
35
40
< primitive key = { index } object = { shape } />
36
41
) ) }
37
42
</ group >
38
- )
43
+ ) ;
39
44
}
40
45
41
46
const Next = ( ) => {
42
- const rotationX = useControl ( 'Mega' , { group : 'Test' , type : 'number' , spring : true } ) ;
47
+ const rotationX = useControl ( 'Mega' , {
48
+ group : 'Test' ,
49
+ type : 'number' ,
50
+ spring : true ,
51
+ } ) ;
43
52
return (
44
53
< a . mesh position = { [ 1.5 , 0 , 0 ] } rotation-x = { rotationX } >
45
54
< boxGeometry attach = "geometry" args = { [ 1 , 1 , 1 ] } />
46
55
< meshStandardMaterial attach = "material" />
47
56
</ a . mesh >
48
- )
57
+ ) ;
49
58
} ;
50
59
51
60
const Box = ( ) => {
52
- const rotationX = useControl ( 'Rotate X' , { group : 'Basic' , type : 'number' , spring : true } ) ;
61
+ const ref = React . useRef < THREE . Mesh > ( ) ;
62
+
63
+ const rotationX = useControl ( 'Rotate X' , {
64
+ group : 'Basic' ,
65
+ type : 'number' ,
66
+ spring : true ,
67
+ } ) ;
68
+
53
69
const rotationY = useControl ( 'Rotate Y' , {
54
70
type : 'number' ,
55
71
group : 'Basic' ,
@@ -62,6 +78,11 @@ const Box = () => {
62
78
mass : 2 ,
63
79
} ,
64
80
} ) ;
81
+ const bool = useControl ( 'Boolean' , {
82
+ group : 'More' ,
83
+ type : 'boolean' ,
84
+ } ) ;
85
+
65
86
const color = useControl ( 'Material color' , {
66
87
type : 'color' ,
67
88
group : 'Basic' ,
@@ -72,14 +93,10 @@ const Box = () => {
72
93
value : { x : 0 , y : 0 } ,
73
94
distance : Math . PI ,
74
95
} ) ;
75
- const bool = useControl ( 'Allowed' , {
76
- group : 'More' ,
77
- type : 'boolean' ,
78
- } ) ;
79
96
const dropdown = useControl ( 'Pick one' , {
80
97
group : 'More' ,
81
98
type : 'select' ,
82
- items : [ 'foo' , 'bar' , 'baz' ]
99
+ items : [ 'foo' , 'bar' , 'baz' ] ,
83
100
} ) ;
84
101
const str = useControl ( 'Text' , {
85
102
group : 'More' ,
@@ -91,27 +108,22 @@ const Box = () => {
91
108
type : 'button' ,
92
109
onClick ( ) {
93
110
alert ( 'Hello world' ) ;
94
- }
111
+ } ,
95
112
} ) ;
96
113
97
- const MyControl = ( { control, value } ) => (
98
- < label > Test:
99
- < input
100
- type = "number"
101
- onChange = { e => control . set ( e . currentTarget . value ) }
102
- value = { value }
103
- />
104
- </ label >
105
- ) ;
106
-
107
- const size = useControl ( 'Test' , {
114
+ const texture = useControl ( 'Texture' , {
108
115
group : 'More' ,
109
- type : 'custom ' ,
110
- value : 1 ,
111
- component : MyControl
116
+ type : 'file ' ,
117
+ value : undefined ,
118
+ loader : new THREE . TextureLoader ( ) ,
112
119
} ) ;
113
120
114
- const ref = React . useRef < THREE . Mesh > ( ) ;
121
+ useEffect ( ( ) => {
122
+ if ( ref . current ) {
123
+ ( ref . current . material as THREE . Material ) . needsUpdate = true ;
124
+ }
125
+ } , [ texture ] ) ;
126
+
115
127
return (
116
128
< >
117
129
< a . mesh
@@ -120,38 +132,48 @@ const Box = () => {
120
132
rotation-x = { rotationX }
121
133
rotation-y = { rotationY }
122
134
>
123
- < boxGeometry attach = "geometry" args = { [ size , size , size ] } />
124
- < a . meshStandardMaterial attach = "material"
125
- color = { color }
126
- />
135
+ < boxGeometry attach = "geometry" args = { [ 1 , 1 , 1 ] } />
136
+ < a . meshPhongMaterial attach = "material" map = { texture } color = { color } />
127
137
</ a . mesh >
128
138
< Text > { str } </ Text >
129
139
{ dropdown === 'bar' && < Next /> }
130
140
</ >
131
- )
132
- }
141
+ ) ;
142
+ } ;
133
143
134
144
const Hello = ( ) => {
135
- useControl ( '1' , { type : 'number' } ) ;
136
- useControl ( '2' , { type : 'number' , max : 10 } ) ;
137
- useControl ( '3' , { type : 'number' , min : - 5 , max : 5 , value : - 2.5 } ) ;
138
- useControl ( '4' , { type : 'number' , min : 0 , max : 200 , value : 100 } ) ;
139
- useControl ( '5' , { type : 'number' , scrub : true } ) ;
140
- useControl ( '5' , { type : 'number' , scrub : true , distance : 1000 } ) ;
141
- return ( < animated . div style = { { width : 100 , height : 100 , background : 'red' } } /> )
145
+ const a1 = useControl ( '1' , { type : 'number' } ) ;
146
+ const a2 = useControl ( '2' , { type : 'number' , max : 10 } ) ;
147
+ const a3 = useControl ( '3' , { type : 'number' , min : - 5 , max : 5 , value : - 2.5 } ) ;
148
+ const a4 = useControl ( '4' , { type : 'number' , min : 0 , max : 200 , value : 100 } ) ;
149
+ const a5 = useControl ( '5' , { type : 'number' , scrub : true } ) ;
150
+ const a6 = useControl ( '6' , { type : 'number' , scrub : true , distance : 1000 } ) ;
151
+ return (
152
+ < animated . div style = { { width : 180 , background : 'orange' , padding : 20 } } >
153
+ < p > This is a div</ p >
154
+ < div > 1: { a1 } </ div >
155
+ < div > 2: { a2 } </ div >
156
+ < div > 3: { a3 } </ div >
157
+ < div > 4: { a4 } </ div >
158
+ < div > 5: { a5 } </ div >
159
+ < div > 6: { a6 } </ div >
160
+ </ animated . div >
161
+ ) ;
142
162
} ;
143
163
144
164
const App = ( ) => {
145
165
return (
146
- < div >
166
+ < ControlsProvider >
147
167
< Canvas style = { { width : 800 , height : 600 } } >
148
168
< ambientLight intensity = { 1 } />
149
169
< pointLight position = { [ 0 , 2 , 2 ] } />
150
- < Box />
170
+ < React . Suspense fallback = { null } >
171
+ < Box />
172
+ </ React . Suspense >
151
173
</ Canvas >
152
- < Controls />
153
174
< Hello />
154
- </ div >
175
+ < Controls />
176
+ </ ControlsProvider >
155
177
) ;
156
178
} ;
157
179
0 commit comments