a hella lotta stuff

This commit is contained in:
Nicky Case 2018-04-03 13:32:26 -04:00
parent ea1958bf5c
commit cf4ba999e0
13 changed files with 541 additions and 89 deletions

View File

@ -19,6 +19,9 @@ body{
width: 100%;
height: calc(100% - 60px);
}
#container[sim_is_running]{
background: #eee;
}
#container > div{
position: absolute;
width: 100%; height: 100%;
@ -44,7 +47,8 @@ body{
background-size: 100% 100%;
}
#slideshow .next_button{
margin: 0 auto;
display: inline-block;
/*margin: 0 auto;*/
position: relative;
top: -10px;
width: 300px;
@ -58,7 +62,9 @@ body{
background-position: 0 -100px;
}
.transitionable{
transition: opacity 0.3s ease-in-out;
transition: opacity 0.3s ease-in-out,
left 0.3s ease-in-out,
top 0.3s ease-in-out;
}
#scratch{
display: none;
@ -68,7 +74,31 @@ body{
background-position: 0% 0%;
}
.sim_button{
position: absolute;
width: 200px;
height: 100px;
border: none !important;
}
.sim_button > div{
position: absolute;
background: #dd4040;
color: #fff;
text-align: center;
border-radius: 10px;
}
.sim_button > #reset_button{
width: 150px;
left:25px;
top:0px;
font-size: 0.8em;
transition: top 0.3s ease-in-out;
}
.sim_button > #start_button{
width: 200px;
padding: 0.5em 0;
}
.sim_button[active] > #reset_button{
top:60px;
}
/* MODAL */

View File

@ -153,13 +153,56 @@ blah blah post-puzzle
<!-- 2. Simple Contagions -->
<words id="_2_simple">
blah blah simple
</words>
<words id="_2_simple_end">
<next wiggle>next</next>
</words>
<words id="_2_cascade">
blah blah simple cascade
</words>
<words id="_2_cascade_end">
<next wiggle>onwards...</next>
</words>
<!-- 3. Complex Contagions -->
<words id="_3_complex">
blah blah complex vs simple
</words>
<words id="_3_complex_end">
herp derp blah blah
<next wiggle>next</next>
</words>
<words id="_3_cascade">
blah blah complex cascade
</words>
<words id="_3_cascade_end">
<next wiggle>fweeee</next>
</words>
<words id="_3_prevent">
blah blah complex prevention
</words>
<words id="_3_prevent_end">
herp derp blah blah
<next wiggle>next</next>
</words>
<!-- 4. Bonding & Bridging -->
<!-- 5. Sandbox -->
<!-- 6. Conclusion -->
<!-- recap and CONCRETE LIFE TAKE-AWAYS. mirror intro UI -->
<!-- 7. Credits -->
@ -168,13 +211,13 @@ blah blah post-puzzle
WIN
</words>
<words id="sim_start">
&gt; start sim
&gt; start
</words>
<words id="sim_next">
&gt;&gt; next
</words>
<words id="sim_reset">
reset sim
&olarr; reset
</words>
<!-- - - - - - - - - - - - - -->

View File

@ -188,7 +188,6 @@ SLIDES.push(
],
// Logic to fade in/out words & stuff
onupdate:function(slideshow, state){
// Win only if EVERYONE hits threshold

View File

@ -6,9 +6,9 @@ var CONTAGION_PUZZLE = {
"connections":[[0,1],[1,3],[3,2],[3,7],[7,8],[8,6],[6,4],[4,2],[6,5],[5,9]]
};
var CASCADE_PUZZLE = {
"peeps":[[34,63,1],[171,97,0],[311,179,0],[191,240,0],[309,312,0],[542,77,0],[450,164,0],[528,264,0],[654,229,0],[661,117,0],[869,295,0],[720,337,0],[926,428,0],[845,508,0],[706,464,0]],
"connections":[[0,1],[3,2],[2,4],[4,3],[6,7],[7,8],[8,9],[9,5],[5,6],[6,9],[9,7],[7,5],[5,8],[8,6],[11,10],[11,14],[14,13],[13,12],[12,10],[11,12],[12,14],[14,10],[10,13],[13,11]]
};
"peeps":[[31,201,1],[148,238,0],[267,317,0],[166,392,0],[282,437,0],[481,202,0],[401,284,0],[472,367,0],[590,340,0],[602,236,0],[843,313,0],[719,376,0],[930,413,0],[846,514,0],[728,488,0]],
"connections":[[0,1,1],[3,2,1],[2,4,1],[4,3,1],[6,7,1],[7,8,1],[8,9,1],[9,5,1],[5,6,1],[6,9,1],[9,7,1],[7,5,1],[5,8,1],[8,6,1],[11,10,1],[11,14,1],[14,13,1],[13,12,1],[12,10,1],[11,12,1],[12,14,1],[14,10,1],[10,13,1],[13,11,1]]
}
SLIDES.push(
{
@ -17,6 +17,13 @@ SLIDES.push(
add:[
// Intro text
{
type:"box",
text:"_2_simple",
x:0, y:0, w:350, h:200
},
// Lil' contagion
{
type:"sim",
@ -36,11 +43,38 @@ SLIDES.push(
// UI for the simulation
{
type:"box",
x:380, y:180,
x:380, y:165,
sim_button:"red"
},
]
// Outro text
{
id:"end",
type:"box",
text:"_2_simple_end",
x:660, y:440, w:300, h:100,
hidden:true
}
],
onupdate:function(slideshow, state){
// Show end if EVERYONE is infected
if(!state.ended){
var sim = slideshow.simulations.sims[0];
var peepCount = 0;
sim.peeps.forEach(function(peep){
if(peep.infected) peepCount++;
});
if(peepCount==sim.peeps.length){
var boxes = slideshow.boxes;
boxes.showChildByID("end", true);
state.ended = true;
}
}
}
},
{
@ -49,10 +83,10 @@ SLIDES.push(
add:[
// Lil' contagion
// Sim
{
type:"sim",
x:0, y:0,
x:0, y:-140,
fullscreen: true,
network: {
"contagion":0,
@ -66,7 +100,49 @@ SLIDES.push(
}
},
]
// UI for the simulation
{
type:"box",
x:380, y:290,
sim_button:"red"
},
// Intro text
{
type:"box",
text:"_2_cascade",
x:0, y:400, w:600, h:140
},
// End text
{
id:"end",
type:"box",
text:"_2_cascade_end",
x:660, y:440, w:300, h:100,
hidden:true
},
],
onupdate:function(slideshow, state){
// Show end if EVERYONE is infected
if(!state.ended){
var sim = slideshow.simulations.sims[0];
var peepCount = 0;
sim.peeps.forEach(function(peep){
if(peep.infected) peepCount++;
});
if(peepCount==sim.peeps.length){
var boxes = slideshow.boxes;
boxes.showChildByID("end", true);
state.ended = true;
sim.win();
}
}
}
},
);

View File

@ -1,11 +1,156 @@
// 3 - Complex Contagion
SLIDES.push(
{
chapter: "Complex",
clear:true,
add:[
// Intro text
{
type:"box",
text:"_3_complex",
x:0, y:0, w:360, h:370
},
// Sim
{
type:"sim",
x:0, y:0,
fullscreen: true,
network: {
"contagion":0.25,
"peeps":[[432,144,1],[438,410,1],[636,139,0],[638,414,0],[789,68,0],[916,101,0],[855,195,0],[798,320,0],[887,346,0],[917,445,0],[840,503,0]],
"connections":[[0,2,0],[2,4,0],[2,5,0],[6,2,0],[1,3,0],[3,10,0],[3,7,0],[8,3,0],[9,3,0]]
},
options:{
infectedFrame: 3,
scale: 1.25
}
},
// UI for the simulation
{
type:"box",
x:440, y:225,
sim_button:"red"
},
// End text
{
id:"end",
type:"box",
text:"_3_complex_end",
x:0, y:370, w:360, h:170, align:"right",
hidden:true
},
],
onupdate:function(slideshow, state){
// Show end if at least 5 infected
if(!state.ended){
var sim = slideshow.simulations.sims[0];
var peepCount = 0;
sim.peeps.forEach(function(peep){
if(peep.infected) peepCount++;
});
if(peepCount>=5){
var boxes = slideshow.boxes;
boxes.showChildByID("end", true);
state.ended = true;
}
}
}
},
{
chapter: "Complex-Cascade",
clear:true,
add:[
// Sim
{
type:"sim",
x:0, y:-140,
fullscreen: true,
network: {
"contagion":0.25,
"peeps":CASCADE_PUZZLE.peeps,
"connections":CASCADE_PUZZLE.connections
},
options:{
infectedFrame: 3,
scale: 1.25,
startUncuttable: true
}
},
// UI for the simulation
{
type:"box",
x:380, y:290,
sim_button:"red"
},
// Intro text
{
type:"box",
text:"_3_cascade",
x:0, y:400, w:600, h:140
},
// End text
{
id:"end",
type:"box",
text:"_3_cascade_end",
x:660, y:440, w:300, h:100,
hidden:true
},
],
onupdate:function(slideshow, state){
// Show end if EVERYONE is infected
if(!state.ended){
var sim = slideshow.simulations.sims[0];
var peepCount = 0;
sim.peeps.forEach(function(peep){
if(peep.infected) peepCount++;
});
if(peepCount==sim.peeps.length){
var boxes = slideshow.boxes;
boxes.showChildByID("end", true);
state.ended = true;
sim.win();
}
}
}
},
{
chapter: "Complex-Prevent",
clear:true,
add:[
// Intro text
{
type:"box",
text:"_3_prevent",
x:0, y:0, w:350, h:200
},
// Lil' contagion
{
type:"sim",
@ -22,31 +167,71 @@ SLIDES.push(
startUncuttable: true
}
},
]
},
{
chapter: "Complex-Cascade",
clear:true,
add:[
// Lil' contagion
// UI for the simulation
{
type:"sim",
x:0, y:0,
fullscreen: true,
network: {
"contagion":0,
"peeps":CASCADE_PUZZLE.peeps,
"connections":CASCADE_PUZZLE.connections
},
options:{
infectedFrame: 3,
scale: 1.25,
startUncuttable: true
}
type:"box",
x:380, y:140,
sim_button:"red"
},
]
},
// Outro text
{
id:"end",
type:"box",
text:"_3_prevent_end",
x:660, y:440, w:300, h:100,
hidden:true
}
],
onupdate:function(slideshow, state){
// Show end if sim is running AND no one left to infect
// that is, it's stalled... YAY!
var sim = slideshow.simulations.sims[0];
if(!state.ended){
if(Simulations.IS_RUNNING){
// if it's a new step...
if(sim.STEP > state.lastStep){
// ...but the infected count is the same as last step
var countInfected = 0;
sim.peeps.forEach(function(peep){ if(peep.infected) countInfected++; });
if(state.lastInfected == countInfected){
// oh, and it's NOT coz ALL of 'em are infected
if(countInfected!=sim.peeps.length){
// WIN
var boxes = slideshow.boxes;
setTimeout(function(){
boxes.showChildByID("end", true);
state.ended = true;
sim.win();
},500);
}
}else{
state.lastInfected = countInfected;
}
}
state.lastStep = sim.STEP;
}else{
state.lastStep = 0;
state.lastInfected = 1;
}
}
}
}
);

View File

@ -1,6 +1,80 @@
// 0 - INTRODUCTION
SLIDES.push(
{
chapter: "BB"
}
chapter: "BB",
clear:true,
add:[
// Sim
{
type:"sim",
x:0, y:130,
fullscreen: true,
network: {
"contagion":0.25,
"peeps":[[92,52,1],[178,54,0],[25,131,0],[83,213,0],[174,213,0],[233,135,0],[421,50,1],[365,141,0],[423,230,0],[527,228,0],[586,135,0],[522,54,0],[772,50,1],[711,128,0],[770,211,0],[864,210,0],[933,126,0],[858,52,0]],
"connections":[[13,12,0],[12,17,0],[16,15,0],[15,14,0],[14,13,0],[13,16,0],[16,14,0],[14,17,0],[17,15,0],[15,12,0],[12,16,0],[15,13,0],[17,16,0],[14,12,0],[13,17,0],[0,1,0],[2,5,0],[4,3,0]]
},
options:{
infectedFrame: 3,
scale: 1
}
},
]
},
{
chapter: "BB-Bridge",
clear:true,
add:[
// Sim
{
type:"sim",
x:0, y:0,
fullscreen: true,
network: {
"contagion":0.25,
"peeps":[[314,58,1],[418,87,0],[234,139,0],[277,234,0],[386,264,0],[460,180,0],[538,390,0],[617,309,0],[719,333,0],[766,432,0],[680,514,0],[572,491,0]],
"connections":[[7,6,0],[6,11,0],[11,10,0],[9,8,0],[8,7,0],[6,10,0],[6,9,0],[9,11,0],[11,7,0],[7,10,0],[9,7,0],[8,10,0],[10,9,0],[6,8,0],[8,11,0],[0,1,0],[2,5,0],[4,3,0]]
},
options:{
infectedFrame: 3,
scale: 1,
startUncuttable: true
}
},
]
},
{
chapter: "BB-Both",
clear:true,
add:[
// Sim
// use a DRAWING to impose SOFT CONSTRAINTS
{
type:"sim",
x:0, y:0,
fullscreen: true,
network: {
"contagion":0.25,
"peeps":[[474,46,1],[578,100,0],[388,94,0],[568,195,0],[392,190,0],[486,233,0],[273,318,0],[183,363,0],[183,447,0],[256,498,0],[355,376,0],[347,469,0],[630,367,0],[696,308,0],[791,360,0],[784,442,0],[725,495,0],[637,450,0]],
"connections":[]
},
options:{
infectedFrame: 3,
scale: 1,
startUncuttable: true
}
},
]
},
);

View File

@ -57,7 +57,8 @@ function removeFromArray(array, item){
function fadeIn(container, dom){
dom.style.opacity = 0;
dom.classList.add("transitionable");
container.appendChild(dom);
dom.style.display = "block";
if(!container.contains(dom)) container.appendChild(dom);
setTimeout(function(){
dom.style.opacity = 1;
},50);
@ -66,7 +67,7 @@ function fadeOut(container, dom){
dom.classList.add("transitionable");
dom.style.opacity = 0;
setTimeout(function(){
container.removeChild(dom);
if(container.contains(dom)) container.removeChild(dom);
},300);
}

View File

@ -28,6 +28,6 @@ window.onload = function(){
window.requestAnimationFrame(update);
// First slide!
slideshow.gotoChapter("Simple");
slideshow.gotoChapter("BB-Both");
}

View File

@ -16,40 +16,51 @@ function ConnectorCutter(config){
var mouse = self.sim.mouse;
// JUST CLICKED, and state=0... can either start connecting or cutting!
if(mouse.justPressed && self.state===0){
// Clicked on a peep?
var peepClicked = self.sim.getHoveredPeep(0);
if(peepClicked){
self.state = 1; // START CONNECTING
self.connectFrom = peepClicked;
}else{
self.state = 2; // START ERASING
}
// only if sim is NOT RUNNING
if(!Simulations.IS_RUNNING){
}
// JUST RELEASED, and state!=0... can either stop connecting or cutting!
if(mouse.justReleased && self.state!==0){
// End connect?
if(self.state==1){
var peepReleased = self.sim.getHoveredPeep(20);
if(peepReleased){
self.sim.addConnection(self.connectFrom, peepReleased);
// JUST CLICKED, and state=0... can either start connecting or cutting!
if(mouse.justPressed && self.state===0){
// Clicked on a peep?
var peepClicked = self.sim.getHoveredPeep(0);
if(peepClicked){
self.state = 1; // START CONNECTING
self.connectFrom = peepClicked;
}else{
self.state = 2; // START ERASING
}
}
// back to normal
self.state = 0;
// JUST RELEASED, and state!=0... can either stop connecting or cutting!
if(mouse.justReleased && self.state!==0){
// End connect?
if(self.state==1){
var peepReleased = self.sim.getHoveredPeep(20);
if(peepReleased){
self.sim.addConnection(self.connectFrom, peepReleased);
}
}
// back to normal
self.state = 0;
}
}else{
self.state = 0;
}
// In "NORMAL" state... tell Pencil what frame to go to
if(self.state==0){
var peepHovered = self.sim.getHoveredPeep(0);
pencil.gotoFrame( peepHovered ? 1 : 0 );
if(!Simulations.IS_RUNNING){
var peepHovered = self.sim.getHoveredPeep(0);
pencil.gotoFrame( peepHovered ? 1 : 0 );
}else{
pencil.gotoFrame(0);
}
}
// In "CONNECTING" state... show where to connect to

View File

@ -135,8 +135,8 @@ function Peep(config){
ctx.save();
var bgColor = "#eee";
var uiColor = "#666";
var bgColor = "#ddd";
var uiColor = "#333";
// Say: Infected/Friends (% then n/n)
ctx.translate(0,-43);

View File

@ -15,11 +15,16 @@ function Simulations(){
// Clear All Sims
self.clear = function(){
Simulations.IS_RUNNING = false;
$("#container").removeAttribute("sim_is_running");
self.sims.forEach(function(sim){
self.dom.removeChild(sim.canvas);
sim.kill();
});
self.sims = [];
};
// Add Sims
@ -49,18 +54,27 @@ function Simulations(){
// SIMULATION RUNNING //
////////////////////////
subscribe("sim/start", function(){
Simulations.IS_RUNNING = true;
$("#container").setAttribute("sim_is_running",true);
self.sims.forEach(function(sim){
sim.save(); // save for later resetting
});
publish("sim/next");
//publish("sim/next");
});
subscribe("sim/reset", function(){
Simulations.IS_RUNNING = false;
$("#container").removeAttribute("sim_is_running");
self.sims.forEach(function(sim){
sim.reload(); // reload the network pre-sim
});
});
subscribe("sim/next", function(){
self.sims.forEach(function(sim){
@ -134,14 +148,10 @@ function Sim(config){
// Connections
self.networkConfig.connections.forEach(function(c){
var from = self.peeps[c[0]],
to = self.peeps[c[1]];
self.addConnection(from, to, false);
to = self.peeps[c[1]],
uncuttable = c[2]||false
self.addConnection(from, to, uncuttable);
});
if(self.options.startUncuttable){
self.connections.forEach(function(c){
c.uncuttable = true;
});
}
// Contagion
self.contagion = self.networkConfig.contagion;
@ -343,16 +353,22 @@ function Sim(config){
// SIMULATION RUNNING //
////////////////////////
self.STEP = 0;
self.save = function(){
self.STEP = 0;
self.networkConfig = self.getCurrentNetwork();
};
self.reload = function(){
self.STEP = 0;
self.init();
};
self.nextStep = function(){
self.STEP++;
// "Infect" the peeps who need to get infected
// TODO: Connection animation
self.peeps.filter(function(peep){
@ -413,7 +429,8 @@ function Sim(config){
self.connections.forEach(function(c){
var fromIndex = self.peeps.indexOf(c.from);
var toIndex = self.peeps.indexOf(c.to);
savedNetwork.connections.push([fromIndex, toIndex]);
var uncuttable = c.uncuttable ? 1 : 0;
savedNetwork.connections.push([fromIndex, toIndex, uncuttable]);
});
return savedNetwork;
};
@ -494,6 +511,13 @@ function Sim(config){
// INIT NOW //
//////////////
// Start Uncuttable?
if(self.options.startUncuttable){
self.networkConfig.connections.forEach(function(c){
c[2] = 1;
});
}
self.init();
}

View File

@ -95,9 +95,13 @@ function Boxes(){
return box.id==id;
});
};
self.showChildByID = function(id){
self.showChildByID = function(id, withFade){
var toShow = self.getChildByID(id);
toShow.style.display = "block";
if(!withFade){
toShow.style.display = "block";
}else{
fadeIn(self.dom, toShow);
}
};
self.hideChildByID = function(id){
var toHide = self.getChildByID(id);
@ -124,10 +128,11 @@ function SimButton(container, color){
self.container.classList.add("sim_button");
// RESET
var smallButton = document.createElement("div");
smallButton.innerHTML = getWords("sim_reset");
self.container.appendChild(smallButton);
smallButton.onclick = function(){
var resetButton = document.createElement("div");
resetButton.id = "reset_button";
resetButton.innerHTML = getWords("sim_reset");
self.container.appendChild(resetButton);
resetButton.onclick = function(){
if(Simulations.IS_RUNNING){
publish("sim/reset");
_updateButtonUI();
@ -135,9 +140,10 @@ function SimButton(container, color){
};
// START / NEXT
var bigButton = document.createElement("div");
self.container.appendChild(bigButton);
bigButton.onclick = function(){
var startButton = document.createElement("div");
startButton.id = "start_button";
self.container.appendChild(startButton);
startButton.onclick = function(){
if(!Simulations.IS_RUNNING){
publish("sim/start");
_updateButtonUI();
@ -149,9 +155,11 @@ function SimButton(container, color){
// Update button UI
var _updateButtonUI = function(){
if(!Simulations.IS_RUNNING){
bigButton.innerHTML = getWords("sim_start");
startButton.innerHTML = getWords("sim_start");
self.container.removeAttribute("active");
}else{
bigButton.innerHTML = getWords("sim_next");
startButton.innerHTML = getWords("sim_next");
self.container.setAttribute("active",true);
}
};
_updateButtonUI();

View File

@ -37,6 +37,7 @@ function Slideshow(){
if(slide.clear && !isFirstSlide){
_delayNewSlide = 700;
self.scratch.scratchOut(); // Scratch out
$("#container").removeAttribute("sim_is_running"); // remove that UI
}
_setTimeout(function(){