diff --git a/css/PatrickHand-Regular.ttf b/css/PatrickHand-Regular.ttf new file mode 100755 index 0000000..fb45ccd Binary files /dev/null and b/css/PatrickHand-Regular.ttf differ diff --git a/css/index.css b/css/index.css index c8ff4cb..71a8d3a 100644 --- a/css/index.css +++ b/css/index.css @@ -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; diff --git a/index.html b/index.html index 38a3767..2e02252 100644 --- a/index.html +++ b/index.html @@ -51,36 +51,40 @@ Cursor is allowed to flow EVERYWHERE though...
- 0 - 0. Introduction + 1 + 1. Introduction
- 1 - 1. Connections + 2 + 2. Connections
- 2 - 2. Contagions + 3 + 3. Contagions
- 3 - 3. Complex Contagions + 4 + 4. Complex Contagions
- 4 - 4. Bonding & Bridging + 5 + 5. Bonding & Bridging +
+
+ 6 + 6. It's A Small World
- 5 - 5. Sandbox Mode + 7 + 7. Sandbox Mode
- 6 - 6. In Conclusion... + 8 + 8. In Conclusion...
- 7 - 7. Credits + 9 + 9. Credits
@@ -92,9 +96,22 @@ Cursor is allowed to flow EVERYWHERE though... Bonus Boxes! (Notes)
- * + * References
+
+ A + Translations +
AHHHHHH @@ -137,7 +154,7 @@ Cursor is allowed to flow EVERYWHERE though...
-


+

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 misinformation. "Fake news", as the cool kids say. And every day, that person spreads the rumor to their friends. And they spread it to their friends. And so on. -

+
Run the simulation, step-by-step ↓ (p.s: you can't draw while the sim's running) @@ -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 new, strange kind of contagion. - And they're called... + However, network scientists have found a new, strange kind of contagion. + They're called... @@ -356,69 +373,71 @@ Cursor is allowed to flow EVERYWHERE though... + - 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. -

+
- Simple contagions, like juicy rumors or hot takes, - only need one "infected" friend to spread. - That doesn't mean the contagion will spread, - just that one exposure can be enough to spread. - This, by the way, is how biological contagions like viruses work. + Simple contagions, like juicy rumors or hot takes, + only need one "infected" friend to spread. + That doesn't mean the contagion will spread, + just that one exposure can be enough to spread. + This, by the way, is how biological contagions (like bacteria & viruses) work. -

+
- Complex contagions are weirder. - Some things -- like norms, habits and hard-to-accept ideas -- - need more social encouragement. - They need not a minimum number of friends to spread, - but a minimum percentage of friends to spread!(*) + Complex contagions are weirder. + Some things -- like norms, habits and hard-to-accept ideas -- + need more social encouragement. + They need not a minimum number of friends to spread, + but a minimum percentage of friends to spread!(*) -

+
- On the right, a person needs AT LEAST 25% of their friends to - adopt a complex fact (img) before they do. - Try "infecting" them all with wisdom! + On the right, a person needs AT LEAST 25% of their friends to + adopt a complex fact (img) before they do. + Try "infecting" them all with wisdom! +
+ - CAUTION: - 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) + CAUTION: + 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) -

- - 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 only support weeds, - something's very wrong. +
+ + 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 only support weeds, + something's very wrong. -

+
- (BONUS: OTHER KINDS OF CONTAGIONS) + (BONUS: OTHER KINDS OF CONTAGIONS) -

+
- So, how do we make sure our social ecosystem is healthy? - Let's revisit... + So, how do we make sure our social ecosystem is healthy? + Let's revisit... - ...the cascade puzzle! + ...the cascade puzzle! +
You did this before, but now, with a complex contagion (img), it'll be tougher... -
- (note: feel free to just hit 'start' and try as many solutions as you want) -
- "Infect" everyone with complex wisdom! ↓ + Try to "infect" everyone with complex wisdom! ↓ + (feel free to just hit 'start' and try as many solutions as you want)
@@ -468,14 +487,15 @@ Cursor is allowed to flow EVERYWHERE though... The immediate cause: it was too cold that morning. -

+
The less immediate cause: the managers ignored the engineers' warnings. Why? Because of groupthink(*). When a group is too 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. -

+
So, that's how to get crowd madness. But how can we "design" for crowd wisdom? @@ -501,7 +521,7 @@ Cursor is allowed to flow EVERYWHERE though...
- This is called bonding social capital, + This is called bonding social capital(*), the strength of the connections within a single group. But what about the connections... ...between groups? @@ -517,9 +537,8 @@ Cursor is allowed to flow EVERYWHERE though... 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 can't pass through it!) -

Now that we know how to "design" connections within and between groups, let's... ...do BOTH. →
@@ -529,30 +548,62 @@ Cursor is allowed to flow EVERYWHERE though... FINAL PUZZLE!
Draw connections within groups (bonding) and between groups (bridging) - however you want, to spread wisdom to everyone: + to spread wisdom to everyone:
- derp derp - derp derp → - - // "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... + “Small World Networks” → - + + + "Unity without uniformity". "Diversity without division". "E Pluribus Unum: out of many, one". +
+ No matter how it's phrased, + people -- across times and cultures -- have often arrived at the same piece of wisdom: + + a healthy society needs both tight bonds within groups + and thick bridges between groups. + + +
+ + That is, not this... +
+ (because ideas can't spread) +
+ + nor this... +
+ (because you'll get groupthink) +
+ + ...but THIS: + + + + Network scientists now have a mathematical definition for this ancient wisdom: + the small world network(*). 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. + + + + And finally, if you'd like to make a whole network from scratch, let's check out... + The Sandbox Mode → - NOTE: "Sandbox Mode" is totally optional. - Feel free to skip it, or play around!(*) - When you're done, let's recap... + NOTE: "Sandbox Mode" is totally optional! + Feel free to skip it, or play around.(*) + Whenever you're done, let's recap... what we learnt today! @@ -607,25 +658,107 @@ Cursor is allowed to flow EVERYWHERE though... - IN CONCLUSION: - Contagion & Connections. - derp + +
+ IN CONCLUSION: it's all about... +
+
+ Contagions & Connections +
+ +
+ Contagions: + Like how neurons pass signals in a brain, + people pass beliefs & 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... +
+ +
+ Connections: + Too few connections and complex ideas can't spread. + Too many connections and complex ideas get crushed by groupthink. + The trick is to build a small world network, the optimal mix of + bonding and bridging: e pluribus unum. +

+ (BONUS: missing) +
+ +
+ so, what about our question from the very beginning? + why do some crowds turn to... +
+
+ ...wisdom and/or madness? +
+
-
- in the final circle - recap all stories, - HUMAN BRAIN. - derp +
+ +
+ 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 + individual people, but how we're trapped in a network's sticky web. + +

+ + That does NOT mean abandoning personal responsibility, + for we're also the weavers 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. + +

+ + We can weave a wise web. + Sure, it's harder than drawing lines on a screen... + ...but so, so worth it. +
-
- GOOD OMENS QUOTE. - derp -
+ + “The great triumphs and tragedies of history are caused, + not by people being fundamentally good or fundamentally bad, + but by people being fundamentally people.” + +
+ ~ Neil Gaiman & Terry Pratchett + <3
@@ -706,14 +839,15 @@ Cursor is allowed to flow EVERYWHERE though... - - - - - - - - + + + + + + + + + diff --git a/js/chapters/0_Introduction.js b/js/chapters/1_Introduction.js similarity index 55% rename from js/chapters/0_Introduction.js rename to js/chapters/1_Introduction.js index 903434a..8f962e6 100644 --- a/js/chapters/0_Introduction.js +++ b/js/chapters/1_Introduction.js @@ -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( diff --git a/js/chapters/1_Networks.js b/js/chapters/2_Networks.js similarity index 100% rename from js/chapters/1_Networks.js rename to js/chapters/2_Networks.js diff --git a/js/chapters/2_Simple_Contagion.js b/js/chapters/3_Simple_Contagion.js similarity index 100% rename from js/chapters/2_Simple_Contagion.js rename to js/chapters/3_Simple_Contagion.js diff --git a/js/chapters/3_Complex_Contagion.js b/js/chapters/4_Complex_Contagion.js similarity index 99% rename from js/chapters/3_Complex_Contagion.js rename to js/chapters/4_Complex_Contagion.js index 9186dba..4775845 100644 --- a/js/chapters/3_Complex_Contagion.js +++ b/js/chapters/4_Complex_Contagion.js @@ -249,10 +249,10 @@ SLIDES.push( setTimeout(function(){ //boxes.showChildByID("end", true); sim.win(); - },500); + },350); setTimeout(function(){ slideshow.next(); - },1250); + },1100); } diff --git a/js/chapters/4_Bonding_And_Bridging.js b/js/chapters/5_Bonding_And_Bridging.js similarity index 70% rename from js/chapters/4_Bonding_And_Bridging.js rename to js/chapters/5_Bonding_And_Bridging.js index 5b19c9f..abe89e7 100644 --- a/js/chapters/4_Bonding_And_Bridging.js +++ b/js/chapters/5_Bonding_And_Bridging.js @@ -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(); - } - } - - } - -}, - +} ); \ No newline at end of file diff --git a/js/chapters/6_Conclusion.js b/js/chapters/6_Conclusion.js deleted file mode 100644 index 431da98..0000000 --- a/js/chapters/6_Conclusion.js +++ /dev/null @@ -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" - }, - - ] - -}, - -); \ No newline at end of file diff --git a/js/chapters/6_Small_World.js b/js/chapters/6_Small_World.js new file mode 100644 index 0000000..c082984 --- /dev/null +++ b/js/chapters/6_Small_World.js @@ -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" + } + + ] +} + +); \ No newline at end of file diff --git a/js/chapters/5_Sandbox.js b/js/chapters/7_Sandbox.js similarity index 96% rename from js/chapters/5_Sandbox.js rename to js/chapters/7_Sandbox.js index 8648128..e459db8 100644 --- a/js/chapters/5_Sandbox.js +++ b/js/chapters/7_Sandbox.js @@ -1,4 +1,3 @@ -// 0 - INTRODUCTION SLIDES.push( { chapter: "Sandbox", diff --git a/js/chapters/8_Conclusion.js b/js/chapters/8_Conclusion.js new file mode 100644 index 0000000..102900d --- /dev/null +++ b/js/chapters/8_Conclusion.js @@ -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; + } +} + +); \ No newline at end of file diff --git a/js/chapters/7_Credits.js b/js/chapters/9_Credits.js similarity index 100% rename from js/chapters/7_Credits.js rename to js/chapters/9_Credits.js diff --git a/js/lib/helpers.js b/js/lib/helpers.js index e34d18d..8ed1b66 100644 --- a/js/lib/helpers.js +++ b/js/lib/helpers.js @@ -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){ diff --git a/js/main.js b/js/main.js index 119a17e..955e470 100644 --- a/js/main.js +++ b/js/main.js @@ -29,6 +29,6 @@ window.onload = function(){ window.requestAnimationFrame(update); // First slide! - slideshow.gotoChapter("Sandbox"); + slideshow.gotoChapter("Conclusion"); } \ No newline at end of file diff --git a/js/sim/Connection.js b/js/sim/Connection.js index 3094399..ebc66ae 100644 --- a/js/sim/Connection.js +++ b/js/sim/Connection.js @@ -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); + + } + + }; + } \ No newline at end of file diff --git a/js/sim/Peep.js b/js/sim/Peep.js index 28134b6..19dad28 100644 --- a/js/sim/Peep.js +++ b/js/sim/Peep.js @@ -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=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; + }; + } diff --git a/js/sim/Simulations.js b/js/sim/Simulations.js index 4a66be4..48d3dea 100644 --- a/js/sim/Simulations.js +++ b/js/sim/Simulations.js @@ -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(); + } + } }); }; diff --git a/js/slideshow/Navigation.js b/js/slideshow/Navigation.js index 0c0ced8..8579c76 100644 --- a/js/slideshow/Navigation.js +++ b/js/slideshow/Navigation.js @@ -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; diff --git a/js/slideshow/SandboxUI.js b/js/slideshow/SandboxUI.js index 23e6827..8d4c354 100644 --- a/js/slideshow/SandboxUI.js +++ b/js/slideshow/SandboxUI.js @@ -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";