22// inspired collision detection system from implementation in https://github.com/JBreidfjord/particle-sim
33// lol looks like we didn't use particle collision in the end
44
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"
67
7- const GRAVITY : number = 9.81 ;
8- const GRAVITY_MULTIPLIER : number = 0.01 ;
98const RADIUS : number = 2 ;
109const SPACING : number = 35 ;
11- const MAX_VELOCITY : number = 100 ;
1210const EXTERNAL_PADDING_PERCENT : number = 0.05 ;
1311let X_PADDING : number = 0 ;
1412let Y_PADDING : number = 0 ;
@@ -19,11 +17,11 @@ interface ICanvasProps {
1917}
2018
2119export const Canvas = ( props : ICanvasProps ) => {
22-
2320 const { style, ...rest } = props
24- const canvasRef = useCanvas ( )
21+
22+ let canvasRef : React . MutableRefObject < HTMLCanvasElement | null > | null = useCanvas ( ) ;
2523 return < >
26- < canvas style = { style } ref = { canvasRef } { ...rest } > </ canvas >
24+ { canvasRef && < canvas style = { style } ref = { canvasRef } { ...rest } > </ canvas > }
2725 </ >
2826}
2927
@@ -37,6 +35,12 @@ var mouse = {
3735
3836const useCanvas = ( ) => {
3937 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+ } , [ ] ) ;
4044
4145 addEventListener ( "resize" , ( ) => {
4246 const canvas = canvasRef . current ;
@@ -49,6 +53,9 @@ const useCanvas = () => {
4953 } ) ;
5054
5155 useEffect ( ( ) => {
56+ if ( ! wasmInstantiated ) {
57+ return ;
58+ }
5259
5360 const canvas = canvasRef . current
5461 const context = canvas ! . getContext ( '2d' ) !
@@ -86,9 +93,9 @@ const useCanvas = () => {
8693 return ( ) => {
8794 window . cancelAnimationFrame ( animationFrameId )
8895 }
89- } , [ ] )
96+ } , [ wasmInstantiated ] )
9097
91- return canvasRef
98+ return wasmInstantiated ? canvasRef : null ;
9299}
93100
94101export const resizeCanvasToDisplaySize = ( canvas : HTMLCanvasElement ) => {
@@ -213,7 +220,7 @@ class Square {
213220 y_gravity : number = 0 ;
214221 x_velocity : number = 0 ;
215222 y_velocity : number = 0 ;
216- isResetting : boolean = false ;
223+ is_resetting : boolean = false ;
217224
218225 constructor ( ctx : CanvasRenderingContext2D , initial_x : number , initial_y : number ) {
219226 this . ctx = ctx ;
@@ -223,7 +230,7 @@ class Square {
223230 this . initial_y = initial_y ;
224231 this . reset_from_x = this . x ;
225232 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 )
227234 ? `#${ ( 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 ) } `
228235 : "#FFFFFF22"
229236 console . log ( this . initial_x , this . initial_y ) ;
@@ -234,131 +241,54 @@ class Square {
234241 this . ctx . beginPath ( ) ;
235242 this . ctx . rect ( this . x - RADIUS , this . y - RADIUS , RADIUS * 2 , RADIUS * 2 ) ;
236243 this . ctx . fillStyle = this . color ;
237- this . ctx . shadowColor = this . color ;
238- this . ctx . shadowBlur = 5 ;
239244 this . ctx . fill ( ) ;
240245 this . ctx . lineWidth = 3 ;
241246 }
242247
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-
320248 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+ }
324280 }
325281
326282 reset = ( ) => {
327- this . isResetting = true ;
283+ this . is_resetting = true ;
328284 this . reset_from_x = this . x ;
329285 this . reset_from_y = this . y ;
330286 this . x_gravity = 0 ;
331287 this . y_gravity = 0 ;
332288 }
333289
334290 cancelReset = ( ) => {
335- this . isResetting = false ;
291+ this . is_resetting = false ;
336292 }
337293
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 ;
364294}
0 commit comments