Bouncing ball - test

by jonahe

HTML

<div id="app"></div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

.arena {
  background: yellow;
  border: 1px solid teal;
}
.ball {
  display: flex;
  justify-content: center;
  align-items: center;
  background: red;
  color: white;
  font-weight: bold;
  
}

React

const stageX = 300;
const stageY = 200;
const ballDiameter = 30;
class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = { velocity: [-5,-2], x: 40, y: 20};
    this.updatePosition();
  }
  
  updatePosition() {
  	requestAnimationFrame(() => {
    	const {velocity, x, y} = this.state;
      let newX, newY;
      let newVelocity = [...velocity];
      const shouldBounceAgainstLeftWall = (x <= 0 && velocity[0] <= -1);
      const shouldBounceAgainstRightWall = (x >= stageX - ballDiameter && velocity[0] >= 1);
      
      if(shouldBounceAgainstLeftWall || shouldBounceAgainstRightWall) {
      	newVelocity[0] = velocity[0] * -1;
      }
      
      const shouldBounceAgainstTopWall = (y <= 0 && velocity[1] <= -1);
      const shouldBounceAgainstBottomWall = (y >= stageY - ballDiameter && velocity[1] >= 1);
      if(shouldBounceAgainstTopWall || shouldBounceAgainstBottomWall) {
      	newVelocity[1] = velocity[1] * -1;
      }
      newX = x + newVelocity[0];
      newY = y + newVelocity[1];
      this.setState({velocity: newVelocity, x: newX, y: newY });
      this.updatePosition();
    });
  }
  speedChanger(multiplier) {
  	return () => {
    	const oldVelocity = this.state.velocity;
  		this.setState({
    		velocity: oldVelocity.map(v => v * multiplier)
    	});
      
    }
  }
  
  render() {
    return (
    <div>
      <button onClick={this.speedChanger(1.1)}>Click to increase speed</button>
      <button onClick={this.speedChanger(0.9)}>Click to decrease speed</button>
    	<div className="arena" style={{height: stageY + "px", width: stageX + "px"}}>
        <div className="ball" style={ 
        	{
          	height: ballDiameter + "px",
            width: ballDiameter + "px",
            borderRadius: (ballDiameter/2) + "px",
      			transform: `translateX(${this.state.x}px) translateY(${this.state.y}px)`
      		}
        } >4</div>
      </div>
     </div>
    )
  }
}

ReactDOM.render(<TodoApp />,...