covid-19/sim/js/Controls.js

440 lines
8.8 KiB
JavaScript

/////////////////////////////////////
// PARAMETERS ///////////////////////
/////////////////////////////////////
let S,E,I,R;
let params = {};
// Update Month Ticks!
let mn = [...$('#month_names').children].map((dom)=>{
return dom.innerHTML;
});
let updateMonthTicks = ()=>{
let ticks;
switch(params.p_years){
case 0.5:
ticks = [
mn[0]+" 2020",
mn[1]+" 2020",
mn[2]+" 2020",
mn[3]+" 2020",
mn[4]+" 2020",
mn[5]+" 2020",
null
];
break;
case 1.0:
ticks = [
mn[0]+" 2020",
mn[3]+" 2020",
mn[6]+" 2020",
mn[9]+" 2020",
null
];
break;
default:
ticks = [];
for(let time=0; time<=params.p_years; time+=0.5){
if(time%1 != 0){
ticks.push(null);
}else{
ticks.push(time+2020);
}
}
ticks[ticks.length-1] = null;
break;
}
let monthTicksDOM = $('#month_ticks');
monthTicksDOM.innerHTML = '';
ticks.forEach((tick,i)=>{
if(i==ticks.length-1 || !tick) return;
let tickDOM = document.createElement('div');
let tickSpanDOM = document.createElement('span');
tickSpanDOM.innerHTML = tick;
tickDOM.style.left = ((i/(ticks.length-1))*500)+"px";
tickDOM.appendChild(tickSpanDOM);
monthTicksDOM.appendChild(tickDOM);
});
}
// Sliders
//let DONT_RECORD_HISTORY = true;
let _DO_NOT_RECURSE = true;
let INPUTS_WERE_CHANGED = false;
let yearsSlider = $('#p_years');
$all('.sim_input').forEach((slider)=>{
let id = slider.id;
let label = $('#label_'+id);
//let isRecordable = slider.classList.contains('recordable');
let onChange = ()=>{
// Change label & param
let val = parseFloat(slider.value);
if(label){
let digits = parseInt(label.getAttribute('toFixed'));
label.innerHTML = digits ? val.toFixed(digits) : val;
}
params[id] = val;
// Record history (@ this day)
/*
if(isRecordable){
if(!DONT_RECORD_HISTORY){
let lastRecordedEntry = recordedHistory[recordedHistory.length-1];
if(!lastRecordedEntry || id!=lastRecordedEntry[0] || Math.round(daysCurrent)!=lastRecordedEntry[2]){ // not same thing/time
recordedHistory.push([id, val, Math.round(daysCurrent)]);
}
}
}
*/
// Just to update other random crap
if(!_DO_NOT_RECURSE){
_DO_NOT_RECURSE = true;
updateModel(1, true); // one day
_DO_NOT_RECURSE = false;
}
// HACK: If this is years, RESET SIM & CHANGE THE MONTHS
if(slider==yearsSlider){
if(daysCurrent>0){
_resetTheSim();
_updateButtons();
}
updateMonthTicks();
}
// MORE HAX
/*
if(daysCurrent==0){
sbDOM.setAttribute('label','params');
}
*/
// HAX
INPUTS_WERE_CHANGED = true;
};
slider.oninput = onChange;
onChange();
});
//DONT_RECORD_HISTORY = false;
_DO_NOT_RECURSE = false;
// Checkboxes
$all('.sim_checkbox').forEach((checkbox)=>{
let id = checkbox.id;
let label = $('#label_'+id);
let onChange = ()=>{
if(label){
if(!checkbox.checked){
label.setAttribute("strikethrough","yes");
}else{
label.removeAttribute("strikethrough");
}
}
params[id] = checkbox.checked;
};
checkbox.oninput = onChange;
onChange();
});
/////////////////////////////////////
// (RE)START ////////////////////////
/////////////////////////////////////
let IS_PLAYING = false;
//let recordedHistory = [];
//let IS_REPLAYING_HISTORY = false;
let START_S = 0.999,
START_E = 0.001,
START_I = 0.001,
START_R = 0.000;
let restart = ()=>{
// Model
S = START_S;
E = START_E;
I = START_I;
R = START_R;
// Drawing
daysCurrent = 0;
daysDrawn = 0;
daysTotal = params.p_years*365;
daysPerFrame = 0; // calc it on the fly
let ctx = context;
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0,0,canvas.width,canvas.height);
// Force refresh DOM
s_dom.oninput();
};
/////////////////////////////////////
// BIG & SMALL BUTTONS //////////////
/////////////////////////////////////
let bbDOM = $('.big_button');
//let sbDOM = $('.small_button');
let handTutorial = 0;
bbDOM.onclick = ()=>{
if(CURRENT_STAGE.SHOW_HAND=="tutorial_0"){
if(handTutorial==0){
hideHand();
handTutorial = 1;
}else if(handTutorial==1){
hideHand();
}else if(handTutorial==2){
hideHand();
setTimeout(()=>{
showHand('end');
},1);
handTutorial = 3;
}
}
if(CURRENT_STAGE.SHOW_HAND=="tutorial_1"){
if(handTutorial==0){
hideHand();
handTutorial = 1;
}else if(handTutorial==1){
hideHand();
handTutorial = 2;
}
}
if(CURRENT_STAGE.SHOW_HAND=="tutorial_2"){
if(handTutorial==0){
hideHand();
handTutorial = 1;
}
}
if(daysCurrent>daysTotal || params._HACK_RESET_WHEN_I_100=="go" || params._HACK_RESET_WHEN_R_100=="go"){
_resetTheSim();
params._HACK_RESET_WHEN_I_100 = undefined;
params._HACK_RESET_WHEN_R_100 = undefined;
if(CURRENT_STAGE.SHOW_HAND=="tutorial_0" && handTutorial<=1){
setTimeout(()=>{
showHand('params');
},1000);
handTutorial = 2;
}
}else{
if(daysCurrent==0){
restart();
}
IS_PLAYING = !IS_PLAYING;
}
_updateButtons();
};
let defaultParams = [
["p_transmission", 4],
["p_exposed", 3],
["p_recovery", 10],
["p_waning", 1],
["p_hospital", 333],
["p_years", 2],
["p_speed", 30],
["p_non_s", 0],
["p_hygiene", 0],
["p_distancing", 0],
["p_isolate", 0],
["p_quarantine", 0],
["p_masks", 0],
["p_summer", 0],
];
let _resetAll = ()=>{
changeSliders(defaultParams);
changeSliders(CURRENT_STAGE.inputs);
_resetTheSim();
};
$('#sb_reset').onclick = ()=>{
_resetAll();
_updateButtons();
};
$('#sb_replay').onclick = ()=>{
_resetAll();
recordedHistory = JSON.parse(JSON.stringify(CURRENT_STAGE.PLAY_RECORDING));
_updateButtons();
restart();
IS_PLAYING = true;
};
/*
sbDOM.onclick = ()=>{
if(daysCurrent==0){
changeSliders(defaultParams);
changeSliders(CURRENT_STAGE.inputs);
}else if(daysCurrent>daysTotal){
//_replayTheSim();
}else{
_resetTheSim();
}
_updateButtons();
};
*/
let _updateButtons = ()=>{
if(daysCurrent > daysTotal){
bbDOM.setAttribute('label','reset');
//sbDOM.setAttribute('label','');
}else if(IS_PLAYING){
bbDOM.setAttribute('label','pause');
$('#sb_reset').style.display = 'block';
if(CURRENT_STAGE.PLAY_RECORDING){
$('#sb_replay').style.display = 'block';
}
//sbDOM.setAttribute('label','reset');
}else{
if(daysCurrent==0){
bbDOM.setAttribute('label','start');
//sbDOM.setAttribute('label','NONE');
}else{
bbDOM.setAttribute('label','continue');
//sbDOM.setAttribute('label','reset');
}
}
};
let hofp = $('#hide_on_first_playthrough');
let _showAllControls = ()=>{
let originalHeight = hofp.getBoundingClientRect().height;
if(originalHeight>0) return;
hofp.style.height = "auto";
hofp.style.position = "absolute";
hofp.style.top = "-1000px";
setTimeout(()=>{
let newHeight = hofp.getBoundingClientRect().height + 10;
hofp.style.position = "";
hofp.style.top = "";
hofp.style.height = originalHeight+"px";
setTimeout(()=>{
hofp.style.marginTop = "";
hofp.style.height = newHeight+"px";
},20);
},20);
};
let _hideAllControls = ()=>{
hofp.style.height = "0px";
};
let _resetTheSim = ()=>{
_showAllControls();
//IS_REPLAYING_HISTORY = false;
recordedHistory = [];
restart();
IS_PLAYING = false;
};
/*
let _replayTheSim = ()=>{
_hideAllControls();
//IS_REPLAYING_HISTORY = true;
restart();
IS_PLAYING = true;
};
*/
/////////////////////////////////////
// THE HAND /////////////////////////
/////////////////////////////////////
let pointerDOM = $('#pointer');
let handDOM = $('#hand_container');
let wordsDOM = $('#pointer_words');
let HAND_IS_VISIBLE = false;
let showHand = (position)=>{
HAND_IS_VISIBLE = true;
pointerDOM.style.display = 'block';
$all('span',pointerDOM).forEach((span)=>{
span.style.display = 'none';
});
switch(position){
case 'start':
handDOM.style.top = '111px';
handDOM.style.left = '98px';
break;
case 'params': case 'params2':
handDOM.style.top = '100px';
handDOM.style.left = '280px';
handDOM.style.transform = 'rotate(270deg)';
wordsDOM.style.top = '117px';
wordsDOM.style.left = '377px';
wordsDOM.style.textAlign = 'left';
$('#pointer_params').style.display = 'inline';
$('#pointer_params_2').style.display = (position=='params2') ? 'inline' : 'none';
break;
case 'end':
handDOM.style.top = '445px';
handDOM.style.left = '101px';
handDOM.style.transform = 'rotate(180deg) scaleX(-1)';
wordsDOM.style.top = '363px';
wordsDOM.style.left = '17px';
wordsDOM.style.textAlign = 'center';
$('#pointer_scroll').style.display = 'inline';
break;
case 'recording':
handDOM.style.top = '300px';
handDOM.style.left = '280px';
handDOM.style.transform = 'rotate(270deg)';
wordsDOM.style.top = '317px';
wordsDOM.style.left = '377px';
wordsDOM.style.textAlign = 'left';
$('#pointer_replay').style.display = 'inline';
break;
}
};
let hideHand = ()=>{
HAND_IS_VISIBLE = false;
pointerDOM.style.display = 'none';
};