xxxxxxxxxx
463
/*
stuff to add:
- ADD GRID TO SELECTED BOX
- undo pop-ups / history?
- visual layout:
- fonts
- grid aesthetics
- sizing
- SHOULD GRID IMMEDIATELY CLOCK OR ADD TO QUEUE??
bug fixes:
- make it zoom correctly on phone
- make separate version for android with double tap disabled
*/
// colors
const orange=[232,94,2], navy=[35,53,65], presscol=[55,73,85], gridpress=[95,108,117], butcol = [50,68,80], lgrey = 180, dgrey=140, grey3 = 229;
// orange[0],orange[1],orange[2] // navy[0],navy[1],navy[2] // presscol[0],presscol[1],presscol[2] // gridpress[0],gridpress[1],gridpress[2] // butcol[0],butcol[1],butcol[2] //
// define mode, true = chatmode, false = gridmode
let mode = true;
let times = [];
let grid = [];
let gridbotx, gridboty;
let dashY, numpadY;
const cwidth = 375, cheight = 727;
const chatmarg = 8,chatheight=50,chatY=cheight-365;
const buttonmarg = 8;
const swapY = chatY + chatheight + chatmarg + buttonmarg, swapheight = 50;
const plusY = swapY + swapheight + buttonmarg, plusheight = 50;
const recordY = plusY + plusheight + buttonmarg, recordwidth = 100;
const topheight = 69, gridbutwidth = 87;
const butwidth = (cwidth-recordwidth-buttonmarg*3)/3, butheight = 72;
const butx1 = buttonmarg,butx2=butx1+butwidth,butx3=butx2+butwidth,buty1=chatY + chatheight + chatmarg + buttonmarg,buty2=buty1+butheight,buty3=buty2+butheight,buty4=buty3+butheight;
const numbers = [[butx2,buty4],[butx1,buty1],[butx2,buty1],[butx3,buty1],[butx1,buty2],[butx2,buty2],[butx3,buty2],[butx1,buty3],[butx2,buty3],[butx3,buty3]];
let press = -1;
let selection = -1;
let typing = "";
let queue = [];
let swapping = false;
const timesmarg = 50, timeswidth = 100, timesheight = 30, timesX = cwidth - timeswidth - buttonmarg, timesY = chatY;
function setup() {
createCanvas(cwidth, cheight);
createButton("switch mode").mousePressed(switchMode);
createButton("export time").mousePressed(exportTimes);
for(i=101;i<130;i++){
grid.push([i,true])
}
// canvas dependent variables
gridbotx = 15;
gridboty = height - 80;
dashY = height - 375;
numpadY = dashY + chatmarg*2 + chatheight;
}
function draw() {
background(255);
noStroke();
fill(220);
//rect(0,dashY,width,height-dashY);
fill(navy[0],navy[1],navy[2]);
if(mode){
rect(0,numpadY,width,height-numpadY);
}
else{
rect(width-recordwidth-buttonmarg*2,numpadY,recordwidth + buttonmarg*2,height-numpadY);
}
// draw buttons
noStroke();
if(mode){
for(i=0;i<numbers.length;i++){
fill(presscol[0],presscol[1],presscol[2]);
if(press==i){
rect(numbers[i][0],numbers[i][1],butwidth,butheight);
}
fill(255);
text(i,numbers[i][0]+butwidth/2-5,numbers[i][1]+butheight/2)
}
}
else{
for(i=0;i<grid.length;i++){
if(grid[i][1]){fill(butcol[0], butcol[1], butcol[2]);}
else{fill(gridpress[0],gridpress[1],gridpress[2])}
rect(gridbotx + (i%3) * butwidth - buttonmarg/2, gridboty - Math.trunc(i/3) * butheight +buttonmarg/2,butwidth - buttonmarg, butheight - buttonmarg,15);
fill(255);
text(grid[i][0], gridbotx + (i%3) * butwidth + 25, gridboty - Math.trunc(i/3) * butheight + 30)
}
}
// draw other buttons
if(mode){
fill(butcol[0],butcol[1],butcol[2]);
if(press=="<-"){fill(presscol[0],presscol[1],presscol[2]);}
rect(butx3+buttonmarg/2,buty4+buttonmarg/2,butwidth-buttonmarg,butheight-buttonmarg,15);
fill(butcol[0],butcol[1],butcol[2]);
if(press=="clear"){fill(presscol[0],presscol[1],presscol[2]);}
rect(butx1+buttonmarg/2,buty4+buttonmarg/2,butwidth-buttonmarg,butheight-buttonmarg,15);
}
fill(butcol[0],butcol[1],butcol[2]);
if(press=="swap"){fill(presscol[0],presscol[1],presscol[2]);}
rect(width-buttonmarg-recordwidth,swapY,recordwidth,swapheight,15);
fill(butcol[0],butcol[1],butcol[2]);
if(press=="+"){fill(presscol[0],presscol[1],presscol[2]);}
rect(width-buttonmarg-recordwidth,plusY,recordwidth,plusheight,15);
fill(orange[0],orange[1],orange[2]);
if(press=="record"){fill(orange[0]+20,orange[1]+20,orange[2]+20);}
rect(width-buttonmarg-recordwidth,recordY,recordwidth,height-recordY-buttonmarg,15);
fill(255);
if(mode){
text("<-",butx3+butwidth/2-5,buty4+butheight/2);
text("Clear",butx1+butwidth/2-14,buty4+butheight/2+3);
}
text("swap racer", width-buttonmarg-recordwidth+20,swapY+30);
text("+ racer", width-buttonmarg-recordwidth+20,plusY+30);
text("record", width-buttonmarg-recordwidth+35,recordY+80);
// draw chatbox
if(selection == -1){
strokeWeight(4);
stroke(orange[0],orange[1],orange[2]);
}
else{
strokeWeight(2);
stroke(180);
}
fill(255);
if(mode){
rect(chatmarg,chatY,width-2*chatmarg,chatheight,5);}
else{rect(width-buttonmarg-recordwidth, chatY, recordwidth, chatheight,5);}
noStroke()
fill(100);
text(hour()+":"+minute()+":"+second()+"."+Math.round(millis()/100)%10,width-chatmarg-70,chatY+30);
fill(0);
let chatbuffer = 0;
for(i=0;i<queue.length;i++){
stroke(180);
strokeWeight(2);
line(chatmarg*2 + chatbuffer*50+45, chatY+10, chatmarg*2+chatbuffer*50+45, chatY+chatheight-10);
noStroke();
text(queue[i],chatmarg*3 + chatbuffer*50, chatY+30);
chatbuffer++
}
text(typing,chatmarg*3 + chatbuffer*50,chatY+30);
// draw times
let buffer = 0;
for(i=times.length-1;i>-1;i--){
let curry = timesY - timesmarg * (times.length-i) - buffer*0.5*timesheight;
let curheight = timesheight;
for(j=2;j<times[i].length;j++){
buffer++;
curheight += 0.5*timesheight;
curry -= 0.5*timesheight;
}
// console.log(buffer);
fill(255);
let currx = timesX;
if(selection == i){
strokeWeight(4);
stroke(orange[0],orange[1],orange[2]);
if(swapping){
currx -= 50;
}
}
else{
strokeWeight(1);
stroke(180);
}
rect(currx, curry, timeswidth, curheight,5);
noStroke();
for(j=2;j<times[i].length;j++){
fill(180);
text(times[i][j], currx + 10, curry + 20);
stroke(180);
strokeWeight(1);
line(currx+10, curry+20, currx + 30, curry+10)
noStroke();
curry += 0.5*timesheight;
}
if(selection==i && times[i][0].length==3){
fill(180);
}
else{
fill(0);
}
text(times[i][0], currx + 10, curry + 20);
fill(120);
text(times[i][1], currx + 40, curry + 20);
}
// draw top bar
fill(orange[0],orange[1],orange[2]);
rect(0,0,width,topheight);
stroke(255); fill(255);
strokeWeight(4);
const arrowmarg= 20, caplength = 13;
line(arrowmarg,topheight/2,45,topheight/2); line(arrowmarg,topheight/2,arrowmarg+caplength,topheight/2 - caplength); line(arrowmarg,topheight/2,arrowmarg+caplength,topheight/2 + caplength);
strokeWeight(2);
const lineX=78, lineY=28, linelength=178;
line(lineX,lineY,lineX+linelength,lineY);
line(lineX+linelength/2,lineY,lineX+linelength/2,lineY-15);
circle(lineX,lineY,8); circle(lineX+linelength/2,lineY,8); circle(lineX+linelength,lineY,8);
triangle(lineX+linelength/2,lineY-15,lineX+linelength/2,lineY-11,lineX+linelength/2+4,lineY-13)
noStroke();
const textY = 48;
text("incoming",lineX-5, textY); text("passed",lineX+linelength-textWidth("passed")+5,textY);
text(grid.length-times.length + " / " + times.length,lineX+linelength/2-textWidth(grid.length-times.length + " /"),textY);
if(press=="grid"){fill(lgrey);} else{fill(grey3);}
rect(width-gridbutwidth,0,gridbutwidth,topheight);
fill(0);
let textheight=16;
text("Change to",width-gridbutwidth+15,5+textheight);
if(mode && press!="grid" || mode==false&&press=="grid"){text("Grid",width-gridbutwidth+33,5+textheight*2);} else{text("Chat",width-gridbutwidth+33,5+textheight*2);}
text("Mode",width-gridbutwidth+30,5+textheight*3);
}
function mousePressed(){
// enable only for chrome on android:
// if (event.type == 'touchstart'){
// GRID FUNCTION
if(mode == false){
for(i=0;i<grid.length;i++){
let xx = gridbotx + (i%3) * butwidth - buttonmarg/2, yy = gridboty - Math.trunc(i/3) * butheight+buttonmarg/2
if(mouseX>xx && mouseX<xx + butwidth && mouseY>yy && mouseY<yy + butheight && grid[i][1]){
press = i;
times.push([grid[i][0],hour()+":"+minute()+":"+second()+"."+Math.round(millis()/100)%10])
grid[i][1] = false;
}
}
}
// NUMPAD FUNCTION
if(mode){
for(i=0;i<numbers.length;i++){
if(mouseX>numbers[i][0] && mouseX<numbers[i][0] + butwidth && mouseY>numbers[i][1] && mouseY<numbers[i][1] + butheight && typing.length < 3){
press = i;
if(selection==-1){
typing = typing.concat(i);
}
else if(times[selection][0].length < 3){
times[selection][0] = times[selection][0].concat(i);
if(times[selection][0].length>2){
selection = -1;
}
}
else{
times[selection].push(times[selection][0]);
times[selection][0] = "".concat(i);
}
}
}
}
// BACKSPACE
if(mouseX > butx3 && mouseX < butx3 + butwidth && mouseY > buty4 && mouseY < buty4 + butheight){
press = "<-";
if(selection==-1){
if(typing.length > 0){
typing = typing.substring(0, typing.length - 1);
}
else if(queue.length > 0){
typing = queue.pop();
}
}
else{
times[selection][0] = times[selection][0].substring(0,times[selection][0].length - 1);
}
}
// rect(butx1+buttonmarg/2,buty4+buttonmarg/2,butwidth-buttonmarg,butheight-buttonmarg,15)
// CLEAR
if(mouseX > butx1 && mouseX < butx2 && mouseY > buty4 && mouseY < buty4 + butheight){
press = "clear";
if(selection==-1){
typing = "";
queue = [];
}
else{
times[selection].push(times[selection][0]);
times[selection][0] = "";
selection = -1;
}
}
// SWITCH MODE
if(mouseX > width-gridbutwidth && mouseX < width && mouseY > 0 && mouseY < topheight){
press = "grid";
if(mode){mode = false;}
else{mode=true;}
}
if(mouseX > width-buttonmarg-recordwidth && mouseX < width-buttonmarg){
// RECORD BUTTON
if(mouseY > recordY && mouseY < height-buttonmarg){
press = "record";
if(queue.length > 0){
times.push([queue[0], hour()+":"+minute()+":"+second()+"."+Math.round(millis()/100)%10]);
queue.shift();
}
else{
times.push([typing, hour()+":"+minute()+":"+second()+"."+Math.round(millis()/100)%10]);
typing = "";
}
}
// PLUS BUTTON
if(mouseY > plusY && mouseY < plusY + plusheight){
press = "+";
if(selection == -1){
queue.push(typing);
typing = "";
}
else{
times.splice(selection+1, 0, ["",times[selection][1]]);
selection++;
}
}
// SWAP BUTTON
if(mouseY > swapY && mouseY < swapY + swapheight){
press = "swap";
if(selection>-1){
if(swapping){
swapping = false;
}
else{
swapping = true;
}
}
}
}
// SELECT TIME
if(mouseX > timesX && mouseX < timesX + timeswidth){
let buffer = 0;
for(i=times.length-1;i>-1;i--){
let curry = timesY - timesmarg * (times.length-i) - buffer*0.5*timesheight;
for(j=2;j<times[i].length;j++){
buffer++;
}
if(mouseY>curry - (times[i].length - 2) * timesheight*0.5 && mouseY<curry + timesheight){
if(swapping){
times[selection].push(times[selection][0]);
times[i].push(times[i][0]);
let bibswap = times[selection][0];
times[selection][0] = times[i][0];
times[i][0] = bibswap;
selection = -1;
swapping = false;
}
else{
selection = i;
}
}
}
}
// DESELECT TIME
if(mouseX > chatmarg && mouseX < chatmarg+width-2*chatmarg && mouseY > chatY && mouseY < chatY+chatheight){
typing = "";
selection = -1;
}
if(mouseX < timesX && mouseY < chatY){
typing = "";
selection = -1;
}
// }
}
function mouseReleased(){
press = -1;
}
function switchMode(){
if(mode){mode = false;}
else{mode=true;}
}
function exportTimes(){
timetable = new p5.Table();
timetable.addColumn('bib');
timetable.addColumn('time');
for(i=0;i<times.length;i++){
let newRow = timetable.addRow();
newRow.setString('bib', times[i][0]);
newRow.setString('time', times[i][1]);
}
saveTable(timetable, 'results.csv');
}