IN THE FINISHING LAP

This commit is contained in:
Nicky Case 2018-04-15 17:24:22 -04:00
parent 29d396cd65
commit c9c7c7c333
20 changed files with 606 additions and 254 deletions

BIN
css/PatrickHand-Regular.ttf Executable file

Binary file not shown.

View File

@ -1,3 +1,13 @@
/* FONT FACE */
@font-face {
font-family: "PatrickHand";
font-style: normal;
font-weight: 400;
src: url(PatrickHand-Regular.ttf) format('truetype');
/*unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;*/
}
/* HTML & BODY */
html, body{
width:100%;
height:100%;
@ -7,9 +17,10 @@ html, body{
body{
margin:0;
font-family: "FuturaHandwritten";
font-size: 20px;
font-family: "PatrickHand";
font-size: 23px;
line-height: 1.5em;
}
/* fake bold */
b, strong{
@ -62,6 +73,7 @@ b, strong{
background-image: url(../sprites/button_large.png);
background-size: 100% auto;
text-align: center;
line-height: 25px;
}
#slideshow .next_button:hover{
background-position: 0 -100px;
@ -114,6 +126,7 @@ b, strong{
}
.sandbox_ui input[type="range"]{
width: 100%;
cursor: none;
}
.choose_one{
overflow: hidden;
@ -199,8 +212,6 @@ b, strong{
color: #222;
}
#navigation > div > span:nth-child(1){
position: relative;
top: 1px;
display: block;
}
#navigation > div > span:nth-child(2){
@ -237,7 +248,6 @@ b, strong{
color: #fff;
text-align: center;
border-radius: 20px;
font-size: 18px;
width: 220px;
padding: 6px 0;

View File

@ -51,36 +51,40 @@ Cursor is allowed to flow EVERYWHERE though...
<!-- The chapters -->
<div chapter="Introduction">
<span>0</span>
<span>0. Introduction</span>
<span>1</span>
<span>1. Introduction</span>
</div>
<div chapter="Networks">
<span>1</span>
<span>1. Connections</span>
<span>2</span>
<span>2. Connections</span>
</div>
<div chapter="Simple">
<span>2</span>
<span>2. Contagions</span>
<span>3</span>
<span>3. Contagions</span>
</div>
<div chapter="Complex">
<span>3</span>
<span>3. Complex Contagions</span>
<span>4</span>
<span>4. Complex Contagions</span>
</div>
<div chapter="BB">
<span>4</span>
<span>4. Bonding &amp; Bridging</span>
<span>5</span>
<span>5. Bonding &amp; Bridging</span>
</div>
<div chapter="SmallWorld">
<span>6</span>
<span>6. It's A Small World</span>
</div>
<div chapter="Sandbox">
<span>5</span>
<span>5. Sandbox Mode</span>
<span>7</span>
<span>7. Sandbox Mode</span>
</div>
<div chapter="Conclusion">
<span>6</span>
<span>6. In Conclusion...</span>
<span>8</span>
<span>8. In Conclusion...</span>
</div>
<div chapter="Credits">
<span>7</span>
<span>7. Credits</span>
<span>9</span>
<span>9. Credits</span>
</div>
<!-- A divider -->
@ -92,9 +96,22 @@ Cursor is allowed to flow EVERYWHERE though...
<span>Bonus Boxes! (Notes)</span>
</div>
<div modal="references">
<span style="margin-top:5px">*</span>
<span style="margin-top: 7px; font-size: 35px;">*</span>
<span>References</span>
</div>
<div modal="translations">
<span style="margin-top:5px; position:relative;"><span style="
position: absolute;
top: -8px;
left: 6px;
">A</span><span style="
position: absolute;
font-size: 16px;
top: -1px;
left: 16px;
">あ</span></span>
<span>Translations</span>
</div>
<!-- The hover bubble -->
<span id="nav_bubble">AHHHHHH</span>
@ -137,7 +154,7 @@ Cursor is allowed to flow EVERYWHERE though...
<words id="_0_intro">
<div class="circle"><span>
<br><br><br>
<br><br>
Sir Isaac Newton was pretty sure he was a smart cookie.
I mean, after inventing calculus and a theory of gravity,
@ -310,7 +327,7 @@ Cursor is allowed to flow EVERYWHERE though...
Some <i>mis</i>information. "Fake news", as the cool kids say.
And every day, that person spreads the rumor to their friends.
And they spread it to <i>their</i> friends. And so on.
<br><br>
<br>
<b>Run the simulation, step-by-step &darr;</b>
(p.s: you can't draw <i>while</i> the sim's running)
</words>
@ -345,8 +362,8 @@ Cursor is allowed to flow EVERYWHERE though...
Mr. Newton fell for such a cascade in 1720.
The world's financial institutions fell for such a cascade in 2008.
But so what? You already knew ideas spread.
However, network scientists recently found a <i>new</i>, strange kind of contagion.
And they're called...
However, network scientists have found a <i>new</i>, strange kind of contagion.
They're called...
</words>
<words id="_2_post_cascade_end">
@ -356,69 +373,71 @@ Cursor is allowed to flow EVERYWHERE though...
<!-- 3. Complex Contagions -->
<words id="_3_complex">
<span style="line-height:1.4em">
Truth may be stranger than fiction, but it doesn't sell as well.
Truth may be stranger than fiction, but it doesn't sell as well.
<br><br>
<div style="height:0.9em"></div>
<b>Simple contagions</b>, like juicy rumors or hot takes,
only need one "infected" friend to spread.
That doesn't mean the contagion <i>will</i> spread,
just that one exposure <i>can</i> be enough to spread.
This, by the way, is how <i>biological</i> contagions like viruses work.
<b>Simple contagions</b>, like juicy rumors or hot takes,
only need one "infected" friend to spread.
That doesn't mean the contagion <i>will</i> spread,
just that one exposure <i>can</i> be enough to spread.
This, by the way, is how <i>biological</i> contagions (like bacteria &amp; viruses) work.
<br><br>
<div style="height:0.9em"></div>
<b>Complex contagions</b> are weirder.
Some things -- like norms, habits and hard-to-accept ideas --
need more social encouragement.
They need not a minimum <i>number</i> of friends to spread,
but a minimum <i>percentage</i> of friends to spread!(*)
<b>Complex contagions</b> are weirder.
Some things -- like norms, habits and hard-to-accept ideas --
need more social encouragement.
They need not a minimum <i>number</i> of friends to spread,
but a minimum <i>percentage</i> of friends to spread!(*)
<br><br>
<div style="height:0.9em"></div>
<b>On the right, a person needs <i>AT LEAST 25%</i> of their friends to
adopt a complex fact (img) before they do.
Try "infecting" them all with <i>wisdom!</i> &rarr;</b>
<b>On the right, a person needs <i>AT LEAST 25%</i> of their friends to
adopt a complex fact (img) before they do.
Try "infecting" them all with <i>wisdom!</i> &rarr;</b>
</span>
</words>
<words id="_3_complex_2">
<span style="line-height:1.4em">
<b>CAUTION:</b>
just because an idea/behavior is "complex" doesn't mean it's good,
(e.g. conspiracy theories)
and just because it's "simple" doesn't mean it's bad!
(e.g. cute cat videos)
<b>CAUTION:</b>
just because an idea/behavior is "complex" doesn't mean it's good,
(e.g. conspiracy theories)
and just because it's "simple" doesn't mean it's bad!
(e.g. cute cat videos)
<br><br>
Think of it this way:
simple contagions are weeds, complex contagions are trees,
and a network is an ecosystem.
Sometimes weeds are good, sometimes trees are bad.
But if your ecosystem can <i>only</i> support weeds,
something's very wrong.
<div style="height:0.9em"></div>
Think of it this way:
simple contagions are weeds, complex contagions are trees,
and a network is an ecosystem.
Sometimes weeds are good, sometimes trees are bad.
But if your ecosystem can <i>only</i> support weeds,
something's very wrong.
<br><br>
<div style="height:0.9em"></div>
(BONUS: OTHER KINDS OF CONTAGIONS)
(BONUS: OTHER KINDS OF CONTAGIONS)
<br><br>
<div style="height:0.9em"></div>
So, how <i>do</i> we make sure our social ecosystem is healthy?
Let's revisit...
So, how <i>do</i> we make sure our social ecosystem is healthy?
Let's revisit...
<next wiggle>...the cascade puzzle!</next>
<next wiggle>...the cascade puzzle!</next>
</span>
</words>
<words id="_3_cascade">
You did this before, but now, with a <i>complex</i> contagion (img), it'll be tougher...
<br>
(note: feel free to just hit 'start' and <i>try</i> as many solutions as you want)
<br>
<b>"Infect" everyone with complex wisdom! &darr;</b>
<b>Try to "infect" everyone with complex wisdom! &darr;</b>
(feel free to just hit 'start' and <i>try</i> as many solutions as you want)
</words>
<words id="_3_cascade_end">
@ -468,14 +487,15 @@ Cursor is allowed to flow EVERYWHERE though...
The immediate cause:
it was too cold that morning.
<br><br>
<div style="height:0.9em"></div>
The less immediate cause: the managers ignored the engineers' warnings.
Why? Because of <b>groupthink</b>(*).
When a group is <i>too</i> closely knit, (as they tend to be at the top of institutions)
they become resistant to hard-to-accept information.
they become resistant to hard-to-accept information
that challenges one's beliefs or ego.
<br><br>
<div style="height:0.9em"></div>
So, that's how to get crowd madness.
But how can we "design" for crowd <i>wisdom?</i>
@ -501,7 +521,7 @@ Cursor is allowed to flow EVERYWHERE though...
</words>
<words id="bonding_end">
This is called <b>bonding social capital</b>,
This is called <b>bonding social capital</b>(*),
the strength of the connections <i>within</i> a single group.
But what about the connections...
<next wiggle>...<i>between</i> groups?</next>
@ -517,9 +537,8 @@ Cursor is allowed to flow EVERYWHERE though...
<words id="bridging_end">
Like bonding, bridging social capital has a sweet spot.
(optional challenge: draw a bridge so thick that the complex contagion
(bonus challenge: try drawing a bridge so thick that the complex contagion
<i>can't</i> pass through it!)
<br><br>
Now that we know how to "design" connections <i>within</i> and <i>between</i> groups, let's...
<next wiggle>...do BOTH. &rarr;</next>
</words>
@ -529,30 +548,62 @@ Cursor is allowed to flow EVERYWHERE though...
<b style="font-size:2em">FINAL PUZZLE!</b>
<br>
Draw connections within groups (bonding) and between groups (bridging)
<i>however</i> you want, to spread wisdom to everyone:
to spread wisdom to everyone:
</words>
<words id="bb_2">
derp derp
<next wiggle>derp derp &rarr;</next>
// "SMALL WORLD"
// e pluribus unum
// unity in diversity?
// examples
// JFK story in footnote
You just drew a very special kind of network!
Networks with high bonding and bridging
are profoundly important, and they're called...
<next wiggle>“Small World Networks” &rarr;</next>
</words>
<words id="bb_small_world">
<words id="bb_small_world_1">
<i>"Unity without uniformity". "Diversity without division". "E Pluribus Unum: out of many, one".</i>
<br>
No matter how it's phrased,
people -- across times and cultures -- have often arrived at the same piece of wisdom:
<b>
a healthy society needs both tight bonds <i>within</i> groups
and thick bridges <i>between</i> groups.
</b>
</words>
<words id="bb_small_world_2">
That is, not this...
<br>
(because ideas can't spread)
</words>
<words id="bb_small_world_3">
nor this...
<br>
(because you'll get groupthink)
</words>
<words id="bb_small_world_4">
...but <i>THIS:</i>
</words>
<words id="bb_small_world_5">
Network scientists now have a mathematical definition for this ancient wisdom:
the <b>small world network</b>(*). This optimal mix of bonding+bridging describes how
our neurons interact(*), gives rise to collective creativity and problem-solving(*),
and, at one point, has even helped us (barely) avoid full-out nuclear war!(*)
So, yeah, small worlds are a big deal.
</words>
<words id="bb_small_world_end">
And finally, if you'd like to make a whole network from scratch, let's check out...
<next>The Sandbox Mode &rarr;</next>
</words>
<!-- 5. Sandbox -->
<words id="sandbox_caption">
<b>NOTE: "Sandbox Mode" is totally optional.</b>
Feel free to skip it, or play around!(*)
When you're done, let's recap...
<b>NOTE: "Sandbox Mode" is totally optional!</b>
Feel free to skip it, or play around.(*)
Whenever you're done, let's recap...
</words>
<words id="sandbox_next">
<next>what we learnt today!</next>
@ -607,25 +658,107 @@ Cursor is allowed to flow EVERYWHERE though...
<!-- recap and CONCRETE LIFE TAKE-AWAYS. mirror intro UI -->
<words id="conclusion_1">
IN CONCLUSION:
Contagion &amp; Connections.
<next>derp</next>
<div style="font-size: 30px;">
IN CONCLUSION: it's all about...
</div>
<div style="
width: 100%;
position: absolute;
font-size: 88px;
top: 20px;
line-height: 100px;
">
Contagions &amp; Connections
</div>
<div style="
width: 710px;
position: absolute;
top: 125px;
left: 250px;
">
<b>Contagions:</b>
Like how neurons pass signals in a brain,
people pass beliefs &amp; behaviors in a society.
Not only do we influence our friends,
we also influence our friends' friends, and even our friends' friends' friends!(*)
(“be the change you wanna see in the world” etc etc)
But, like neurons, it's not just signals that matter, it's also...
</div>
<div style="
width: 710px;
position: absolute;
top: 275px;
left: 250px;
">
<b>Connections:</b>
Too few connections and complex ideas can't spread.
Too <i>many</i> connections and complex ideas get crushed by groupthink.
The trick is to build a small world network, the optimal mix of
bonding and bridging: <i>e pluribus unum.</i>
<br><br>
(BONUS: missing)
</div>
<div style="
width: 400px;
position: absolute;
top: 395px;
right: 0px;
text-align: right;
">
so, what about our question from the very beginning?
why <i>do</i> some crowds turn to...
</div>
<div style="
width: 300px;
position: absolute;
top: 460px;
right: 0px;
">
<next>...wisdom and/or madness?</next>
</div>
</words>
<words id="conclusion_2">
<div class="circle"><span>
in the final circle
recap all stories,
HUMAN BRAIN.
<next>derp</next>
<div class="circle" style="font-size:22px; line-height:1.3em;"><span>
<br>
From Newton to NASA to network science, we've covered a lot here today.
Long story short, the madness of crowds is not necessarily due to the
<i>individual people</i>, but how we're trapped in a network's sticky web.
<br><br>
That <i>does NOT</i> mean abandoning personal responsibility,
for we're also the <i>weavers</i> of that web.
So, improve your contagions:
be skeptical of ideas that flatter you(*),
spend time understanding complex ideas.
And, improve your connections: bond with similar folk,
but also build bridges across cultural/political divides.
<br><br>
We can weave a wise web.
Sure, it's harder than drawing lines on a screen...
<next>...but so, so worth it.</next>
</span></div>
</words>
<words id="conclusion_3">
<div class="circle"><span>
GOOD OMENS QUOTE.
<next>derp</next>
</span></div>
<i>
“The great triumphs and tragedies of history are caused,
not by people being fundamentally good or fundamentally bad,
but by people being fundamentally people.”
</i>
<br>
<span style="position:relative; top:5px">~</span> Neil Gaiman &amp; Terry Pratchett
<next small>&lt;3</next>
</words>
<!-- 7. Credits -->
@ -706,14 +839,15 @@ Cursor is allowed to flow EVERYWHERE though...
<!--script src="js/sim/_Game.js"></script-->
<script src="js/sim/Simulations.js"></script>
<script src="js/chapters/0_Introduction.js"></script>
<script src="js/chapters/1_Networks.js"></script>
<script src="js/chapters/2_Simple_Contagion.js"></script>
<script src="js/chapters/3_Complex_Contagion.js"></script>
<script src="js/chapters/4_Bonding_And_Bridging.js"></script>
<script src="js/chapters/5_Sandbox.js"></script>
<script src="js/chapters/6_Conclusion.js"></script>
<script src="js/chapters/7_Credits.js"></script>
<script src="js/chapters/1_Introduction.js"></script>
<script src="js/chapters/2_Networks.js"></script>
<script src="js/chapters/3_Simple_Contagion.js"></script>
<script src="js/chapters/4_Complex_Contagion.js"></script>
<script src="js/chapters/5_Bonding_And_Bridging.js"></script>
<script src="js/chapters/6_Small_World.js"></script>
<script src="js/chapters/7_Sandbox.js"></script>
<script src="js/chapters/8_Conclusion.js"></script>
<script src="js/chapters/9_Credits.js"></script>
<script src="js/main.js"></script>

View File

@ -3,8 +3,8 @@
// FOR REUSE:
var SPLASH_NETWORK = {
"contagion":0,
"peeps":[[-432,-121,0],[308,-101,0],[401,-224,0],[-226,392,0],[-217,-397,0],[303,356,0],[-70,-439,0],[280,-373,0],[35,-322,0],[125,299,0],[-549,-108,0],[489,118,0],[387,78,0],[189,385,0],[-425,-214,0],[69,602,0],[214,244,0],[305,108,0],[15,436,0],[389,236,0],[-271,-178,0],[-100,-308,0],[-106,440,0],[-346,4,0],[172,-372,0],[-575,-257,0],[457,-131,0],[-215,-242,0],[-318,-58,0],[22,323,0],[122,475,0],[388,461,0],[-492,27,0],[114,-303,0],[307,-252,0],[487,-347,0],[264,187,0],[231,-226,0],[-181,269,0],[-68,317,0],[-333,399,0],[-437,289,0],[-286,259,0],[-265,186,0],[-571,201,0],[-317,66,0],[618,35,0],[587,190,0],[574,-217,0],[-259,546,0],[-296,-307,0],[-618,53,0],[-127,-531,0],[489,336,0],[324,-9,0],[261,551,0],[-275,-535,0],[-396,-444,0],[-447,-333,0],[477,-26,0],[-406,486,0],[22,-464,0],[-3,-619,0],[-86,587,0],[382,-457,0],[266,-556,0],[119,-529,0],[-421,168,0]],
"connections":[[24,37,0],[37,1,0],[1,2,0],[26,1,0],[34,1,0],[13,9,0],[9,30,0],[30,29,0],[29,9,0],[9,18,0],[18,29,0],[18,30,0],[30,13,0],[13,29,0],[18,13,0],[36,19,0],[19,5,0],[19,12,0],[19,16,0],[17,19,0],[11,19,0],[14,25,0],[10,25,0],[10,14,0],[28,20,0],[20,0,0],[0,32,0],[8,21,0],[6,8,0],[21,27,0],[4,21,0],[4,27,0],[21,6,0],[39,3,0],[3,38,0],[38,22,0],[22,39,0],[39,38,0],[22,3,0],[6,4,0],[23,32,0],[42,40,0],[40,41,0],[41,42,0],[37,7,0],[37,33,0],[45,43,0],[47,46,0],[55,31,0],[57,56,0],[58,50,0],[59,54,0],[60,49,0],[62,52,0],[62,61,0],[63,15,0],[64,65,0],[65,66,0],[44,51,0],[48,35,0],[67,43,0],[67,45,0],[61,52,0],[23,0,0],[28,0,0]]
"peeps":[[-408,-115,0],[290,-143,0],[400,-221,0],[-221,373,0],[-214,-378,0],[358,357,0],[-86,-420,0],[269,-369,0],[6,-324,0],[124,299,0],[-550,-119,0],[469,137,0],[366,80,0],[176,381,0],[-452,-217,0],[43,597,0],[238,276,0],[300,120,0],[22,416,0],[373,226,0],[-275,-172,0],[-113,-303,0],[-117,419,0],[-324,5,0],[156,-375,0],[-580,-250,0],[416,-111,0],[-215,-243,0],[-316,-65,0],[33,322,0],[112,456,0],[363,487,0],[-455,13,0],[95,-310,0],[302,-268,0],[507,-313,0],[254,200,0],[207,-249,0],[-177,271,0],[-77,315,0],[-357,387,0],[-462,305,0],[-332,261,0],[-258,195,0],[-556,184,0],[-312,87,0],[600,19,0],[593,158,0],[562,-188,0],[-249,534,0],[-318,-295,0],[-592,55,0],[-99,-541,0],[528,282,0],[322,-31,0],[241,542,0],[-244,-540,0],[-356,-469,0],[-435,-359,0],[456,-11,0],[-382,507,0],[22,-475,0],[14,-611,0],[-89,571,0],[396,-446,0],[284,-521,0],[152,-537,0],[-399,172,0]],
"connections":[[24,37,0],[37,1,0],[1,2,0],[26,1,0],[34,1,0],[13,9,0],[9,30,0],[30,29,0],[29,9,0],[9,18,0],[18,29,0],[18,30,0],[30,13,0],[13,29,0],[18,13,0],[36,19,0],[19,5,0],[19,12,0],[19,16,0],[17,19,0],[11,19,0],[14,25,0],[10,25,0],[10,14,0],[28,20,0],[20,0,0],[0,32,0],[8,21,0],[6,8,0],[21,27,0],[4,21,0],[4,27,0],[21,6,0],[39,3,0],[3,38,0],[38,22,0],[22,39,0],[39,38,0],[22,3,0],[6,4,0],[23,32,0],[42,40,0],[40,41,0],[41,42,0],[37,7,0],[37,33,0],[45,43,0],[47,46,0],[55,31,0],[57,56,0],[58,50,0],[59,54,0],[60,49,0],[62,52,0],[62,61,0],[63,15,0],[64,65,0],[65,66,0],[44,51,0],[48,35,0],[67,43,0],[67,45,0],[61,52,0],[23,0,0],[28,0,0],[53,47,0]]
};
SLIDES.push(

View File

@ -249,10 +249,10 @@ SLIDES.push(
setTimeout(function(){
//boxes.showChildByID("end", true);
sim.win();
},500);
},350);
setTimeout(function(){
slideshow.next();
},1250);
},1100);
}

View File

@ -1,4 +1,3 @@
// 0 - INTRODUCTION
SLIDES.push(
{
@ -160,81 +159,6 @@ SLIDES.push(
}
},
{
chapter: "BB-Both",
clear:true,
add:[
// Sim
// use a DRAWING to impose SOFT CONSTRAINTS
{
type:"sim",
x:150, y:0,
fullscreen: true,
network: {
"contagion":0.25,
"peeps":[[485,50,1],[581,97,0],[389,101,0],[579,200,0],[399,193,0],[487,243,0],[290,312,0],[201,358,0],[196,446,0],[278,509,0],[381,374,0],[367,469,0],[596,370,0],[680,315,0],[778,354,0],[784,454,0],[700,506,0],[604,459,0]],
"connections":[]
},
options:{
infectedFrame: 3,
scale: 1,
startUncuttable: true
}
},
// UI for the simulation
{
type:"box",
id:"ui",
x:70, y:190,
sim_ui:"blue"
},
// Words
{
type:"box",
text:"bb_1",
x:0, y:10, w:350, h:170
},
// Words
{
id:"end",
type:"box",
text:"bb_2",
x:0, y:310, w:300, h:230,
//hidden: true
}
],
onupdate:function(slideshow, state){
// If ALL infected...
var sim = slideshow.simulations.sims[0];
var peepCount = 0;
sim.peeps.forEach(function(peep){
if(peep.infected) peepCount++;
});
// Win
if(!state.ended){
if(peepCount==sim.peeps.length){
var boxes = slideshow.boxes;
boxes.showChildByID("end", true);
state.ended = true;
sim.win();
}
}
}
},
}
);

View File

@ -1,36 +0,0 @@
// 0 - INTRODUCTION
SLIDES.push(
/*{
chapter: "Conclusion",
clear:true
}*/
{
chapter: "Conclusion",
clear:true,
add:[
// Splash
{
type:"sim",
x:960/2, y:540/2,
fullscreen: true,
network: SPLASH_NETWORK,
options:{
splash: true,
randomStart: 20
}
},
// Words
{
type:"box",
text:"conclusion_2", x:210, y:0, w:540, h:540, align:"center"
},
]
},
);

View File

@ -0,0 +1,118 @@
SLIDES.push(
{
chapter: "SmallWorld",
clear:true,
add:[
// Sim
// use a DRAWING to impose SOFT CONSTRAINTS
{
type:"sim",
x:150, y:0,
fullscreen: true,
network: {
"contagion":0.25,
"peeps":[[485,50,1],[581,97,0],[389,101,0],[579,200,0],[399,193,0],[487,243,0],[290,312,0],[201,358,0],[196,446,0],[278,509,0],[381,374,0],[367,469,0],[596,370,0],[680,315,0],[778,354,0],[784,454,0],[700,506,0],[604,459,0]],
"connections":[[13,12,0],[12,17,0],[17,16,0],[16,15,0],[15,14,0],[14,13,0],[12,14,0],[14,17,0],[17,13,0],[13,15,0],[15,12,0],[12,16,0],[16,14,0],[13,16,0],[15,17,0],[7,6,0],[6,10,0],[10,11,0],[11,9,0],[9,8,0],[8,7,0],[7,10,0],[10,9,0],[9,7,0],[6,9,0],[8,11,0],[11,6,0],[6,8,0],[7,11,0],[10,8,0]]
},
options:{
infectedFrame: 3,
scale: 1,
startUncuttable: true
}
},
// UI for the simulation
{
type:"box",
id:"ui",
x:70, y:180,
sim_ui:"blue"
},
// Words
{
type:"box",
text:"bb_1",
x:0, y:10, w:350, h:170
},
// Words
{
id:"end",
type:"box",
text:"bb_2",
x:0, y:310, w:300, h:230,
hidden: true
}
],
onupdate:function(slideshow, state){
// If ALL infected...
var sim = slideshow.simulations.sims[0];
var peepCount = 0;
sim.peeps.forEach(function(peep){
if(peep.infected) peepCount++;
});
// Win
if(!state.ended){
if(peepCount==sim.peeps.length){
var boxes = slideshow.boxes;
boxes.showChildByID("end", true);
state.ended = true;
sim.win();
}
}
}
},
{
chapter: "SmallWorld-Explanation",
clear:true,
add:[
// Words
{
type:"box",
text:"bb_small_world_1", x:0, y:0, w:960, h:120,
},
{
type:"box",
text:"bb_small_world_2", x:0, y:120, w:320, h:50,
fontSize:"19px", lineHeight:"21px",
align:"center"
},
{
type:"box",
text:"bb_small_world_3", x:320, y:120, w:320, h:50,
fontSize:"19px", lineHeight:"21px",
align:"center"
},
{
type:"box",
text:"bb_small_world_4", x:640, y:130, w:320, h:40,
fontSize:"30px", lineHeight:"30px",
align:"center"
},
{
type:"box",
text:"bb_small_world_5", x:0, y:360, w:640, h:180,
},
{
type:"box",
text:"bb_small_world_end", x:640, y:360, w:320, h:180,
align:"center"
}
]
}
);

View File

@ -1,4 +1,3 @@
// 0 - INTRODUCTION
SLIDES.push(
{
chapter: "Sandbox",

View File

@ -0,0 +1,84 @@
// 0 - INTRODUCTION
SLIDES.push(
{
chapter: "Conclusion",
clear:true,
add:[
// Words
{
type:"box",
id:"conclusion_1",
text:"conclusion_1", x:0, y:0, w:960, h:540
}
]
},
{
chapter: "Conclusion-Splash",
clear:true,
add:[
// Splash
{
type:"sim",
x:960/2, y:540/2,
fullscreen: true,
network: SPLASH_NETWORK,
options:{
splash: true,
randomStart: 20
}
},
// Words
{
type:"box",
id:"conclusion_2",
text:"conclusion_2", x:210, y:0, w:540, h:540, align:"center"
},
]
},
{
remove:[
{type:"box", id:"conclusion_2"}
],
add:[
{
type:"box",
id:"conclusion_3",
text:"conclusion_3", x:210, y:160, w:540, h:220, align:"center"
}
]
},
{
remove:[
{type:"box", id:"conclusion_3"}
],
onstart: function(slideshow, state){
// splash animation, then auto-next to CREDITS.
var splash = slideshow.simulations.sims[0];
splash.options.CONCLUSION = true;
splash.options.CONCLUSION_GLOW_RADIUS = 0;
setTimeout(function(){
slideshow.next();
},7000);
},
onupdate: function(slideshow, state){
var splash = slideshow.simulations.sims[0];
splash.options.CONCLUSION_GLOW_RADIUS += 3;
}
}
);

View File

@ -72,7 +72,7 @@ function fadeOut(container, dom){
}
// Tween position
function tweenPosition(from, to, callback){
function tweenPosition(from, to, callback, ease, speed){
var x1 = from.x;
var y1 = from.y;
var x2 = to.x;
@ -80,10 +80,12 @@ function tweenPosition(from, to, callback){
var dx = x2-x1;
var dy = y2-y1;
var t = 0;
ease = ease || easeInOutSine;
speed = speed || 3/60;
var handle = subscribe("update", function(){
// Time
t += 3/60;
t += speed;
if(t>=1){
from.x = x2;
from.y = y2;
@ -118,6 +120,9 @@ function tweenPosition(from, to, callback){
function easeInOutSine(t) {
return -1/2 * (Math.cos((Math.TAU/2)*t) - 1);
};
function easeLinear(t){
return t;
}
// Get Bounding Box of points
function getBoundsOfPoints(points){

View File

@ -29,6 +29,6 @@ window.onload = function(){
window.requestAnimationFrame(update);
// First slide!
slideshow.gotoChapter("Sandbox");
slideshow.gotoChapter("Conclusion");
}

View File

@ -8,7 +8,7 @@ function Connection(config){
self.uncuttable = config.uncuttable || false;
self.sim = config.sim;
// Sprite
// Line Sprite
self.sprite = new Sprite({
src: "sprites/line.png",
frames:1, sw:300, sh:20,
@ -16,6 +16,15 @@ function Connection(config){
self.sprite.pivotX = 2.8;
self.sprite.pivotY = 10;
// Dot Sprite
self.dotSprite = new Sprite({
src: "sprites/peeps.png",
frames:6, sw:200, sh:200,
});
self.dotSprite.pivotX = 100;
self.dotSprite.pivotY = 100;
self.dotSprite.scale = 0.1;
// Update
self.update = function(){};
@ -37,6 +46,15 @@ function Connection(config){
self.sprite.draw(ctx);
ctx.restore();
// DRAW CONTAGION DOT
if(self.contagionDot){
var infectedFrame = self.sim.options.infectedFrame || 1;
self.dotSprite.x = self.contagionDot.x;
self.dotSprite.y = self.contagionDot.y;
self.dotSprite.gotoFrame(infectedFrame);
self.dotSprite.draw(ctx);
}
};
// Hit Test with a LINE SEGMENT
@ -66,4 +84,38 @@ function Connection(config){
};
// Animate
self.contagionDot = null;
self.animate = function(){
// Infection?
var cFrom, cTo;
if(self.from.infected && (!self.to.infected && self.to.isPastThreshold)){
cFrom = self.from;
cTo = self.to;
}
if(self.to.infected && (!self.from.infected && self.from.isPastThreshold)){
cFrom = self.to;
cTo = self.from;
}
// boop!
if(cFrom && cTo){
// ANIMATE IT
cFrom = { x:cFrom.x, y:cFrom.y };
cTo = { x:cTo.x, y:cTo.y };
tweenPosition(cFrom, cTo, function(point){
self.contagionDot = point;
}, easeLinear);
// Then, goodbye later
setTimeout(function(){
self.contagionDot = null;
},333);
}
};
}

View File

@ -73,24 +73,29 @@ function Peep(config){
y: 0 - self.y
});
var gravityScale = getVectorLength(self)*0.00012;
if(self.sim.options.CONCLUSION){
gravityScale *= 2;
}
gravity = multiplyVector(gravity, gravityScale);
self.velocity = addVectors(self.velocity, gravity);
// If within the ring, push OUT.
var RADIUS = 325;
var distanceFromCenter = getVectorLength(self);
if(distanceFromCenter<RADIUS){
var forcePushOut = RADIUS-distanceFromCenter;
forcePushOut *= 0.05;
forcePushOut = Math.min(forcePushOut, 2); //cap
var forceDirection = getUnitVector(self);
var forceOut = multiplyVector( forceDirection, forcePushOut );
self.velocity = addVectors(self.velocity, forceOut);
if(!self.sim.options.CONCLUSION){
var RADIUS = 325;
var distanceFromCenter = getVectorLength(self);
if(distanceFromCenter<RADIUS){
var forcePushOut = RADIUS-distanceFromCenter;
forcePushOut *= 0.05;
forcePushOut = Math.min(forcePushOut, 2); //cap
var forceDirection = getUnitVector(self);
var forceOut = multiplyVector( forceDirection, forcePushOut );
self.velocity = addVectors(self.velocity, forceOut);
}
}
// Hookes to Connected
var k = 0.002;
var hookesDistance = 160;
var hookesDistance = 140;
var hookesTotalForce = {x:0, y:0};
friends.forEach(function(friend){
@ -106,6 +111,9 @@ function Peep(config){
// Coulomb from Disconnected
var c = -300;
if(self.sim.options.CONCLUSION){
c = -400;
}
var coulombTotalForce = {x:0, y:0};
self.sim.peeps.forEach(function(peep){
@ -163,6 +171,8 @@ function Peep(config){
"#7DE74E", // green
"#FBCBDC" // pink
];
var _glowAnim = 0;
self.conclusionFrame = Math.floor(1+Math.random()*5);
self.draw = function(ctx){
ctx.save();
@ -176,15 +186,27 @@ function Peep(config){
var infectedColor = PEEP_COLORS[infectedFrame];
var myFrame = self.infected ? infectedFrame : 0;
var myColor = PEEP_COLORS[myFrame];
// CONCLUSION SPLASH
if(self.sim.options.CONCLUSION){
var distance = getVectorLength(self);
if(distance < self.sim.options.CONCLUSION_GLOW_RADIUS){
//self.isPastThreshold = true;
myFrame = self.conclusionFrame;
infectedFrame = self.conclusionFrame;
}
}
self.sprite.rotation = bodyRotation;
if(self.isPastThreshold){ // highlight!
if(self.isPastThreshold){ // highlight! glow!
ctx.globalAlpha = 0.4;
self.sprite.scale = _initSpriteScale*1.25;
_glowAnim += 0.03;
var _glowScale = 1 + Math.sin(_glowAnim)*0.04;
ctx.globalAlpha = 0.35;
self.sprite.scale = _initSpriteScale*1.25*_glowScale;
self.sprite.gotoFrame(infectedFrame);
self.sprite.draw(ctx);
// undo
ctx.globalAlpha = 1;
self.sprite.scale = _initSpriteScale;
@ -209,12 +231,19 @@ function Peep(config){
ctx.save();
// SHAKE
if(self._shakeAnim>=0){
var shake = Math.sin(self._shakeAnim*10)*3;
ctx.translate(shake, 0);
self._shakeAnim -= 0.05;
}
var bgColor = "#ddd";
var uiColor = "#333";
// Say: Infected/Friends (% then n/n)
ctx.translate(0,-43);
ctx.font = '9px FuturaHandwritten';
ctx.font = '12px PatrickHand';
ctx.fillStyle = uiColor;
ctx.textBaseline = "middle";
ctx.fontWeight = "bold";
@ -289,4 +318,10 @@ function Peep(config){
self.infected = true;
};
// Shake
self._shakeAnim = -1;
self.shake = function(){
self._shakeAnim = 1;
};
}

View File

@ -281,7 +281,7 @@ function Sim(config){
ctx.globalAlpha = alpha;
}
ctx.font = '80px FuturaHandwritten';
ctx.font = '100px PatrickHand';
ctx.fillStyle = "#000";
ctx.textBaseline = "middle";
ctx.fontWeight = "bold";
@ -376,16 +376,44 @@ function Sim(config){
self.contagion = contagionLevel;
};
self._dontStepAgain = false;
self.nextStep = function(){
self.STEP++;
if(self._dontStepAgain) return;
self._dontStepAgain = true;
setTimeout(function(){
self.STEP++;
self._dontStepAgain = false;
},420); // just in case...
// "Infect" the peeps who need to get infected
// TODO: Connection animation
self.peeps.filter(function(peep){
return peep.isPastThreshold;
}).forEach(function(peep){
peep.infect();
// CONNECTIONS: IF one is INFECTED and the other is PAST THRESHOLD, then ANIMATE
self.connections.forEach(function(c){
c.animate();
});
// PEEPS: If not already infected & past threshold, infect
self.peeps.forEach(function(peep){
if(!peep.infected && peep.isPastThreshold){
// timeout for animation
setTimeout(function(){
peep.infect();
},333);
}
});
// PEEPS: If NOT infected, NOT past threshold, and a friend IS INFECTED, then SHAKE
self.peeps.forEach(function(peep){
if(!peep.infected && !peep.isPastThreshold){
var friends = self.getFriendsOf(peep);
var infectedFriends = friends.filter(function(f){
return f.infected;
});
if(infectedFriends.length>0){
peep.shake();
}
}
});
};

View File

@ -52,7 +52,7 @@ function Navigation(){
var _showBubble = function(nav){
var offset = nav.getBoundingClientRect().x - $("#navigation").getBoundingClientRect().x;
var label = nav.querySelector("span:nth-child(2)").innerHTML;
var label = nav.children[1].innerHTML;
bubble.style.left = offset - (220/2) + (36/2);
bubble.innerHTML = label;

View File

@ -44,11 +44,9 @@ function SandboxUI(container){
// Choose Color of Peeps //
///////////////////////////
var GAP = "0.5em";
var colorChooserLabel = document.createElement("div");
colorChooserLabel.innerHTML = getWords("sandbox_color_chooser");
colorChooserLabel.style.marginTop = GAP;
colorChooserLabel.style.marginTop = "0.5em";
var colorChooser = new ChooseOne({
options:[
1, // red
@ -77,7 +75,7 @@ function SandboxUI(container){
var toolChooserLabel = document.createElement("div");
toolChooserLabel.innerHTML = getWords("sandbox_tool_chooser");
toolChooserLabel.style.marginTop = "0.25em"; //GAP;
toolChooserLabel.style.marginTop = "0.25em";
var tools = [
"pencil",
"add",
@ -124,7 +122,8 @@ function SandboxUI(container){
var shortcutsLabel = document.createElement("div");
shortcutsLabel.innerHTML = getWords("sandbox_shortcuts_label");
shortcutsLabel.id = "sandbox_shortcuts_label";
shortcutsLabel.style.marginTop = GAP;
shortcutsLabel.style.marginTop = "0.5em";
shortcutsLabel.style.lineHeight = "1.2em";
var shortcuts = document.createElement("div");
shortcuts.innerHTML = getWords("sandbox_shortcuts");
shortcuts.id = "sandbox_shortcuts";