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{ html, body{
width:100%; width:100%;
height:100%; height:100%;
@ -7,9 +17,10 @@ html, body{
body{ body{
margin:0; margin:0;
font-family: "FuturaHandwritten"; font-family: "PatrickHand";
font-size: 20px; font-size: 23px;
line-height: 1.5em; line-height: 1.5em;
} }
/* fake bold */ /* fake bold */
b, strong{ b, strong{
@ -62,6 +73,7 @@ b, strong{
background-image: url(../sprites/button_large.png); background-image: url(../sprites/button_large.png);
background-size: 100% auto; background-size: 100% auto;
text-align: center; text-align: center;
line-height: 25px;
} }
#slideshow .next_button:hover{ #slideshow .next_button:hover{
background-position: 0 -100px; background-position: 0 -100px;
@ -114,6 +126,7 @@ b, strong{
} }
.sandbox_ui input[type="range"]{ .sandbox_ui input[type="range"]{
width: 100%; width: 100%;
cursor: none;
} }
.choose_one{ .choose_one{
overflow: hidden; overflow: hidden;
@ -199,8 +212,6 @@ b, strong{
color: #222; color: #222;
} }
#navigation > div > span:nth-child(1){ #navigation > div > span:nth-child(1){
position: relative;
top: 1px;
display: block; display: block;
} }
#navigation > div > span:nth-child(2){ #navigation > div > span:nth-child(2){
@ -237,7 +248,6 @@ b, strong{
color: #fff; color: #fff;
text-align: center; text-align: center;
border-radius: 20px; border-radius: 20px;
font-size: 18px;
width: 220px; width: 220px;
padding: 6px 0; padding: 6px 0;

View File

@ -51,36 +51,40 @@ Cursor is allowed to flow EVERYWHERE though...
<!-- The chapters --> <!-- The chapters -->
<div chapter="Introduction"> <div chapter="Introduction">
<span>0</span> <span>1</span>
<span>0. Introduction</span> <span>1. Introduction</span>
</div> </div>
<div chapter="Networks"> <div chapter="Networks">
<span>1</span> <span>2</span>
<span>1. Connections</span> <span>2. Connections</span>
</div> </div>
<div chapter="Simple"> <div chapter="Simple">
<span>2</span> <span>3</span>
<span>2. Contagions</span> <span>3. Contagions</span>
</div> </div>
<div chapter="Complex"> <div chapter="Complex">
<span>3</span> <span>4</span>
<span>3. Complex Contagions</span> <span>4. Complex Contagions</span>
</div> </div>
<div chapter="BB"> <div chapter="BB">
<span>4</span> <span>5</span>
<span>4. Bonding &amp; Bridging</span> <span>5. Bonding &amp; Bridging</span>
</div>
<div chapter="SmallWorld">
<span>6</span>
<span>6. It's A Small World</span>
</div> </div>
<div chapter="Sandbox"> <div chapter="Sandbox">
<span>5</span> <span>7</span>
<span>5. Sandbox Mode</span> <span>7. Sandbox Mode</span>
</div> </div>
<div chapter="Conclusion"> <div chapter="Conclusion">
<span>6</span> <span>8</span>
<span>6. In Conclusion...</span> <span>8. In Conclusion...</span>
</div> </div>
<div chapter="Credits"> <div chapter="Credits">
<span>7</span> <span>9</span>
<span>7. Credits</span> <span>9. Credits</span>
</div> </div>
<!-- A divider --> <!-- A divider -->
@ -92,9 +96,22 @@ Cursor is allowed to flow EVERYWHERE though...
<span>Bonus Boxes! (Notes)</span> <span>Bonus Boxes! (Notes)</span>
</div> </div>
<div modal="references"> <div modal="references">
<span style="margin-top:5px">*</span> <span style="margin-top: 7px; font-size: 35px;">*</span>
<span>References</span> <span>References</span>
</div> </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 --> <!-- The hover bubble -->
<span id="nav_bubble">AHHHHHH</span> <span id="nav_bubble">AHHHHHH</span>
@ -137,7 +154,7 @@ Cursor is allowed to flow EVERYWHERE though...
<words id="_0_intro"> <words id="_0_intro">
<div class="circle"><span> <div class="circle"><span>
<br><br><br> <br><br>
Sir Isaac Newton was pretty sure he was a smart cookie. Sir Isaac Newton was pretty sure he was a smart cookie.
I mean, after inventing calculus and a theory of gravity, 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. Some <i>mis</i>information. "Fake news", as the cool kids say.
And every day, that person spreads the rumor to their friends. And every day, that person spreads the rumor to their friends.
And they spread it to <i>their</i> friends. And so on. And they spread it to <i>their</i> friends. And so on.
<br><br> <br>
<b>Run the simulation, step-by-step &darr;</b> <b>Run the simulation, step-by-step &darr;</b>
(p.s: you can't draw <i>while</i> the sim's running) (p.s: you can't draw <i>while</i> the sim's running)
</words> </words>
@ -345,8 +362,8 @@ Cursor is allowed to flow EVERYWHERE though...
Mr. Newton fell for such a cascade in 1720. Mr. Newton fell for such a cascade in 1720.
The world's financial institutions fell for such a cascade in 2008. The world's financial institutions fell for such a cascade in 2008.
But so what? You already knew ideas spread. But so what? You already knew ideas spread.
However, network scientists recently found a <i>new</i>, strange kind of contagion. However, network scientists have found a <i>new</i>, strange kind of contagion.
And they're called... They're called...
</words> </words>
<words id="_2_post_cascade_end"> <words id="_2_post_cascade_end">
@ -356,69 +373,71 @@ Cursor is allowed to flow EVERYWHERE though...
<!-- 3. Complex Contagions --> <!-- 3. Complex Contagions -->
<words id="_3_complex"> <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, <b>Simple contagions</b>, like juicy rumors or hot takes,
only need one "infected" friend to spread. only need one "infected" friend to spread.
That doesn't mean the contagion <i>will</i> spread, That doesn't mean the contagion <i>will</i> spread,
just that one exposure <i>can</i> be enough to 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. 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. <b>Complex contagions</b> are weirder.
Some things -- like norms, habits and hard-to-accept ideas -- Some things -- like norms, habits and hard-to-accept ideas --
need more social encouragement. need more social encouragement.
They need not a minimum <i>number</i> of friends to spread, They need not a minimum <i>number</i> of friends to spread,
but a minimum <i>percentage</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 <b>On the right, a person needs <i>AT LEAST 25%</i> of their friends to
adopt a complex fact (img) before they do. adopt a complex fact (img) before they do.
Try "infecting" them all with <i>wisdom!</i> &rarr;</b> Try "infecting" them all with <i>wisdom!</i> &rarr;</b>
</span>
</words> </words>
<words id="_3_complex_2"> <words id="_3_complex_2">
<span style="line-height:1.4em">
<b>CAUTION:</b> <b>CAUTION:</b>
just because an idea/behavior is "complex" doesn't mean it's good, just because an idea/behavior is "complex" doesn't mean it's good,
(e.g. conspiracy theories) (e.g. conspiracy theories)
and just because it's "simple" doesn't mean it's bad! and just because it's "simple" doesn't mean it's bad!
(e.g. cute cat videos) (e.g. cute cat videos)
<br><br> <div style="height:0.9em"></div>
Think of it this way: Think of it this way:
simple contagions are weeds, complex contagions are trees, simple contagions are weeds, complex contagions are trees,
and a network is an ecosystem. and a network is an ecosystem.
Sometimes weeds are good, sometimes trees are bad. Sometimes weeds are good, sometimes trees are bad.
But if your ecosystem can <i>only</i> support weeds, But if your ecosystem can <i>only</i> support weeds,
something's very wrong. 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? So, how <i>do</i> we make sure our social ecosystem is healthy?
Let's revisit... Let's revisit...
<next wiggle>...the cascade puzzle!</next> <next wiggle>...the cascade puzzle!</next>
</span>
</words> </words>
<words id="_3_cascade"> <words id="_3_cascade">
You did this before, but now, with a <i>complex</i> contagion (img), it'll be tougher... You did this before, but now, with a <i>complex</i> contagion (img), it'll be tougher...
<br> <b>Try to "infect" everyone with complex wisdom! &darr;</b>
(note: feel free to just hit 'start' and <i>try</i> as many solutions as you want) (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>
</words> </words>
<words id="_3_cascade_end"> <words id="_3_cascade_end">
@ -468,14 +487,15 @@ Cursor is allowed to flow EVERYWHERE though...
The immediate cause: The immediate cause:
it was too cold that morning. it was too cold that morning.
<br><br> <div style="height:0.9em"></div>
The less immediate cause: the managers ignored the engineers' warnings. The less immediate cause: the managers ignored the engineers' warnings.
Why? Because of <b>groupthink</b>(*). 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) 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. So, that's how to get crowd madness.
But how can we "design" for crowd <i>wisdom?</i> But how can we "design" for crowd <i>wisdom?</i>
@ -501,7 +521,7 @@ Cursor is allowed to flow EVERYWHERE though...
</words> </words>
<words id="bonding_end"> <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. the strength of the connections <i>within</i> a single group.
But what about the connections... But what about the connections...
<next wiggle>...<i>between</i> groups?</next> <next wiggle>...<i>between</i> groups?</next>
@ -517,9 +537,8 @@ Cursor is allowed to flow EVERYWHERE though...
<words id="bridging_end"> <words id="bridging_end">
Like bonding, bridging social capital has a sweet spot. 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!) <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... Now that we know how to "design" connections <i>within</i> and <i>between</i> groups, let's...
<next wiggle>...do BOTH. &rarr;</next> <next wiggle>...do BOTH. &rarr;</next>
</words> </words>
@ -529,30 +548,62 @@ Cursor is allowed to flow EVERYWHERE though...
<b style="font-size:2em">FINAL PUZZLE!</b> <b style="font-size:2em">FINAL PUZZLE!</b>
<br> <br>
Draw connections within groups (bonding) and between groups (bridging) 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>
<words id="bb_2"> <words id="bb_2">
derp derp You just drew a very special kind of network!
<next wiggle>derp derp &rarr;</next> Networks with high bonding and bridging
are profoundly important, and they're called...
// "SMALL WORLD" <next wiggle>“Small World Networks” &rarr;</next>
// e pluribus unum
// unity in diversity?
// examples
// JFK story in footnote
</words> </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> </words>
<!-- 5. Sandbox --> <!-- 5. Sandbox -->
<words id="sandbox_caption"> <words id="sandbox_caption">
<b>NOTE: "Sandbox Mode" is totally optional.</b> <b>NOTE: "Sandbox Mode" is totally optional!</b>
Feel free to skip it, or play around!(*) Feel free to skip it, or play around.(*)
When you're done, let's recap... Whenever you're done, let's recap...
</words> </words>
<words id="sandbox_next"> <words id="sandbox_next">
<next>what we learnt today!</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 --> <!-- recap and CONCRETE LIFE TAKE-AWAYS. mirror intro UI -->
<words id="conclusion_1"> <words id="conclusion_1">
IN CONCLUSION:
Contagion &amp; Connections. <div style="font-size: 30px;">
<next>derp</next> 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>
<words id="conclusion_2"> <words id="conclusion_2">
<div class="circle"><span> <div class="circle" style="font-size:22px; line-height:1.3em;"><span>
in the final circle
recap all stories, <br>
HUMAN BRAIN. From Newton to NASA to network science, we've covered a lot here today.
<next>derp</next> 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> </span></div>
</words> </words>
<words id="conclusion_3"> <words id="conclusion_3">
<div class="circle"><span> <i>
GOOD OMENS QUOTE. “The great triumphs and tragedies of history are caused,
<next>derp</next> not by people being fundamentally good or fundamentally bad,
</span></div> 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> </words>
<!-- 7. Credits --> <!-- 7. Credits -->
@ -706,14 +839,15 @@ Cursor is allowed to flow EVERYWHERE though...
<!--script src="js/sim/_Game.js"></script--> <!--script src="js/sim/_Game.js"></script-->
<script src="js/sim/Simulations.js"></script> <script src="js/sim/Simulations.js"></script>
<script src="js/chapters/0_Introduction.js"></script> <script src="js/chapters/1_Introduction.js"></script>
<script src="js/chapters/1_Networks.js"></script> <script src="js/chapters/2_Networks.js"></script>
<script src="js/chapters/2_Simple_Contagion.js"></script> <script src="js/chapters/3_Simple_Contagion.js"></script>
<script src="js/chapters/3_Complex_Contagion.js"></script> <script src="js/chapters/4_Complex_Contagion.js"></script>
<script src="js/chapters/4_Bonding_And_Bridging.js"></script> <script src="js/chapters/5_Bonding_And_Bridging.js"></script>
<script src="js/chapters/5_Sandbox.js"></script> <script src="js/chapters/6_Small_World.js"></script>
<script src="js/chapters/6_Conclusion.js"></script> <script src="js/chapters/7_Sandbox.js"></script>
<script src="js/chapters/7_Credits.js"></script> <script src="js/chapters/8_Conclusion.js"></script>
<script src="js/chapters/9_Credits.js"></script>
<script src="js/main.js"></script> <script src="js/main.js"></script>

View File

@ -3,8 +3,8 @@
// FOR REUSE: // FOR REUSE:
var SPLASH_NETWORK = { var SPLASH_NETWORK = {
"contagion":0, "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]], "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]] "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( SLIDES.push(

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@ function Connection(config){
self.uncuttable = config.uncuttable || false; self.uncuttable = config.uncuttable || false;
self.sim = config.sim; self.sim = config.sim;
// Sprite // Line Sprite
self.sprite = new Sprite({ self.sprite = new Sprite({
src: "sprites/line.png", src: "sprites/line.png",
frames:1, sw:300, sh:20, frames:1, sw:300, sh:20,
@ -16,6 +16,15 @@ function Connection(config){
self.sprite.pivotX = 2.8; self.sprite.pivotX = 2.8;
self.sprite.pivotY = 10; 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 // Update
self.update = function(){}; self.update = function(){};
@ -37,6 +46,15 @@ function Connection(config){
self.sprite.draw(ctx); self.sprite.draw(ctx);
ctx.restore(); 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 // 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 y: 0 - self.y
}); });
var gravityScale = getVectorLength(self)*0.00012; var gravityScale = getVectorLength(self)*0.00012;
if(self.sim.options.CONCLUSION){
gravityScale *= 2;
}
gravity = multiplyVector(gravity, gravityScale); gravity = multiplyVector(gravity, gravityScale);
self.velocity = addVectors(self.velocity, gravity); self.velocity = addVectors(self.velocity, gravity);
// If within the ring, push OUT. // If within the ring, push OUT.
var RADIUS = 325; if(!self.sim.options.CONCLUSION){
var distanceFromCenter = getVectorLength(self); var RADIUS = 325;
if(distanceFromCenter<RADIUS){ var distanceFromCenter = getVectorLength(self);
var forcePushOut = RADIUS-distanceFromCenter; if(distanceFromCenter<RADIUS){
forcePushOut *= 0.05; var forcePushOut = RADIUS-distanceFromCenter;
forcePushOut = Math.min(forcePushOut, 2); //cap forcePushOut *= 0.05;
var forceDirection = getUnitVector(self); forcePushOut = Math.min(forcePushOut, 2); //cap
var forceOut = multiplyVector( forceDirection, forcePushOut ); var forceDirection = getUnitVector(self);
self.velocity = addVectors(self.velocity, forceOut); var forceOut = multiplyVector( forceDirection, forcePushOut );
self.velocity = addVectors(self.velocity, forceOut);
}
} }
// Hookes to Connected // Hookes to Connected
var k = 0.002; var k = 0.002;
var hookesDistance = 160; var hookesDistance = 140;
var hookesTotalForce = {x:0, y:0}; var hookesTotalForce = {x:0, y:0};
friends.forEach(function(friend){ friends.forEach(function(friend){
@ -106,6 +111,9 @@ function Peep(config){
// Coulomb from Disconnected // Coulomb from Disconnected
var c = -300; var c = -300;
if(self.sim.options.CONCLUSION){
c = -400;
}
var coulombTotalForce = {x:0, y:0}; var coulombTotalForce = {x:0, y:0};
self.sim.peeps.forEach(function(peep){ self.sim.peeps.forEach(function(peep){
@ -163,6 +171,8 @@ function Peep(config){
"#7DE74E", // green "#7DE74E", // green
"#FBCBDC" // pink "#FBCBDC" // pink
]; ];
var _glowAnim = 0;
self.conclusionFrame = Math.floor(1+Math.random()*5);
self.draw = function(ctx){ self.draw = function(ctx){
ctx.save(); ctx.save();
@ -176,15 +186,27 @@ function Peep(config){
var infectedColor = PEEP_COLORS[infectedFrame]; var infectedColor = PEEP_COLORS[infectedFrame];
var myFrame = self.infected ? infectedFrame : 0; var myFrame = self.infected ? infectedFrame : 0;
var myColor = PEEP_COLORS[myFrame]; 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; self.sprite.rotation = bodyRotation;
if(self.isPastThreshold){ // highlight! if(self.isPastThreshold){ // highlight! glow!
ctx.globalAlpha = 0.4; _glowAnim += 0.03;
self.sprite.scale = _initSpriteScale*1.25; 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.gotoFrame(infectedFrame);
self.sprite.draw(ctx); self.sprite.draw(ctx);
// undo
ctx.globalAlpha = 1; ctx.globalAlpha = 1;
self.sprite.scale = _initSpriteScale; self.sprite.scale = _initSpriteScale;
@ -209,12 +231,19 @@ function Peep(config){
ctx.save(); 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 bgColor = "#ddd";
var uiColor = "#333"; var uiColor = "#333";
// Say: Infected/Friends (% then n/n) // Say: Infected/Friends (% then n/n)
ctx.translate(0,-43); ctx.translate(0,-43);
ctx.font = '9px FuturaHandwritten'; ctx.font = '12px PatrickHand';
ctx.fillStyle = uiColor; ctx.fillStyle = uiColor;
ctx.textBaseline = "middle"; ctx.textBaseline = "middle";
ctx.fontWeight = "bold"; ctx.fontWeight = "bold";
@ -289,4 +318,10 @@ function Peep(config){
self.infected = true; 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.globalAlpha = alpha;
} }
ctx.font = '80px FuturaHandwritten'; ctx.font = '100px PatrickHand';
ctx.fillStyle = "#000"; ctx.fillStyle = "#000";
ctx.textBaseline = "middle"; ctx.textBaseline = "middle";
ctx.fontWeight = "bold"; ctx.fontWeight = "bold";
@ -376,16 +376,44 @@ function Sim(config){
self.contagion = contagionLevel; self.contagion = contagionLevel;
}; };
self._dontStepAgain = false;
self.nextStep = function(){ 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 // "Infect" the peeps who need to get infected
// TODO: Connection animation
self.peeps.filter(function(peep){ // CONNECTIONS: IF one is INFECTED and the other is PAST THRESHOLD, then ANIMATE
return peep.isPastThreshold; self.connections.forEach(function(c){
}).forEach(function(peep){ c.animate();
peep.infect(); });
// 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 _showBubble = function(nav){
var offset = nav.getBoundingClientRect().x - $("#navigation").getBoundingClientRect().x; 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.style.left = offset - (220/2) + (36/2);
bubble.innerHTML = label; bubble.innerHTML = label;

View File

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