1- import React , { useEffect , useState } from 'react' ;
2- import '../styles/Art.css' ;
1+ import React , { useEffect , useState } from 'react'
2+ import '../styles/Art.css'
3+
4+ const CELL_SIZE = 15
35
46export const Art : React . FC < any > = ( ) => {
5- const [ seconds , setSeconds ] = useState ( 0 ) ;
6- useEffect ( ( ) => {
7- const interval = setInterval ( ( ) => setSeconds ( previousValue => previousValue + 1 ) , 200 ) ;
8- return ( ) => clearInterval ( interval ) ;
9- } , [ ] ) ;
7+ const [ seconds , setSeconds ] = useState ( 0 )
8+ const [ size , setSize ] = useState < { width : number , height : number } > ( )
109
11- const [ size , setSize ] = useState < { width : number , height : number } > ( ) ;
10+ useEffect ( ( ) => {
11+ const interval = setInterval ( ( ) => setSeconds ( previousValue => previousValue + 1 ) , 200 )
12+ return ( ) => clearInterval ( interval )
13+ } , [ ] )
1214 useEffect ( ( ) => {
1315 setSize ( {
1416 width : Math . floor ( window . innerWidth ) ,
@@ -17,94 +19,97 @@ export const Art: React.FC<any> = () => {
1719 const resize = ( ) => setSize ( {
1820 width : Math . floor ( window . innerWidth ) ,
1921 height : Math . floor ( window . innerHeight )
20- } ) ;
21- window . addEventListener ( 'resize' , resize ) ;
22- return ( ) => window . removeEventListener ( 'resize' , resize ) ;
23- } , [ ] ) ;
22+ } )
23+ window . addEventListener ( 'resize' , resize )
24+ return ( ) => window . removeEventListener ( 'resize' , resize )
25+ } , [ ] )
2426
25- const [ cols , setCols ] = useState < number > ( ) ;
26- const [ rows , setRows ] = useState < number > ( ) ;
27- const [ numCells , setNumCells ] = useState < number > ( ) ;
27+ const [ cols , setCols ] = useState < number > ( )
28+ const [ rows , setRows ] = useState < number > ( )
29+ const [ numCells , setNumCells ] = useState < number > ( )
2830
2931 useEffect ( ( ) => {
30- if ( ! size ) return ;
31- let cols = Math . floor ( size . width / CELL_SIZE ) ;
32- setCols ( cols ) ;
33- let rows = Math . floor ( size . height / CELL_SIZE ) ;
34- setRows ( rows ) ;
32+ if ( ! size ) return
33+ let cols = Math . floor ( size . width / CELL_SIZE )
34+ setCols ( cols )
35+ let rows = Math . floor ( size . height / CELL_SIZE )
36+ setRows ( rows )
3537 setNumCells ( cols * rows )
36- } , [ size ] ) ;
38+ } , [ size ] )
3739
3840 const [ gameState , setGameState ] = useState < ( number [ ] | null ) [ ] > ( [ ] )
39- const [ cells , setCells ] = useState < any [ ] > ( new Array ( numCells ) ) ;
41+ const [ cells , setCells ] = useState < any [ ] > ( new Array ( numCells ) )
4042
4143 useEffect ( ( ) => setGameState ( ( ) => {
42- if ( ! numCells || ! rows || ! cols ) return [ ] ;
43- const initialCells : ( number [ ] | null ) [ ] = new Array ( numCells ) ;
44+ if ( ! numCells || ! rows || ! cols ) return [ ]
45+ const initialCells : ( number [ ] | null ) [ ] = new Array ( numCells )
4446 for ( let y = 0 ; y < rows ; y ++ ) {
4547 for ( let x = 0 ; x < cols ; x ++ ) {
46- const xChance = 1 - ( Math . abs ( cols / 2 - x ) + 20 ) / cols ;
47- const yChance = y / rows ;
48- const alive = Math . random ( ) * 3 + 4 * xChance + 2 * yChance > 6 ;
49- initialCells [ gridToIndex ( x , y , cols ) ] = ( alive ? getRandomColor ( ) : null ) ;
48+ const xChance = 1 - ( Math . abs ( cols / 2 - x ) ) / cols
49+ const yChance = y / rows
50+ const alive = Math . random ( ) * 3 + 4 * xChance + 2 * yChance > 6
51+ initialCells [ gridToIndex ( x , y , cols ) ] = ( alive ? getRandomColor ( ) : null )
5052 }
5153 }
52- return initialCells ;
54+ return initialCells
5355 } ) , [ rows , cols , numCells ] )
5456
5557 useEffect ( ( ) => setCells ( gameState . map ( ( state , index ) => {
56- return state === null ? null :
57- < Cell color = { gameState [ index ] } index = { index } />
58- } ) ) , [ gameState ] ) ;
58+ return ! state ? null : < Cell key = { index } color = { gameState [ index ] } index = { index } />
59+ } ) ) , [ gameState ] )
5960
6061 useEffect ( function updateGameState ( ) {
61- if ( ! rows || ! cols ) return ;
62+ if ( ! rows || ! cols ) return
6263 setGameState ( gameState => {
63- const newColors = new Array ( gameState . length ) ;
64+ const newColors = new Array ( gameState . length )
6465 const isAlive = ( x : number , y : number ) : number => {
65- if ( x < 0 || x >= cols || y < 0 || y >= rows ) return 0 ;
66- return gameState [ gridToIndex ( x , y , cols ) ] ? 1 : 0 ;
66+ if ( x < 0 || x >= cols || y < 0 || y >= rows ) return 0
67+ return gameState [ gridToIndex ( x , y , cols ) ] ? 1 : 0
6768 }
6869 for ( let x = 0 ; x < cols ; x ++ ) {
6970 for ( let y = 0 ; y < rows ; y ++ ) {
70- let centerIndex = gridToIndex ( x , y , cols ) ;
71+ let centerIndex = gridToIndex ( x , y , cols )
7172 let numAlive = isAlive ( x - 1 , y - 1 )
7273 + isAlive ( x , y - 1 )
7374 + isAlive ( x + 1 , y - 1 )
7475 + isAlive ( x - 1 , y )
7576 + isAlive ( x + 1 , y )
7677 + isAlive ( x - 1 , y + 1 )
7778 + isAlive ( x , y + 1 )
78- + isAlive ( x + 1 , y + 1 ) ;
79- if ( numAlive === 2 ) newColors [ centerIndex ] = gameState [ centerIndex ] ;
80- else if ( numAlive === 3 ) newColors [ centerIndex ] = getNeighborColor ( gameState [ centerIndex ] ) ;
81- else newColors [ centerIndex ] = null ;
79+ + isAlive ( x + 1 , y + 1 )
80+ if ( numAlive === 2 ) newColors [ centerIndex ] = gameState [ centerIndex ]
81+ else if ( numAlive === 3 ) newColors [ centerIndex ] = getNeighborColor ( gameState [ centerIndex ] )
82+ else newColors [ centerIndex ] = null
8283 }
8384 }
84- return newColors ;
85- } ) ;
86- } , [ cols , rows , seconds ] ) ;
87-
88- return < div className = "blob" > { cells } </ div > ;
89- } ;
85+ return newColors
86+ } )
87+ } , [ cols , rows , seconds ] )
88+ return < div className = "blob" > { cells } </ div >
89+ }
9090
91- const CELL_SIZE = 12 ;
92- const getRandomColor = ( ) => [ Math . random ( ) * 255 , Math . random ( ) * 255 , Math . random ( ) * 255 ] ;
93- const getNeighborColor = ( color : number [ ] | null ) => ( color ?? [ 1 , 1 , 1 ] ) . map ( value => ( value + ( Math . random ( ) * 255 ) ) / 2 ) ;
94- const gridToIndex = ( x : number , y : number , cols : number ) => x + ( y * cols ) ;
91+ const getRandomColor = ( ) => [ Math . random ( ) * 255 , Math . random ( ) * 255 , Math . random ( ) * 255 ]
92+ const getNeighborColor = ( color : number [ ] | null ) => ( color ?? [ 1 , 1 , 1 ] ) . map ( value => ( value + ( Math . random ( ) * 255 ) ) / 2 )
93+ const gridToIndex = ( x : number , y : number , cols : number ) => x + ( y * cols )
9594
9695const Cell : React . FC < { index : number , color : number [ ] | null } > = props => {
9796 const size = {
9897 width : Math . floor ( window . innerWidth ) ,
9998 height : Math . floor ( window . innerHeight )
10099 }
101- const cols = Math . floor ( size . width / CELL_SIZE ) ;
102- const indexToGrid = ( index : number ) => [ index % cols , index / cols ] ;
103- const [ left , top ] = indexToGrid ( props . index ) . map ( index => `${ CELL_SIZE * index + 1 } px` ) ;
100+ const cols = Math . floor ( size . width / CELL_SIZE )
101+ const indexToGrid = ( index : number ) => [ index % cols , index / cols ]
102+ const [ left , top ] = indexToGrid ( props . index ) . map ( index => `${ CELL_SIZE * index + 1 } px` )
104103
105104 return props . color ? < div
106- className = "cell"
107- style = { { left, top, background : `rgba(${ props . color [ 0 ] } , ${ props . color [ 1 ] } , ${ props . color [ 2 ] } , .4)` } }
105+ style = { {
106+ left,
107+ top,
108+ background : `rgba(${ props . color [ 0 ] } , ${ props . color [ 1 ] } , ${ props . color [ 2 ] } , .4)` ,
109+ height : `${ CELL_SIZE } px` ,
110+ width : `${ CELL_SIZE } px` ,
111+ position : 'absolute'
112+ } }
108113 />
109- : < div key = { props . index . toString ( ) } /> ;
110- } ;
114+ : < div key = { props . index . toString ( ) } />
115+ }
0 commit comments