Browse Source

Make width and height adjustable

master
Dylan Baker 4 years ago
parent
commit
0dcf852dc5
3 changed files with 101 additions and 21 deletions
  1. 43
    12
      src/Board.tsx
  2. 43
    8
      src/Controls.tsx
  3. 15
    1
      src/index.css

+ 43
- 12
src/Board.tsx View File

3
 import Controls from './Controls';
3
 import Controls from './Controls';
4
 import { generateNewGrid } from './lib';
4
 import { generateNewGrid } from './lib';
5
 
5
 
6
-interface Props {
7
-  width?: number;
8
-  height?: number;
9
-  speed?: number;
10
-}
6
+const DEFAULT_WIDTH = 20;
7
+const DEFAULT_HEIGHT = 10;
8
+const DEFAULT_SPEED = 500;
11
 
9
 
12
 interface State {
10
 interface State {
13
   grid: boolean[][];
11
   grid: boolean[][];
14
   running: boolean;
12
   running: boolean;
15
   speed: number;
13
   speed: number;
14
+  width: number;
15
+  height: number;
16
 }
16
 }
17
 
17
 
18
-class Board extends React.Component<Props, State> {
18
+class Board extends React.Component<{}, State> {
19
   timer: NodeJS.Timeout | null;
19
   timer: NodeJS.Timeout | null;
20
 
20
 
21
-  constructor(props: Props) {
21
+  constructor(props: {}) {
22
     super(props);
22
     super(props);
23
-    const height = props.height ?? 10;
24
-    const width = props.height ?? 20;
25
     this.state = {
23
     this.state = {
26
-      grid: Array(height).fill(Array(width).fill(false)),
24
+      grid: Array(DEFAULT_HEIGHT).fill(Array(DEFAULT_WIDTH).fill(false)),
27
       running: false,
25
       running: false,
28
-      speed: 500,
26
+      speed: DEFAULT_SPEED,
27
+      width: DEFAULT_WIDTH,
28
+      height: DEFAULT_HEIGHT,
29
     };
29
     };
30
     this.timer = null;
30
     this.timer = null;
31
   }
31
   }
63
     }
63
     }
64
   };
64
   };
65
 
65
 
66
+  updateDimensions = (dimensions: { width?: number; height?: number }) => {
67
+    if (dimensions.width) {
68
+      this.setState({ width: dimensions.width });
69
+    }
70
+
71
+    if (dimensions.height) {
72
+      this.setState({ height: dimensions.height });
73
+    }
74
+
75
+    const width = dimensions.width ?? this.state.width;
76
+    const height = dimensions.height ?? this.state.height;
77
+
78
+    const grid = [...this.state.grid];
79
+    while (grid.length < height) {
80
+      grid.push(Array(width).fill(false));
81
+    }
82
+
83
+    const newGrid = grid.map((row) => {
84
+      while (row.length < width) {
85
+        row.push(false);
86
+      }
87
+
88
+      return row;
89
+    });
90
+
91
+    this.setState({ grid: newGrid });
92
+  };
93
+
66
   render() {
94
   render() {
67
-    const { grid, running, speed } = this.state;
95
+    const { grid, running, speed, width, height } = this.state;
68
 
96
 
69
     return (
97
     return (
70
       <div className="board">
98
       <div className="board">
72
           running={running}
100
           running={running}
73
           speed={speed}
101
           speed={speed}
74
           toggle={this.toggleRunning}
102
           toggle={this.toggleRunning}
103
+          width={width}
104
+          height={height}
105
+          updateDimensions={this.updateDimensions}
75
           updateSpeed={this.updateSpeed}
106
           updateSpeed={this.updateSpeed}
76
         />
107
         />
77
         {grid.map((row, y) => (
108
         {grid.map((row, y) => (

+ 43
- 8
src/Controls.tsx View File

3
 interface Props {
3
 interface Props {
4
   running: boolean;
4
   running: boolean;
5
   speed: number;
5
   speed: number;
6
+  width: number;
7
+  height: number;
6
   toggle: () => void;
8
   toggle: () => void;
7
   updateSpeed: (speed: number) => void;
9
   updateSpeed: (speed: number) => void;
10
+  updateDimensions: (dimensions: { width?: number; height?: number }) => void;
8
 }
11
 }
9
 
12
 
10
 const Controls = (props: Props) => {
13
 const Controls = (props: Props) => {
11
-  const { running, speed, toggle, updateSpeed } = props;
14
+  const {
15
+    running,
16
+    speed,
17
+    toggle,
18
+    updateSpeed,
19
+    width,
20
+    height,
21
+    updateDimensions,
22
+  } = props;
12
 
23
 
13
   const goSlower = () => {
24
   const goSlower = () => {
14
     updateSpeed(speed + 100);
25
     updateSpeed(speed + 100);
22
 
33
 
23
   return (
34
   return (
24
     <div className="controls">
35
     <div className="controls">
25
-      <button onClick={toggle}>{running ? 'Pause' : 'Play'}</button>
26
-      <div className="speed">
27
-        <button onClick={goSlower}>Slower</button>
28
-        <button disabled={speed <= 100} onClick={goFaster}>
29
-          Faster
30
-        </button>
31
-        <span>{speed}ms</span>
36
+      <div className="controls__row --width">
37
+        <label>
38
+          Width{' '}
39
+          <input
40
+            type="number"
41
+            value={width}
42
+            onChange={(e) =>
43
+              updateDimensions({ width: parseInt(e.currentTarget.value, 10) })
44
+            }
45
+          />
46
+        </label>
47
+        <label>
48
+          Height{' '}
49
+          <input
50
+            type="number"
51
+            value={height}
52
+            onChange={(e) =>
53
+              updateDimensions({ height: parseInt(e.currentTarget.value, 10) })
54
+            }
55
+          />
56
+        </label>
57
+      </div>
58
+      <div className="controls__row">
59
+        <button onClick={toggle}>{running ? 'Pause' : 'Play'}</button>
60
+        <div className="speed">
61
+          <button onClick={goSlower}>Slower</button>
62
+          <button disabled={speed <= 100} onClick={goFaster}>
63
+            Faster
64
+          </button>
65
+          <span>{speed}ms</span>
66
+        </div>
32
       </div>
67
       </div>
33
     </div>
68
     </div>
34
   );
69
   );

+ 15
- 1
src/index.css View File

56
 
56
 
57
 .controls {
57
 .controls {
58
   display: flex;
58
   display: flex;
59
-  margin-bottom: 1em;
59
+  flex-direction: column;
60
   width: 100%;
60
   width: 100%;
61
 }
61
 }
62
 
62
 
80
   color: white;
80
   color: white;
81
 }
81
 }
82
 
82
 
83
+.controls .controls__row {
84
+  display: flex;
85
+  margin: 1em 0;
86
+}
87
+
83
 .controls .speed {
88
 .controls .speed {
84
   align-items: center;
89
   align-items: center;
85
   display: flex;
90
   display: flex;
101
   cursor: not-allowed;
106
   cursor: not-allowed;
102
   opacity: 0.6;
107
   opacity: 0.6;
103
 }
108
 }
109
+
110
+.--width label {
111
+  flex: 1;
112
+}
113
+
114
+.--width input {
115
+  border: 1px solid black;
116
+  font-size: 16px;
117
+}

Loading…
Cancel
Save