2
2
// inspired collision detection system from implementation in https://github.com/JBreidfjord/particle-sim
3
3
// lol looks like we didn't use particle collision in the end
4
4
5
- import React , { useRef , useEffect } from 'react'
5
+ import React , { useRef , useEffect } from 'react' ;
6
+ import init , { check_on_image_map , calculate_position } from "../wasm/main"
6
7
7
- const GRAVITY : number = 9.81 ;
8
- const GRAVITY_MULTIPLIER : number = 0.01 ;
9
8
const RADIUS : number = 2 ;
10
9
const SPACING : number = 35 ;
11
- const MAX_VELOCITY : number = 100 ;
12
10
const EXTERNAL_PADDING_PERCENT : number = 0.05 ;
13
11
let X_PADDING : number = 0 ;
14
12
let Y_PADDING : number = 0 ;
@@ -19,11 +17,11 @@ interface ICanvasProps {
19
17
}
20
18
21
19
export const Canvas = ( props : ICanvasProps ) => {
22
-
23
20
const { style, ...rest } = props
24
- const canvasRef = useCanvas ( )
21
+
22
+ let canvasRef : React . MutableRefObject < HTMLCanvasElement | null > | null = useCanvas ( ) ;
25
23
return < >
26
- < canvas style = { style } ref = { canvasRef } { ...rest } > </ canvas >
24
+ { canvasRef && < canvas style = { style } ref = { canvasRef } { ...rest } > </ canvas > }
27
25
</ >
28
26
}
29
27
@@ -37,6 +35,12 @@ var mouse = {
37
35
38
36
const useCanvas = ( ) => {
39
37
const canvasRef : React . MutableRefObject < HTMLCanvasElement | null > = useRef ( null ) ;
38
+ const [ wasmInstantiated , setWasmInstantiated ] = React . useState ( false ) ;
39
+ useEffect ( ( ) => {
40
+ init ( ) . then ( ( ) => {
41
+ setWasmInstantiated ( true ) ;
42
+ } ) ;
43
+ } , [ ] ) ;
40
44
41
45
addEventListener ( "resize" , ( ) => {
42
46
const canvas = canvasRef . current ;
@@ -49,6 +53,9 @@ const useCanvas = () => {
49
53
} ) ;
50
54
51
55
useEffect ( ( ) => {
56
+ if ( ! wasmInstantiated ) {
57
+ return ;
58
+ }
52
59
53
60
const canvas = canvasRef . current
54
61
const context = canvas ! . getContext ( '2d' ) !
@@ -86,9 +93,9 @@ const useCanvas = () => {
86
93
return ( ) => {
87
94
window . cancelAnimationFrame ( animationFrameId )
88
95
}
89
- } , [ ] )
96
+ } , [ wasmInstantiated ] )
90
97
91
- return canvasRef
98
+ return wasmInstantiated ? canvasRef : null ;
92
99
}
93
100
94
101
export const resizeCanvasToDisplaySize = ( canvas : HTMLCanvasElement ) => {
@@ -213,7 +220,7 @@ class Square {
213
220
y_gravity : number = 0 ;
214
221
x_velocity : number = 0 ;
215
222
y_velocity : number = 0 ;
216
- isResetting : boolean = false ;
223
+ is_resetting : boolean = false ;
217
224
218
225
constructor ( ctx : CanvasRenderingContext2D , initial_x : number , initial_y : number ) {
219
226
this . ctx = ctx ;
@@ -223,7 +230,7 @@ class Square {
223
230
this . initial_y = initial_y ;
224
231
this . reset_from_x = this . x ;
225
232
this . reset_from_y = this . y ;
226
- this . color = checkOnImageMap ( initial_x , initial_y )
233
+ this . color = check_on_image_map ( initial_x , initial_y , innerHeight , innerWidth )
227
234
? `#${ ( Math . random ( ) * 70 + 100 ) . toString ( 16 ) . slice ( 0 , 2 ) } ${ ( Math . random ( ) * 100 + 100 ) . toString ( 16 ) . slice ( 0 , 2 ) } ${ ( Math . random ( ) * 155 + 100 ) . toString ( 16 ) . slice ( 0 , 2 ) } `
228
235
: "#FFFFFF22"
229
236
console . log ( this . initial_x , this . initial_y ) ;
@@ -234,131 +241,54 @@ class Square {
234
241
this . ctx . beginPath ( ) ;
235
242
this . ctx . rect ( this . x - RADIUS , this . y - RADIUS , RADIUS * 2 , RADIUS * 2 ) ;
236
243
this . ctx . fillStyle = this . color ;
237
- this . ctx . shadowColor = this . color ;
238
- this . ctx . shadowBlur = 5 ;
239
244
this . ctx . fill ( ) ;
240
245
this . ctx . lineWidth = 3 ;
241
246
}
242
247
243
- calculateGravity = ( ) => {
244
- if ( this . isResetting ) {
245
- this . x_gravity = GRAVITY * ( this . initial_x - this . x ) / window . innerWidth * GRAVITY_MULTIPLIER * 100 ;
246
- this . y_gravity = GRAVITY * ( this . initial_y - this . y ) / window . innerHeight * GRAVITY_MULTIPLIER * 100 ;
247
- // this.x_gravity = 0;
248
- // this.y_gravity = 0;
249
- } else {
250
- const x_relative_to_center = ( this . x - window . innerWidth / 2 ) / window . innerWidth * 3
251
- const y_relative_to_center = ( this . y - window . innerHeight / 2 ) / window . innerHeight * 3
252
- this . x_gravity = GRAVITY * ( window . innerWidth > window . innerHeight ? window . innerWidth / window . innerHeight : 1 ) * GRAVITY_MULTIPLIER * - ( x_relative_to_center - mouse . x ) * ( mouse . down ? 1 : 0 ) ;
253
- this . y_gravity = GRAVITY * ( window . innerHeight > window . innerWidth ? window . innerHeight / window . innerWidth : 1 ) * GRAVITY_MULTIPLIER * - ( y_relative_to_center - mouse . y ) * ( mouse . down ? 1 : 0 ) ;
254
- }
255
- }
256
-
257
- calculateVelocity = ( ) => {
258
-
259
- if ( this . isResetting ) {
260
- // set velocity to start slow, then speed up, then slow down, then stop from reset_from to initial
261
- const x_distance = this . reset_from_x - this . initial_x ;
262
- const y_distance = this . reset_from_y - this . initial_y ;
263
- const x_distance_from_initial = this . x - this . initial_x ;
264
- const y_distance_from_initial = this . y - this . initial_y ;
265
-
266
- const x_distance_from_initial_percent = Math . abs ( x_distance_from_initial / x_distance ) ;
267
- const y_distance_from_initial_percent = Math . abs ( y_distance_from_initial / y_distance ) ;
268
-
269
- this . x_velocity = x_distance_from_initial_percent * - x_distance_from_initial ;
270
- this . y_velocity = y_distance_from_initial_percent * - y_distance_from_initial ;
271
- } else {
272
- this . x_velocity += this . x_gravity ;
273
- this . y_velocity += this . y_gravity ;
274
- this . x_velocity *= 1 - this . friction ;
275
- this . y_velocity *= 1 - this . friction ;
276
- }
277
-
278
- if ( Math . abs ( this . x_velocity ) > MAX_VELOCITY ) {
279
- this . x_velocity = MAX_VELOCITY * ( this . x_velocity > 0 ? 1 : - 1 ) ;
280
- }
281
- if ( Math . abs ( this . y_velocity ) > MAX_VELOCITY ) {
282
- this . y_velocity = MAX_VELOCITY * ( this . y_velocity > 0 ? 1 : - 1 ) ;
283
- }
284
- }
285
-
286
- calculatePosition = ( ) => {
287
- this . x += this . x_velocity ; // what about this
288
- this . y += this . y_velocity ; // okay this kinda looks
289
-
290
- if ( this . x > window . innerWidth - EXTERNAL_PADDING_PERCENT * window . innerWidth / 2 ) {
291
- this . x = window . innerWidth - EXTERNAL_PADDING_PERCENT * window . innerWidth / 2 ;
292
- this . x_velocity *= - this . restitution ;
293
- }
294
- if ( this . x < EXTERNAL_PADDING_PERCENT * window . innerWidth / 2 ) {
295
- this . x = EXTERNAL_PADDING_PERCENT * window . innerWidth / 2 ;
296
- this . x_velocity *= - this . restitution ;
297
- }
298
- if ( this . y > window . innerHeight - EXTERNAL_PADDING_PERCENT * window . innerHeight / 2 ) {
299
- this . y = window . innerHeight - EXTERNAL_PADDING_PERCENT * window . innerHeight / 2 ;
300
- this . y_velocity *= - this . restitution * 0.9 ;
301
- }
302
- if ( this . y < EXTERNAL_PADDING_PERCENT * window . innerHeight / 2 ) {
303
- this . y = EXTERNAL_PADDING_PERCENT * window . innerHeight / 2 ;
304
- this . y_velocity *= - this . restitution * 0.9 ;
305
- }
306
-
307
- if ( this . isResetting ) {
308
- if ( Math . abs ( this . x - this . initial_x ) < 1 && Math . abs ( this . y - this . initial_y ) < 1 && Math . abs ( this . x_velocity ) < 0.1 && Math . abs ( this . y_velocity ) < 0.1 ) {
309
- this . isResetting = false ;
310
- this . x = this . initial_x ;
311
- this . y = this . initial_y ;
312
- this . x_gravity = 0 ;
313
- this . y_gravity = 0 ;
314
- this . x_velocity = 0 ;
315
- this . y_velocity = 0 ;
316
- }
317
- }
318
- }
319
-
320
248
prepareAnimation = ( ) => {
321
- this . calculateGravity ( ) ;
322
- this . calculateVelocity ( ) ;
323
- this . calculatePosition ( ) ;
249
+ try {
250
+ let s = calculate_position (
251
+ mouse . x ,
252
+ mouse . y ,
253
+ mouse . down ,
254
+ this . x ,
255
+ this . y ,
256
+ this . x_velocity ,
257
+ this . y_velocity ,
258
+ this . x_gravity ,
259
+ this . y_gravity ,
260
+ this . is_resetting ,
261
+ this . reset_from_x ,
262
+ this . reset_from_y ,
263
+ this . friction ,
264
+ this . restitution ,
265
+ this . initial_x ,
266
+ this . initial_y ,
267
+ window . innerWidth ,
268
+ window . innerHeight
269
+ ) as Square ;
270
+ this . x = s . x ;
271
+ this . y = s . y ;
272
+ this . x_velocity = s . x_velocity ;
273
+ this . y_velocity = s . y_velocity ;
274
+ this . x_gravity = s . x_gravity ;
275
+ this . y_gravity = s . y_gravity ;
276
+ this . is_resetting = s . is_resetting ;
277
+ } catch ( e ) {
278
+ console . log ( e ) ;
279
+ }
324
280
}
325
281
326
282
reset = ( ) => {
327
- this . isResetting = true ;
283
+ this . is_resetting = true ;
328
284
this . reset_from_x = this . x ;
329
285
this . reset_from_y = this . y ;
330
286
this . x_gravity = 0 ;
331
287
this . y_gravity = 0 ;
332
288
}
333
289
334
290
cancelReset = ( ) => {
335
- this . isResetting = false ;
291
+ this . is_resetting = false ;
336
292
}
337
293
338
- }
339
-
340
- const checkOnImageMap = ( x : number , y : number ) => {
341
- const smallestDimension = window . innerWidth > window . innerHeight ? window . innerHeight : window . innerWidth ;
342
- const x_offset = ( window . innerWidth - smallestDimension ) / 2 ;
343
- const y_offset = ( window . innerHeight - smallestDimension ) / 2 ;
344
- const x_center = window . innerWidth / 2 ;
345
- const y_center = window . innerHeight / 2 ;
346
-
347
- const unit = smallestDimension / 100 ;
348
-
349
- // borders
350
- if ( x < x_offset || x > window . innerWidth - x_offset || y < y_offset || y > window . innerHeight - y_offset ) {
351
- return false ;
352
- }
353
-
354
- // center triangle
355
- if ( ( Math . abs ( x - x_center ) / - ( y - y_center / 1.5 ) > 1 || y > y_center / 1.5 ) && ( Math . abs ( x - x_center ) / - ( y - y_center - y_center * 0.25 ) < 1 && y < y_center * 1.25 ) ) {
356
- return true ;
357
- }
358
-
359
- // bars
360
- if ( Math . abs ( x - x_center ) >= unit * 30 ) {
361
- return true ;
362
- }
363
- return false ;
364
294
}
0 commit comments