JSFiddle - React, Tailwind, and code Playground
by UTree
HTML
<div class="table">
<p class="message">Use keyboard arrows to control left player. <a href="http://codepen.io/allanpope/full/a01ddb29cbdecef58197c2e829993284/">Open in fullscreen</a>.</p>
<div class="table-inner">
<span class="table__goal-crease circle"></span>
<span class="table__faceoff table__faceoff--top-left circle"></span>
<span class="table__faceoff table__faceoff--bottom-left circle"></span>
<span class="table__blue-line"></span>
<span class="table__center-line"></span>
<span class="circle"></span>
<span class="table__blue-line table__blue-line--two"></span>
<span class="table__faceoff table__faceoff--top-right circle"></span>
<span class="table__faceoff table__faceoff--bottom-right circle"></span>
<span class="table__goal-crease table__goal-crease--two circle"></span>
</div>
</div>
<canvas id="canvas" class="table table--canvas" tabindex="0"></canvas>
CSS
// Colors
@red: fade(#bb0422, 25%);
@blue: fade(#304f86, 25%);
@black: #2e2e2e;
@grey: #F1F0F4;
@grey-dark: #7A7A7A;
@ice: #FFF;
// Table
@table-width: 800px;
@table-height: 550px;
@table-border: 15px;
@table-border-2x: @table-border * 2;
@line-width: 5px;
@blue-line-pos: 37%;
@circle-center-size: 140px;
@goal-size: 190px;
@table-faceoff-size: 80px;
@table-faceoff-pos: 20%;
* {
box-sizing: border-box;
}
body {
background-color: @grey;
font-family: helvetica;
}
a {
color: @grey-dark;
text-decoration: none;
transition: .3s opacity ease-out;
&:hover,
&:focus {
opacity: .6;
}
}
.circle {
width: @circle-center-size;
height: @circle-center-size;
border-radius: 100%;
border: @line-width solid @blue;
position: absolute;
top: 50%;
left: 50%;
margin-top: -(@circle-center-size/2);
margin-left: -(@circle-center-size/2);
}
// Table
.table {
width: @table-width;
height: @table-height;
margin-top: -(@table-height / 2);
margin-left: -(@table-width / 2);
position: absolute;
top: 50%;
left: 50%;
border: @table-border solid @black;
border-radius: 70px;
background-color: @ice;
box-shadow: inset 0 2px 5px 0 rgba(50, 50, 50, 0.25);
&:before,
&:after {
content: '';
position: absolute;
background-color: @grey-dark;
width: @table-border;
height: @goal-size;
top: 50%;
left: -@table-border;
margin-top: -(@goal-size / 2);
}
&:after {
left: auto;
right: -@table-border;
}
}
.table--canvas {
width: @table-width - @table-border-2x;
height: @table-height - @table-border-2x;
margin-top: -((@table-height - @table-border-2x) / 2);
margin-left: -((@table-width - @table-border-2x) / 2);
background-color: transparent;
border-radius: 55px;
border: none;
&:focus {
outline: none;
}
}
.table-inner {
overflow: hidden;
display: block;
position: relative;
width: 100%;
height: 100%;
}
.table__center-line {
width: @line-width;
height: 100%;
background-color: @red;
position: absolute;
left: 50%;
margin-left:...
JavaScript
var board = document.getElementById("canvas"),
boardContext = board.getContext('2d'),
boardWidth = window.innerWidth,
boardHeight = window.innerHeight,
boardCenterX = boardWidth / 2,
boardCenterY = boardHeight / 2,
controllers = [],
goal = document.getElementsByClassName('table__goal-crease'),
goalHeight = goal[0].clientHeight,
goalPosTop = (boardHeight - goalHeight) / 2,
score = [];
// Set width & height for canvas
board.width = boardWidth;
board.height = boardHeight;
// Set focus to canvas so keyboard events work
board.focus();
// Disc
function Disc() {
this.startingPosX = boardCenterX;
this.startingPosY = boardCenterY;
this.x = this.startingPosX;
this.y = this.startingPosY;
this.radius = 34;
this.mass = 15;
this.velocityX = 0;
this.velocityY = 0;
this.maxSpeed = 10;
this.frictionX = 0.997;
this.frictionY = 0.997;
this.acceleration = 1;
this.color = '#000000';
this.keepControllerInBoard = function() {
// Need to determine if goal scored on x axis as well
if (this.x > (boardWidth - this.radius) || this.x < this.radius) {
if (this.x < this.radius) {
this.velocityX = 2;
} else {
this.velocityX = -2;
}
}
// Determine if disc is to far up or down
if (this.y > (boardHeight - this.radius) || this.y < this.radius) {
if (this.y < this.radius) {
this.velocityY = 2;
} else {
this.velocityY = -2;
}
}
// Keep player one controller on left hand side of screen
if (controller.x > (boardCenterX - controller.radius) && controller.x < boardCenterX) {
controller.velocityX = -3;
}
// Keep player two controller on right hand side of screen
if (controllerTwo.x > boardCenterX && controllerTwo.x < (boardCenterX + (controllerTwo.radius / 2))) {
controllerTwo.velocityX = +3;
}
},
// Keep disc inside board
this.keepPuckInBoard = function() {
// Determine if disc is to far right or...