JSFiddle - React, Tailwind, and code Playground

by Evan Raskob

HTML

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<div class="container">
		<div class="row">
			<div id="canvas" class="col-lg-12"></div>
		</div>
	  
		<div id="buttons" class="row">
			<div class="col-xs-3">
				<button id="p1" value="p1">p1++</button>
			</div>	
			<div class="col-xs-3">
				<button id="p2" value="p1">p2++</button>
			</div>
			<div class="col-xs-3">
				<button id="p3" value="p1">p3++</button>
			</div>			
			<div class="col-xs-3">
				<button id="p4" value="p1">p4++</button>
			</div>
		</div>
		<div id="buttons" class="row">
			<div class="col-xs-3">
				<button id="p1r" value="p1">p1--</button>
			</div>	
			<div class="col-xs-3">
				<button id="p2r" value="p1">p2--</button>
			</div>
			<div class="col-xs-3">
				<button id="p3r" value="p1">p3--</button>
			</div>			
			<div class="col-xs-3">
				<button id="p4r" value="p1">p4--</button>
			</div>
		</div>

	</div>

CSS

body {
    background-color: black;
    color: white;
    font-family: arial, sans-serif;
    font-size: 14px;
}
#canvas {
    background-color: black;
    width:100%;
    height:300px;
    margin-bottom: 18px;
}
button {
	display: block;
	width: 50%;
	margin: 0 auto;
	background-color: gray;
	font-size: 10px;
}

.score-column {
	fill: #222;
	stroke: none;
}

.player-1 {
    fill: #f8b;
    stroke: black;
}
.player-2 {
    fill: yellow;
    stroke: black;
}
.player-3 {
    fill: lightblue;
    stroke: black;
}
.player-4 {
    fill: lightgreen;
    stroke: black;
}

JavaScript

// scoreboard downward growing prototype using svg.js

// by Evan Raskob for gameshowhack
// https://twitter.com/evanraskob
// github for the project: https://github.com/pixelpusher/mozfest2013



var MAX_PLAYERS = 4;
// player scores
var scores = [];
var scoreGroups;
var scoreBoxHeight = 20;


//
// get the score for a player (0 - MAX_PLAYERS)
//
function getPlayerScore(playerIndex)
{
	if ( playerIndex < scores.length )
		return scores[playerIndex];
	else
		return -1; // error!
}

//
// init everything
//
function initCanvas()
{
	// create svg drawing paper
	draw = SVG('canvas');
	
	
	// player scores - init to 0
	for (var i=0; i<MAX_PLAYERS; i++)
		scores.push(0);
	
	
	scoreGroups = [];
	
	for (var i = 0; i < scores.length; i++) {
		var vb = draw.viewbox();
		var boxWidth = vb.width / scores.length;
		var hoffset = boxWidth * i;
		var voffset = vb.height - 24 - 20;
		var hPadding = 0.1;
		

		var scoreGroup = draw.group().attr('class', 'player-' + (i + 1));
		var scoreColumn = scoreGroup.rect(boxWidth-2*hPadding*boxWidth, vb.height).attr('class', 'score-column') 
			.move(hoffset+boxWidth*hPadding,0);
		
		var t = scoreGroup.text('P' + (i + 1))
			.move(hoffset+boxWidth/2-boxWidth*hPadding, voffset)
			.font({
				family: 'arial',
				size: 18
				})
			.fill({
				color: '#000',	
			})
			.stroke('none')
			.animate(2500, '>', 500)
			.fill({
				color: '#fff'
			});
		
		scoreGroup.boxes = [];	// this will contain the scoreboxes so we can remove them later
		scoreGroups.push(scoreGroup);
	}
	
	
	// add points scoring handlers to buttons
	document.getElementById('p1').addEventListener('click', function () {
		addScore(0);
	});
	document.getElementById('p2').addEventListener('click', function () {
		addScore(1);
	});
	document.getElementById('p3').addEventListener('click', function () {
		addScore(2);
	});
	document.getElementById('p4').addEventListener('click', function () {
		addScore(3);
	});
	
	// add points scoring handlers to...