Compare commits

...

22 Commits

Author SHA1 Message Date
  edoardoo 148ec764a3 bigger font 9 years ago
  edoardoo c9df78338e fixed multiple object local json 9 years ago
  edoardoo 07869652b2 added local json input 9 years ago
  edoardoo 758568c033 undefined score fix 9 years ago
  edoardoo 23121ca1ff added keystroke arrows and strings on score and index rendered image 9 years ago
  edoardoo 77af021323 added score image, and fixed leaderbard menu zindex 9 years ago
  edoardoo 14ebfb1a5d fixed overflow on slide rendered images, maybe 9 years ago
  edoardoo 3da181d58d fixed overflow on slide rendered images 9 years ago
  edoardoo 6f2d6ddcba fixed max length of renderedImage 9 years ago
  edoardoo a67786faee added multiple honeycmob rendering, diahane 9 years ago
  edoardoo e69e7f5614 added update time and script for screenshot 9 years ago
  edoardoo 573b6e6a6a aligned with master and the mother fucking sample problems, beacuse: ce l'avete tutti 9 years ago
  edoardoo 66da973e02 leaderboard with alarm on new points 9 years ago
  edoardoo b7c4ac7c95 fix: client wasn't conneting if server is not restarted meanwhile 9 years ago
  edoardoo af91d6fb3c working live update through /show POST 9 years ago
  edoardoo 0bfcf47f33 added node 9 years ago
  edoardoo 41a2511a1d honeycomb working with marked cells 9 years ago
  edoardoo 88e1254fb7 fix: problem on multiple sessions 9 years ago
  edoardoo ef4956007c fix: client wasn't conneting if server is not restarted meanwhile 9 years ago
  edoardoo 140caf7b53 working live update through /show POST 9 years ago
  edoardoo 75a4006218 added node 9 years ago
  edoardoo 7c53f0d53b honeycomb working with marked cells 9 years ago
15 changed files with 12294 additions and 0 deletions
Split View
  1. +1
    -0
      .gitignore
  2. +0
    -0
      index.html
  3. +22
    -0
      package.json
  4. +34
    -0
      public/index.html
  5. +286
    -0
      public/scripts/functions.js
  6. +4519
    -0
      public/scripts/html2canvas.js
  7. +17
    -0
      public/scripts/less.min.js
  8. +7006
    -0
      public/scripts/socket.io.js
  9. +17
    -0
      public/scripts/socketSetup.js
  10. BIN
      public/sounds/bell.mp3
  11. +39
    -0
      public/style/style.css
  12. +7
    -0
      public/style/style.css.map
  13. +197
    -0
      public/style/style.less
  14. +72
    -0
      public/style/style.scss
  15. +77
    -0
      server.js

+ 1
- 0
.gitignore View File

@ -0,0 +1 @@
node_modules/

+ 0
- 0
index.html View File


+ 22
- 0
package.json View File

@ -0,0 +1,22 @@
{
"name": "icfp2015",
"version": "1.0.0",
"description": "",
"main": "server.js",
"dependencies": {
"body-parser": "^1.13.3",
"cookie-parser": "^1.3.5",
"express": "^4.13.3",
"socket.io": "^1.3.6"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://edoardoo@bitbucket.org/lilik/icfp2015.git"
},
"author": "",
"license": "ISC"
}

+ 34
- 0
public/index.html View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<title>icfp 2015 visualizer</title>
<!-- <link rel="stylesheet" type="text/css" href="style/style.css"> -->
<link rel="stylesheet/less" type="text/css" href="style/style.less" />
<script type="text/javascript" src="scripts/less.min.js"></script>
<script type="text/javascript" src="scripts/socket.io.js"></script>
<script type="text/javascript" src="scripts/html2canvas.js"></script>
</head>
<body>
<div id="controlBar">
<button onclick="slideBack()"><</button>
<span id="indexSlide"></span>
<button onclick="slideForward()">></button>
</div>
<div id="leaderBoard" class="">
<button onclick="toggleLeaderBoard()">LeaderBoard</button>
<section id="listBoard">Loading...</section>
</div>
<div class="bottomRight"><input placeholder="Paste Json, visible only locally." type="text" id="sendHCJson"><button onclick="sendJson()">Send</button></div>
<section id="honeyComb">
</section>
<section id="renderedHoneyComb"></section>
<script type="text/javascript" src="scripts/socketSetup.js"></script>
<script type="text/javascript" src="scripts/functions.js"></script>
<audio id="bell" controls>
<source src="sounds/bell.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</body>
</html>

+ 286
- 0
public/scripts/functions.js View File

@ -0,0 +1,286 @@
var points = 0;
var totalRenders = 0;
function updateDimensions( dimension ){
less.modifyVars({"@sizeWidth":dimension+"px"});
}
function prePopulate(honeyCells){
var honeyCells = JSON.parse(honeyCells);
if( honeyCells.constructor === Array){
for (var i = 0; i < honeyCells.length; i++) {
populateHoneycomb( honeyCells[i], i );
};
}else{
populateHoneycomb( honeyCells , 0);
}
}
function populateHoneycomb( honeyCells , index){
// honeyCells = jsonExample;
var height = "innerHeight" in window
? window.innerHeight
: document.documentElement.offsetHeight;
var width = "innerWidth" in window
? window.innerWidth
: document.documentElement.offsetWidth;
// var cellWidth = ( height/honeyCells.height )*Math.sqrt(3);
// if( width/honeyCells.width < height/honeyCells.height ){
var cellWidth = (width - honeyCells.width)/(honeyCells.width+1);
// }
updateDimensions( cellWidth );
var horizontal = false;
if(width/height > 1){
horizontal = true;
}
var honeyCombHorizontal = false;
if( honeyCells.width/honeyCells.height > 1){
honeyCombHorizontal = true;
}
var honeyComb = document.getElementById("honeyComb");
var renderedHoneyComb = document.getElementById("renderedHoneyComb");
renderedHoneyComb.innerHTML="";
if( typeof honeyCells.score == "undefined"){
honeyCells.score = 0;
}
honeyComb.innerHTML = "<div class='honeycombIndex'>Index: "+index+"</div>";
honeyComb.innerHTML += "<div class='honeycombScore'>Score:"+honeyCells.score+"</div>";
for (var i = honeyCells.height - 1; i >= 0; i--) {
var even = (i%2 == 0) ? "even" : "";
var container = document.createElement('div');
container.className = "hex-row " + even;
honeyComb.appendChild(container);
for (var j = honeyCells.width - 1; j >= 0; j--) {
var hexCell = document.createElement("div");
hexCell.className = "hex";
container.appendChild(hexCell);
var topPart = document.createElement('div');
topPart.className = "top";
var middlePart = document.createElement('div');
middlePart.className = "middle";
var bottomPart = document.createElement('div');
bottomPart.className = "bottom";
hexCell.appendChild(topPart);
hexCell.appendChild(middlePart);
hexCell.appendChild(bottomPart);
};
};
addHexDetails( honeyCells );
renderImage( index );
totalRenders++;
removeHexs();
}
function addHexDetails( honeyCells ){
setFilled( honeyCells, honeyCells.filled, "active" );
if(honeyCells.touched){
setFilled( honeyCells, honeyCells.touched, "touched" );
}
if(honeyCells.unit){
setFilled( honeyCells, honeyCells.unit, "unitMember" );
}
}
function removeHexs(){
var honeyComb = document.getElementById("honeyComb");
honeyComb.innerHTML = "";
}
function setFilled( honeyCells, cellsToCheck, className ){
// honeyCells = jsonExample;
var hexCells = document.getElementsByClassName("hex");
for (var i = 0; i < cellsToCheck.length; i++) {
var x = cellsToCheck[i].x;
var y = cellsToCheck[i].y;
var filledCell = ( y * honeyCells.width ) + x;
var honeyCell = hexCells[ filledCell ];
honeyCell.className += " "+className;
};
}
function renderImage(index){
html2canvas(document.getElementById("honeyComb")).then(function(canvas) {
canvas.id = "rendered_"+index;
canvas.className = "renderedCanvas";
if(index == 0){
canvas.className += " visible";
}
document.getElementById("renderedHoneyComb").appendChild(canvas);
totalRenders--;
if( totalRenders == 0){
document.getElementById("controlBar").className += " visible";
}
});
}
function orderRenderedCanvas(){
renders = [].slice.call(renders);
renders.sort(function(a,b){
if(a.id.split("_")[1] == 0){
a.className += " visible";
}
if(a.id.split("_")[1] < b.id.split("_")[1] ){
return -1;
}
});
var container = document.getElementById("renderedHoneyComb");
container.innerHTML = "";
for (var i = 0; i < renders.length; i++) {
container.appendChild(renders[i]);
};
// 17:43
}
function slideBack(){
var actual = document.getElementById("renderedHoneyComb").getElementsByClassName("visible")[0];
var actualId = actual.id.split("_")[1];
if(actualId > 0){
actualId--;
actual.className = "renderedCanvas";
document.getElementById("rendered_"+actualId).className += " visible";
}
}
function slideForward(){
var actual = document.getElementById("renderedHoneyComb").getElementsByClassName("visible")[0];
var actualId = actual.id.split("_")[1];
if(actualId < document.getElementsByClassName("renderedCanvas").length - 1){
actualId++;
actual.className = "renderedCanvas";
document.getElementById("rendered_"+actualId).className += " visible";
}
}
function hasClass(el, cls) {
return el.className && new RegExp("(\\s|^)" + cls + "(\\s|$)").test(el.className);
}
function removeClass(ele,cls) {
if (hasClass(ele,cls)) {
var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
ele.className=ele.className.replace(reg,' ');
}
}
function removeId(id) {
return (elem=document.getElementById(id)).parentNode.removeChild(elem);
}
function toggleLeaderBoard(){
var leaderBoard = document.getElementById("leaderBoard");
if( hasClass(leaderBoard, "open")){
removeClass(leaderBoard, "open");
}else{
leaderBoard.className += " open";
}
updateLeaderBoard()
}
function populateBoard(){
var listBoard = document.getElementById("listBoard");
var results = "";
var rankings = data.data.rankings;
var date = new Date();
var seconds = date.getSeconds();
var minutes = date.getMinutes();
var hour = date.getHours();
for (var i = rankings.length - 1; i >= 0; i--) {
if( rankings[i].teamId == 235 ){
results += "<p>Updated "+hour+"h "+minutes+"m "+seconds+"s</p>";
results += "<h1>Cazziammolla Placement: "+rankings[i].rank+"</h1>";
results += "<h2>with a score of: "+rankings[i].score+"</h2>";
if (rankings[i].rank != points && points != 0){
ringTheBell();
}
points = rankings[i].rank;
}
};
var settings = data.data.settings;
for (var i = 0; i < settings.length; i++) {
for (var j = settings[i].rankings.length - 1; j >= 0; j--) {
if(settings[i].rankings[j].teamId == 235){
results += "<tr><td>"+i+"</td><td>"+j+"</td></tr>"
}
};
};
var results = "<table><thead><th>Setting</th><th>Placement</th></thead>"+results+"</table>";
listBoard.innerHTML = results;
}
function updateLeaderBoard(){
loadRankingJs('https://davar.icfpcontest.org/rankings.js?cachebuster='+ new Date().getTime());
var intervalID = setInterval( function(){
loadRankingJs('https://davar.icfpcontest.org/rankings.js?cachebuster='+ new Date().getTime());
}, 30000);
}
function loadRankingJs(scriptName) {
var rankingScript = document.getElementById("rankingScript");
if ( rankingScript ){
removeId("rankingScript");
}
var docHeadObj = document.getElementsByTagName("head")[0];
var dynamicScript = document.createElement("script");
dynamicScript.type = "text/javascript";
dynamicScript.id = "rankingScript";
dynamicScript.src = scriptName;
dynamicScript.onload = function(){ populateBoard();};
docHeadObj.appendChild(dynamicScript);
return dynamicScript;
}
function ringTheBell(){
document.getElementById("bell").play();
}
document.onkeydown = checkKey;
function sendJson(){
// console.log("sending mama some json.")
// socket.emit("jsonToParse", document.getElementById("sendHCJson").value);
prePopulate( document.getElementById("sendHCJson").value);
}
function checkKey(e) {
e = e || window.event;
if ( document.getElementById("controlBar").className.indexOf("visible") != -1 ) {
if (e.keyCode == '37') {
slideBack();
}else if(e.keyCode == '39') {
slideForward();
}
}
}
// jsonExample = {"height":15,"width":15,"sourceSeeds":[0],"units":[{"members":[{"x":0,"y":0}],"pivot":{"x":0,"y":0}}],"id":1,"filled":[{"x":2,"y":4},{"x":3,"y":4},{"x":4,"y":4},{"x":5,"y":4},{"x":6,"y":4},{"x":11,"y":4},{"x":2,"y":5},{"x":8,"y":5},{"x":11,"y":5},{"x":2,"y":6},{"x":11,"y":6},{"x":2,"y":7},{"x":3,"y":7},{"x":4,"y":7},{"x":8,"y":7},{"x":11,"y":7},{"x":2,"y":8},{"x":9,"y":8},{"x":11,"y":8},{"x":2,"y":9},{"x":8,"y":9},{"x":2,"y":10},{"x":3,"y":10},{"x":4,"y":10},{"x":5,"y":10},{"x":6,"y":10},{"x":9,"y":10},{"x":11,"y":10}],"sourceLength":100};

+ 4519
- 0
public/scripts/html2canvas.js
File diff suppressed because it is too large
View File


+ 17
- 0
public/scripts/less.min.js
File diff suppressed because it is too large
View File


+ 7006
- 0
public/scripts/socket.io.js
File diff suppressed because it is too large
View File


+ 17
- 0
public/scripts/socketSetup.js View File

@ -0,0 +1,17 @@
var socket = io();
/*Initializing the connection with the server via websockets */
socket.emit('liveMessage', "true");
socket.on("jsonHoneycomb",function(message){
/*
When server sends data to the client it will trigger "message" event on the client side , by
using socket.on("message") , one cna listen for the ,message event and associate a callback to
be executed . The Callback function gets the dat sent from the server
*/
console.log("Message from the server arrived")
prePopulate(message);
socket.emit('ackMessage', "true");
});

BIN
public/sounds/bell.mp3 View File


+ 39
- 0
public/style/style.css View File

@ -0,0 +1,39 @@
html, body {
margin: 0;
padding: 0;
height: 100%;
width: 100%; }
body {
background-color: #333; }
.hex {
float: left;
margin-left: 3px;
margin-bottom: -26px; }
.hex .top, .hex.disabled .top {
width: 0;
border-bottom: 30.02221px solid #6C6;
border-left: 52px solid transparent;
border-right: 52px solid transparent; }
.hex .middle {
width: 104px;
height: 60.04443px;
background: #6C6; }
.hex .bottom {
width: 0;
border-top: 30.02221px solid #6C6;
border-left: 52px solid transparent;
border-right: 52px solid transparent; }
.hex.disabled .top {
border-bottom-color: #efefef; }
.hex.disabled .middle {
background: #efefef; }
.hex.disabled .bottom {
border-top-color: #efefef; }
.hex-row {
clear: left; }
.hex-row.even {
margin-left: 53px; }
/*# sourceMappingURL=style.css.map */

+ 7
- 0
public/style/style.css.map View File

@ -0,0 +1,7 @@
{
"version": 3,
"mappings": "AAiBA,UAAU;EACT,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;EACV,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,IAAI;;AAEZ,IAAI;EACH,gBAAgB,EAAE,IAAI;;AAEvB,IAAK;EACJ,KAAK,EAAE,IAAI;EACX,WAAW,EAAE,GAAG;EAChB,aAAa,EAAE,KAAK;EAEpB,6BAAK;IACJ,KAAK,EAAE,CAAC;IACR,aAAa,EAAE,qBAAyB;IACxC,WAAW,EAAE,sBAA+B;IAC5C,YAAY,EAAE,sBAA+B;EAE9C,YAAQ;IACP,KAAK,EAzBK,KAAK;IA0Bf,MAAM,EAxBK,UAAkB;IAyB7B,UAAU,EAAE,IAAI;EAEjB,YAAQ;IACP,KAAK,EAAE,CAAC;IACR,UAAU,EAAE,qBAAwB;IACpC,WAAW,EAAE,sBAA8B;IAC3C,YAAY,EAAE,sBAA8B;EAI5C,kBAAI;IAEH,mBAAmB,EAxCN,OAAO;EA2CrB,qBAAO;IACN,UAAU,EA5CG,OAAO;EA8CrB,qBAAO;IACN,gBAAgB,EA/CH,OAAO;EAkDtB,QAAK;IACJ,KAAK,EAAE,IAAI;IACX,aAAO;MACN,WAAW,EAAE,IAAgB",
"sources": ["style.scss"],
"names": [],
"file": "style.css"
}

+ 197
- 0
public/style/style.less View File

@ -0,0 +1,197 @@
@activeColor: #FFDDA0;
@touchColor: #F7D7D7;
@unitColor: #C2F19D;
@sizeWidth: 100px;
@border: 1px;
@sizeHeight: @sizeWidth/sqrt(3);
@color: #efefef;
html, body{
margin: 0;
padding: 0;
height: auto;
width: 100%;
}
body{
background-color: #333;
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-weight: 300;
}
audio{
display: none;
}
.transition{
-webkit-transition: all .5s ease-in-out; /* Android 2.1+, Chrome 1-25, iOS 3.2-6.1, Safari 3.2-6 */
transition: all .5s ease-in-out;
}
.bottomRight{
position: fixed;
right: 0;
bottom: 0;
z-index: 9999;
background: #666;
padding: 10px;
button{
margin-left: 10px;
margin-right: 10px;
}
input{
min-width: 200px;
}
}
#controlBar{
position: fixed;
top: 0;
width: 100%;
margin: 0 auto;
text-align: center;
z-index: 999;
display: none;
&.visible{
display: block;
}
}
#renderedHoneyComb{
canvas{
height: 700px;
position: absolute;
display: none;
}
canvas.visible{
display: block;
}
}
#leaderBoard:extend(.transition) {
position: fixed;
top: 0px;
right: 0;
width: 500px;
height: 100%;
overflow: hidden;
background-color: rgba(255,255,255,1);
right: -400px;
color: #333;
opacity: .2;
z-index: 999;
h1, h2, p{
padding-left: 10px;
}
&:hover{
opacity: 1;
}
button{
height: 100%;
background-color: rgba(0,0,0,0.5);
color: white;
border-color: transparent;
float: left;
width: 100px;
opacity: .4;
}
#listBoard{
float: left;
overflow: auto;
height: 100%;
width: 400px;
table, tr{
width: 100%;
td{
width: 50%;
text-align: center;
}
}
}
&.open:extend(.transition){
right: 0;
opacity: 1;
}
}
.honeycombIndex{
position: fixed;
top: 0;
left: 0;
background-color: rgba(185, 5, 198, 0.29);
padding: 20px;
z-index: 999;
font-size: 50px;
}
.honeycombScore:extend(.honeycombIndex){
top: 120px;
background-color: rgba(175, 0, 198, 0.29);
}
.hex {
float: left;
margin-left: @border;
margin-bottom: -@sizeWidth/4;
.top {
width: 0;
border-bottom: @sizeHeight/2 solid @color;
border-left: @sizeWidth/2 solid transparent;
border-right: @sizeWidth/2 solid transparent;
}
.middle {
width: @sizeWidth;
height: @sizeHeight;
background: @color;
}
.bottom {
width: 0;
border-top: @sizeHeight/2 solid @color;
border-left: @sizeWidth/2 solid transparent;
border-right: @sizeWidth/2 solid transparent;
}
&.active{
.top:extend(.hex .top){
border-bottom-color: @activeColor;
}
.middle:extend(.hex .middle){
background: @activeColor;
}
.bottom:extend(.hex .bottom){
border-top-color: @activeColor;
}
}
&.touched{
.top:extend(.hex .top){
border-bottom-color: @touchColor;
}
.middle:extend(.hex .middle){
background: @touchColor;
}
.bottom:extend(.hex .bottom){
border-top-color: @touchColor;
}
}
&.unitMember{
.middle:extend(.hex .middle){
background-color: @unitColor;
// background-image:
}
}
&-row{
clear: left;
&.even {
margin-left: (@sizeWidth/2);
}
}
}

+ 72
- 0
public/style/style.scss View File

@ -0,0 +1,72 @@
@function sqrt($r) {
$x0: 1;
$x1: $x0;
@for $i from 1 through 10 {
$x1: $x0 - ($x0 * $x0 - abs($r)) / (2 * $x0);
$x0: $x1;
}
@return $x1;
}
$disabledColor: #efefef;
$sizeWidth: 104px;
$border: 1px;
$sizeHeight: $sizeWidth/sqrt(3);
html, body{
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
body{
background-color: #333;
}
.hex {
float: left;
margin-left: 3px;
margin-bottom: -26px;
.top {
width: 0;
border-bottom: $sizeHeight/2 solid #6C6;
border-left: $sizeWidth/2 solid transparent;
border-right: $sizeWidth/2 solid transparent;
}
.middle {
width: $sizeWidth;
height: $sizeHeight;
background: #6C6;
}
.bottom {
width: 0;
border-top: $sizeHeight/2 solid #6C6;
border-left: $sizeWidth/2 solid transparent;
border-right: $sizeWidth/2 solid transparent;
}
&.disabled{
.top{
@extend .top;
border-bottom-color: $disabledColor;
}
.middle{
background: $disabledColor;
}
.bottom{
border-top-color: $disabledColor;
}
}
&-row{
clear: left;
&.even {
margin-left: ($sizeWidth/2)+1;
}
}
}

+ 77
- 0
server.js View File

@ -0,0 +1,77 @@
var express = require('express');
var http = require('http');
var io = require('socket.io');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var app = express();
app.use(express.static('./public'));
//Specifying the public folder of the server to make the html accesible using the static middleware
app.use(cookieParser());
var jsonParser = bodyParser.json()
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })
// POST /login gets urlencoded bodies
function findSocketByCookie(cookie) {
for(var i in io.sockets.connected) {
var socket = io.sockets.connected[i];
if(socket.handshake.headers.cookie.indexOf(cookie) !== -1){
return socket;
}
}
}
app.post('/show', urlencodedParser, function (req, res) {
res.sendStatus(200);
console.log("Sending json to live interfaces...");
// console.dir(io.sockets.connected);
for(var i in io.sockets.connected) {
var socket = io.sockets.connected[i];
socket.emit("jsonHoneycomb", req.body.honeyComb);
}
// var socket = findSocketByCookie(req.cookies.myUniqueCookie);
});
var server = http.createServer(app).listen(8080);
console.log("Listening on port 8080");
console.log("Send jsons to /show please.");
//Server listens on the port 8124
var io = io.listen(server);
/*initializing the websockets communication , server instance has to be sent as the argument */
io.sockets.on('connection', function(socket){
console.log("New Client Connected.");
socket.on('disconnect', function () {
console.log("Client disconnected.")
});
socket.on('ackMessage', function(msg){
if(msg == "true"){
console.log('Message received.');
}
});
socket.on('liveMessage', function(msg){
if(msg == "true"){
console.log('Live interface connected.');
}
});
socket.on('jsonToParse', function(msg){
if(msg == "true"){
console.log('Json received.');
socket.emit("jsonHoneycomb", msg);
}
});
});

Loading…
Cancel
Save