YAY
This commit is contained in:
parent
74a6342e4a
commit
fd39f09979
|
@ -2,13 +2,14 @@ html, body{
|
|||
width:100%;
|
||||
height:100%;
|
||||
overflow: hidden;
|
||||
cursor: none;
|
||||
}
|
||||
body{
|
||||
margin:0;
|
||||
|
||||
font-family: "FuturaHandwritten";
|
||||
font-size: 22px;
|
||||
cursor: none;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
/* SIMULATION and SLIDESHOW */
|
||||
|
@ -32,13 +33,16 @@ body{
|
|||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
#simulations canvas, #slideshow div{
|
||||
#simulations canvas, #slideshow > div{
|
||||
position: absolute;
|
||||
}
|
||||
#slideshow .box.image{
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
#slideshow .box.button{
|
||||
#slideshow .next_button{
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
top: -10px;
|
||||
width: 300px;
|
||||
height: 20px;
|
||||
padding: 40px 0;
|
||||
|
@ -46,7 +50,7 @@ body{
|
|||
background-size: 100% auto;
|
||||
text-align: center;
|
||||
}
|
||||
#slideshow .box.button:hover{
|
||||
#slideshow .next_button:hover{
|
||||
background-position: 0 -100px;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,147 @@ Cursor is allowed to flow EVERYWHERE though...
|
|||
</body>
|
||||
</html>
|
||||
|
||||
<!-- - - - - - - - - - - - -->
|
||||
<!-- THE SLIDESHOW'S WORDS -->
|
||||
<!-- - - - - - - - - - - - -->
|
||||
|
||||
<!-- 0. Introduction -->
|
||||
|
||||
<words id="_0_title">
|
||||
the
|
||||
<br>
|
||||
WISDOM and/or MADNESS
|
||||
<br>
|
||||
of CROWDS
|
||||
</words>
|
||||
|
||||
<words id="_0_subtitle">
|
||||
playing time: 30 min • by nicky case, april 2018
|
||||
</words>
|
||||
|
||||
<words id="_0_loading">
|
||||
loading...
|
||||
</words>
|
||||
|
||||
<words id="_0_play">
|
||||
let's play! →
|
||||
</words>
|
||||
|
||||
<words id="_0_intro">
|
||||
Why is it that the <i>same</i> people,
|
||||
in <i>different</i> groups, can be kind, cruel, smart, stupid?
|
||||
In this explorable explanation,
|
||||
I'll show how the <i>network</i> of a group itself
|
||||
can shape the people caught in its web.
|
||||
<button onclick="slideshow.next()">NEXT</button>
|
||||
</words>
|
||||
|
||||
<!-- 1. Networks -->
|
||||
|
||||
<words id="_1_tutorial_start">
|
||||
blah blah blah blah blah<br>
|
||||
let's make a network of friends!
|
||||
</words>
|
||||
|
||||
<words id="_1_tutorial_connect">
|
||||
draw to connect
|
||||
</words>
|
||||
|
||||
<words id="_1_tutorial_disconnect">
|
||||
scratch to disconnect
|
||||
</words>
|
||||
|
||||
<words id="_1_tutorial_end">
|
||||
feel free to play around! when you're done,
|
||||
<next wiggle>let's continue →</next>
|
||||
</words>
|
||||
|
||||
<words id="_1_threshold">
|
||||
blah blah blah blah
|
||||
blah blah blah blah
|
||||
blah blah blah blah
|
||||
blah blah blah blah
|
||||
blah blah blah blah
|
||||
thresholds NOT COUNTING THEMSELVES
|
||||
</words>
|
||||
<words id="_1_threshold_count1">
|
||||
# of drinker friends / # of total friends
|
||||
</words>
|
||||
<words id="_1_threshold_count2">
|
||||
% of friends are drinkers
|
||||
</words>
|
||||
<words id="_1_threshold_count3">
|
||||
(black line shows the 50% "majority" mark)
|
||||
</words>
|
||||
<words id="_1_threshold_end">
|
||||
<next>and next...</next>
|
||||
</words>
|
||||
|
||||
<words id="_1_pre_puzzle">
|
||||
blah blah drinking
|
||||
<next>blah blah next</next>
|
||||
</words>
|
||||
|
||||
<words id="_1_puzzle">
|
||||
blah blah puzzle
|
||||
</words>
|
||||
<words id="_1_puzzle_metric">
|
||||
HOW MANY PEEPS FOOLED:
|
||||
</words>
|
||||
<words id="_1_puzzle_end">
|
||||
blah blah puzzle
|
||||
<next wiggle>a winrar is you</next>
|
||||
</words>
|
||||
|
||||
<words id="_1_post_puzzle">
|
||||
blah blah post-puzzle
|
||||
<next>simple contagion...</next>
|
||||
</words>
|
||||
|
||||
<!-- 2. Simple Contagions -->
|
||||
|
||||
<!-- 3. Complex Contagions -->
|
||||
|
||||
<!-- 4. Bonding & Bridging -->
|
||||
|
||||
<!-- 5. Sandbox -->
|
||||
|
||||
<!-- 6. Conclusion -->
|
||||
|
||||
<!-- 7. Credits -->
|
||||
|
||||
<!-- x. misc -->
|
||||
<words id="WIN">
|
||||
WIN
|
||||
</words>
|
||||
<words id="sim_start">
|
||||
start sim!
|
||||
</words>
|
||||
<words id="sim_next">
|
||||
next day >>
|
||||
</words>
|
||||
<words id="sim_reset">
|
||||
reset sim
|
||||
</words>
|
||||
|
||||
<!-- - - - - - - - - - - - - -->
|
||||
<!-- BONUS BOXES (footnotes) -->
|
||||
<!-- - - - - - - - - - - - - -->
|
||||
|
||||
<bonus>
|
||||
</bonus>
|
||||
|
||||
<!-- - - - - - -->
|
||||
<!-- GLOSSARY -->
|
||||
<!-- - - - - - -->
|
||||
|
||||
<glossary>
|
||||
</glossary>
|
||||
|
||||
<!-- - - - - -->
|
||||
<!-- SCRIPTS -->
|
||||
<!-- - - - - -->
|
||||
|
||||
<script src="js/lib/helpers.js"></script>
|
||||
<script src="js/lib/minpubsub.src.js"></script>
|
||||
<script src="js/lib/Key.js"></script>
|
||||
|
@ -70,60 +211,3 @@ Cursor is allowed to flow EVERYWHERE though...
|
|||
|
||||
<script src="js/main.js"></script>
|
||||
|
||||
<!-- - - - - - - - - - - - -->
|
||||
<!-- THE SLIDESHOW'S WORDS -->
|
||||
<!-- - - - - - - - - - - - -->
|
||||
|
||||
<!-- 0. Introduction -->
|
||||
<words id="_0a">
|
||||
Why is it that the <i>same</i> people,
|
||||
in <i>different</i> groups, can be kind, cruel, smart, stupid?
|
||||
In this explorable explanation,
|
||||
I'll show how the <i>network</i> of a group itself
|
||||
can shape the people caught in its web.
|
||||
<button onclick="slideshow.next()">NEXT</button>
|
||||
</words>
|
||||
<words id="_0b">
|
||||
herp derp herp derp
|
||||
</words>
|
||||
|
||||
<!-- 1. Networks -->
|
||||
<words id="_1_tutorial_start">
|
||||
blah blah blah blah blah<br>
|
||||
let's make a network of friends!
|
||||
</words>
|
||||
<words id="_1_tutorial_connect">
|
||||
draw to connect
|
||||
</words>
|
||||
<words id="_1_tutorial_disconnect">
|
||||
scratch to disconnect
|
||||
</words>
|
||||
<words id="_1_tutorial_end">
|
||||
feel free to play around! when you're done,<br>
|
||||
</words>
|
||||
<words id="_1_tutorial_next">
|
||||
let's continue →
|
||||
</words>
|
||||
|
||||
<!-- 2. Simple Contagions -->
|
||||
<!-- 3. Complex Contagions -->
|
||||
<!-- 4. Bonding & Bridging -->
|
||||
<!-- 5. Sandbox -->
|
||||
<!-- 6. Conclusion -->
|
||||
|
||||
<!-- 7. Credits -->
|
||||
|
||||
<!-- - - - - - - - - - - - - -->
|
||||
<!-- BONUS BOXES (footnotes) -->
|
||||
<!-- - - - - - - - - - - - - -->
|
||||
|
||||
<bonus>
|
||||
</bonus>
|
||||
|
||||
<!-- - - - - - -->
|
||||
<!-- GLOSSARY -->
|
||||
<!-- - - - - - -->
|
||||
|
||||
<glossary>
|
||||
</glossary>
|
||||
|
||||
|
|
|
@ -20,7 +20,11 @@ SLIDES.push(
|
|||
type:"sim",
|
||||
x:0, y:10,
|
||||
fullscreen: true,
|
||||
network: {"contagion":0,"peeps":[[44,184,0],[155,215,0],[237,105,0],[309,213,0],[646,211,0],[328,305,0],[629,308,0],[417,111,0],[539,375,0],[216,299,0],[107,311,0],[-61,220,0],[87,452,0],[733,147,0],[760,293,0],[753,448,0],[744,46,0],[134,33,0],[929,181,0],[848,111,0],[1013,330,0],[880,269,0],[538,128,0],[208,391,0],[853,356,0]],"connections":[[5,6]]}
|
||||
network: {
|
||||
"contagion":0,
|
||||
"peeps":[[44,184,0],[155,215,0],[237,105,0],[309,213,0],[646,211,0],[328,305,0],[629,308,0],[417,111,0],[539,375,0],[216,299,0],[107,311,0],[-61,220,0],[87,452,0],[733,147,0],[760,293,0],[753,448,0],[744,46,0],[134,33,0],[929,181,0],[848,111,0],[1013,330,0],[880,269,0],[538,128,0],[208,391,0],[853,356,0]],
|
||||
"connections":[[5,6]]
|
||||
}
|
||||
},
|
||||
|
||||
// "Connect" instruction (words & picture)
|
||||
|
@ -52,18 +56,8 @@ SLIDES.push(
|
|||
type:"box",
|
||||
id:"end_words",
|
||||
text:"_1_tutorial_end", x:230, y:425, w:500, h:70, align:"center",
|
||||
hidden:true
|
||||
},
|
||||
{
|
||||
type:"box",
|
||||
id:"end_button",
|
||||
button:"large", wiggle:true,
|
||||
text:"_1_tutorial_next", x:330, y:440,
|
||||
hidden:true,
|
||||
onclick:function(){
|
||||
slideshow.next();
|
||||
}
|
||||
},
|
||||
//hidden:true
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
|
@ -93,7 +87,7 @@ SLIDES.push(
|
|||
// If did both, show end
|
||||
if(state.canConnect && state.canDisconnect){
|
||||
boxes.showChildByID("end_words");
|
||||
boxes.showChildByID("end_button");
|
||||
//boxes.showChildByID("end_button");
|
||||
}
|
||||
|
||||
// update # of connections in state
|
||||
|
@ -104,20 +98,115 @@ SLIDES.push(
|
|||
},
|
||||
|
||||
// PLAY AROUND: how the "threshold" model workds
|
||||
// diagonal
|
||||
{
|
||||
|
||||
chapter: "Networks-Threshold",
|
||||
|
||||
clear:true,
|
||||
add:[
|
||||
|
||||
// TEXT
|
||||
{
|
||||
type:"box",
|
||||
id:"_1_threshold",
|
||||
text:"_1_threshold", x:80, y:25, w:300
|
||||
},
|
||||
{
|
||||
type:"box",
|
||||
id:"_1_threshold_end",
|
||||
text:"_1_threshold_end", x:80, y:400, w:300
|
||||
},
|
||||
|
||||
// SIMULATION: THRESHOLD
|
||||
{
|
||||
type:"sim",
|
||||
x:400, y:70,
|
||||
fullscreen: true,
|
||||
network: {
|
||||
"contagion":0.5,
|
||||
"peeps":[[95,65,0],[417,380,1],[52,340,0],[399,92,1]],
|
||||
"connections":[[2,3],[3,1]],
|
||||
},
|
||||
options:{
|
||||
infectedFrame: 2,
|
||||
scale: 2
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
// PUZZLE: The "Majority Illusion" puzzle
|
||||
// pre-puzzle ramble
|
||||
{
|
||||
clear:true
|
||||
remove:[
|
||||
{ type:"box", id:"_1_threshold" },
|
||||
{ type:"box", id:"_1_threshold_end" }
|
||||
],
|
||||
add:[
|
||||
{
|
||||
type:"box",
|
||||
id:"_1_pre_puzzle",
|
||||
text:"_1_pre_puzzle", x:80, y:25, w:325, h:540
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// post-puzzle ramble
|
||||
|
||||
// PUZZLE: The "Majority Illusion" puzzle
|
||||
{
|
||||
clear:true
|
||||
|
||||
chapter: "Networks-Majority",
|
||||
|
||||
clear:true,
|
||||
add:[
|
||||
|
||||
// The puzzle!
|
||||
{
|
||||
id:"puzzle",
|
||||
type:"sim",
|
||||
x:480-250, y:25,
|
||||
fullscreen: true,
|
||||
network: {
|
||||
"contagion":0.5,
|
||||
"peeps":[[106,106,1],[239,52,1],[376,110,1],[27,221,0],[54,365,0],[162,458,0],[308,467,0],[407,371,0],[453,241,0]],
|
||||
"connections":[],
|
||||
},
|
||||
options:{
|
||||
infectedFrame: 2,
|
||||
scale: 1.5
|
||||
}
|
||||
},
|
||||
|
||||
// Done? Let's go... (hidden at first...)
|
||||
{
|
||||
type:"box",
|
||||
id:"_1_puzzle_end",
|
||||
text:"_1_puzzle_end", x:680, y:430, w:300, align:"center"
|
||||
//hidden:true
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
},
|
||||
|
||||
// post-puzzle ramble, introduce simple contagion
|
||||
{
|
||||
remove:[
|
||||
{ type:"box", id:"_1_puzzle_end" }
|
||||
],
|
||||
move:[
|
||||
// shift sim to side
|
||||
{type:"sim", id:"puzzle", x:0}
|
||||
],
|
||||
add:[
|
||||
// new text
|
||||
{
|
||||
type:"box",
|
||||
id:"_1_post_puzzle",
|
||||
text:"_1_post_puzzle", x:600, y:0, w:300
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
);
|
|
@ -0,0 +1,7 @@
|
|||
// 0 - INTRODUCTION
|
||||
SLIDES.push(
|
||||
{
|
||||
chapter: "Simple",
|
||||
clear:true
|
||||
}
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
// 0 - INTRODUCTION
|
||||
SLIDES.push(
|
||||
{
|
||||
chapter: "Complex"
|
||||
}
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
// 0 - INTRODUCTION
|
||||
SLIDES.push(
|
||||
{
|
||||
chapter: "BB"
|
||||
}
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
// 0 - INTRODUCTION
|
||||
SLIDES.push(
|
||||
{
|
||||
chapter: "Sandbox"
|
||||
}
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
// 0 - INTRODUCTION
|
||||
SLIDES.push(
|
||||
{
|
||||
chapter: "Conclusion"
|
||||
}
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
// 0 - INTRODUCTION
|
||||
SLIDES.push(
|
||||
{
|
||||
chapter: "Credits"
|
||||
}
|
||||
);
|
|
@ -45,4 +45,10 @@ function cloneObject(obj){
|
|||
// Get words
|
||||
function getWords(wordsID){
|
||||
return $("words#"+wordsID).innerHTML;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove from array
|
||||
function removeFromArray(array, item){
|
||||
var index = array.indexOf(item);
|
||||
if(index>=0) array.splice(index,1);
|
||||
}
|
||||
|
|
|
@ -21,14 +21,9 @@ function Connection(config){
|
|||
|
||||
// Draw
|
||||
self.draw = function(ctx){
|
||||
/*
|
||||
ctx.strokeStyle = "#444";
|
||||
ctx.lineWidth = self.uncuttable ? 6 : 3; // thick=uncuttable
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(self.from.x, self.from.y);
|
||||
ctx.lineTo(self.to.x, self.to.y);
|
||||
ctx.stroke();
|
||||
*/
|
||||
|
||||
var s = self.sim.options.scale || 1;
|
||||
|
||||
ctx.save();
|
||||
ctx.translate(self.from.x, self.from.y);
|
||||
var dx = self.to.x - self.from.x;
|
||||
|
@ -37,9 +32,11 @@ function Connection(config){
|
|||
var dist = Math.sqrt(dx*dx + dy*dy);
|
||||
self.sprite.scaleX = dist/300;
|
||||
self.sprite.scaleY = self.uncuttable ? 1 : 0.5; // thick=uncuttable
|
||||
//self.sprite.scaleY *= s;
|
||||
self.sprite.rotation = a;
|
||||
self.sprite.draw(ctx);
|
||||
ctx.restore();
|
||||
|
||||
};
|
||||
|
||||
// Hit Test with a LINE SEGMENT
|
||||
|
|
|
@ -95,14 +95,9 @@ function ConnectorCutter(config){
|
|||
|
||||
// Connecting!
|
||||
if(self.state==1){
|
||||
/*ctx.strokeStyle = "#ccc";
|
||||
ctx.lineWidth = 3;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(self.connectFrom.x, self.connectFrom.y);
|
||||
ctx.lineTo(self.connectTo.x, self.connectTo.y);
|
||||
ctx.stroke();*/
|
||||
var tempConnection = new Connection({
|
||||
from:self.connectFrom, to:self.connectTo
|
||||
from:self.connectFrom, to:self.connectTo,
|
||||
sim:self.sim
|
||||
});
|
||||
ctx.save();
|
||||
ctx.globalAlpha = 0.5;
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
var PEEP_STATE_COLORS = {
|
||||
1: "#ccc",
|
||||
2: "#dd4040"
|
||||
};
|
||||
|
||||
function Peep(config){
|
||||
|
||||
var self = this;
|
||||
|
@ -52,6 +47,21 @@ function Peep(config){
|
|||
if(friend.infected) self.numInfectedFriends++;
|
||||
});
|
||||
|
||||
// Past threshold?
|
||||
self.isPastThreshold = false;
|
||||
if(self.sim.contagion==0){
|
||||
// simple
|
||||
if(self.numInfectedFriends>0) self.isPastThreshold = true;
|
||||
}else{
|
||||
// complex
|
||||
if(self.numFriends>0){
|
||||
var ratio = self.numInfectedFriends/self.numFriends;
|
||||
if(ratio>=self.sim.contagion-0.0001){ // floating point errors
|
||||
self.isPastThreshold = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Body Sprite
|
||||
|
@ -61,22 +71,50 @@ function Peep(config){
|
|||
});
|
||||
self.sprite.pivotX = 100;
|
||||
self.sprite.pivotY = 100;
|
||||
self.sprite.scale = 0.3;
|
||||
var _initSpriteScale = 0.3;
|
||||
self.sprite.scale = _initSpriteScale;
|
||||
//self.sprite.gotoFrame(1);
|
||||
|
||||
// Draw
|
||||
var radius = 25;
|
||||
var barWidth = 30;
|
||||
var barWidth = radius*1.75;
|
||||
var barHeight = 10;
|
||||
var bodyRotation = Math.TAU*Math.random();
|
||||
var PEEP_COLORS = [
|
||||
"#B4B4B4", // gray
|
||||
"#F73C50", // red
|
||||
"#FEE576", // yellow
|
||||
"#86F5FB", // blue
|
||||
"#7DE74E", // green
|
||||
"#FBCBDC" // pink
|
||||
];
|
||||
self.draw = function(ctx){
|
||||
|
||||
ctx.save();
|
||||
ctx.translate(self.x, self.y);
|
||||
|
||||
var s;
|
||||
if(s = self.sim.options.scale) ctx.scale(s,s);
|
||||
|
||||
// Circle
|
||||
var infectedFrame = self.sim.options.infectedFrame || 1;
|
||||
var infectedColor = PEEP_COLORS[infectedFrame];
|
||||
var myFrame = self.infected ? infectedFrame : 0;
|
||||
var myColor = PEEP_COLORS[myFrame];
|
||||
self.sprite.rotation = bodyRotation;
|
||||
self.sprite.gotoFrame(self.infected ? 1 : 0);
|
||||
if(self.isPastThreshold){ // highlight!
|
||||
|
||||
ctx.globalAlpha = 0.4;
|
||||
self.sprite.scale = _initSpriteScale*1.25;
|
||||
|
||||
self.sprite.gotoFrame(infectedFrame);
|
||||
self.sprite.draw(ctx);
|
||||
|
||||
ctx.globalAlpha = 1;
|
||||
self.sprite.scale = _initSpriteScale;
|
||||
|
||||
}
|
||||
self.sprite.gotoFrame(myFrame);
|
||||
self.sprite.draw(ctx);
|
||||
|
||||
// Face
|
||||
|
@ -91,63 +129,57 @@ function Peep(config){
|
|||
// LABEL FOR INFECTED/FRIENDS, BAR, AND CONTAGION LEVEL //
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
// DON'T show bar if simple contagion
|
||||
if(self.sim.contagion>0){
|
||||
|
||||
ctx.save();
|
||||
|
||||
// Say: Infected/Friends
|
||||
ctx.translate(0,-42);
|
||||
var labelNum = self.numInfectedFriends+"/"+self.numFriends;
|
||||
var labelPercent = "";
|
||||
if(self.numFriends>0){
|
||||
labelPercent = Math.round(100*(self.numInfectedFriends/self.numFriends)) + "%";
|
||||
}
|
||||
ctx.font = '12px sans-serif';
|
||||
ctx.fillStyle = myColor;
|
||||
ctx.textAlign = "center";
|
||||
var bgColor = "#eee";
|
||||
var uiColor = "#666";
|
||||
|
||||
// Say: Infected/Friends (% then n/n)
|
||||
ctx.translate(0,-43);
|
||||
ctx.font = '10px FuturaHandwritten';
|
||||
ctx.fillStyle = uiColor;
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.fontWeight = "bold";
|
||||
ctx.fillText(labelNum, 0, 0);
|
||||
ctx.textAlign = "center";
|
||||
if(self.numFriends>0){
|
||||
var labelNum = self.numInfectedFriends+"/"+self.numFriends;
|
||||
var labelPercent = Math.round(100*(self.numInfectedFriends/self.numFriends)) + "%";
|
||||
var label = labelNum + "=" + labelPercent;
|
||||
ctx.fillText(label, 0, 0);
|
||||
}else{
|
||||
ctx.fillText("∅", 0, -1);
|
||||
}
|
||||
|
||||
// A nice bar
|
||||
ctx.translate(0,12);
|
||||
ctx.lineWidth = 1;
|
||||
|
||||
// the white fill
|
||||
ctx.fillStyle = "#fff";
|
||||
// the gray bg
|
||||
ctx.translate(0,10);
|
||||
ctx.fillStyle = bgColor;
|
||||
ctx.beginPath();
|
||||
ctx.rect(-barWidth/2, -barHeight/2, barWidth, barHeight);
|
||||
ctx.fill();
|
||||
|
||||
// The color fills
|
||||
// the color fill
|
||||
if(self.numFriends>0){
|
||||
ctx.fillStyle = PEEP_STATE_COLORS[2]; // state = 2 infected
|
||||
ctx.fillStyle = infectedColor;
|
||||
ctx.beginPath();
|
||||
ctx.rect(-barWidth/2, -barHeight/2, barWidth*(self.numInfectedFriends/self.numFriends), barHeight);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
// The outline
|
||||
ctx.strokeStyle = myColor;
|
||||
ctx.beginPath();
|
||||
if(self.numFriends>0){
|
||||
ctx.rect(-barWidth/2, -barHeight/2, barWidth, barHeight);
|
||||
}else{
|
||||
ctx.rect(-barWidth/2, 0, barWidth, 0);
|
||||
}
|
||||
ctx.stroke();
|
||||
|
||||
// a pointer for contagion level
|
||||
ctx.translate(0, barHeight/2+2);
|
||||
self._drawThreshold(ctx, self.sim.contagion);
|
||||
|
||||
// Percent
|
||||
ctx.font = '8px sans-serif';
|
||||
ctx.fillStyle = "rgba(0,0,0,0.8)";
|
||||
ctx.textAlign = "center";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.fontWeight = "bold";
|
||||
ctx.fillText(labelPercent, 0, -6);
|
||||
ctx.translate(0, -barHeight/2);
|
||||
ctx.save();
|
||||
ctx.translate(barWidth*self.sim.contagion - barWidth/2, 0);
|
||||
ctx.lineCap = "butt";
|
||||
ctx.strokeStyle = uiColor;
|
||||
ctx.lineWidth = 1;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0,0);
|
||||
ctx.lineTo(0,barHeight);
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
|
||||
ctx.restore();
|
||||
|
||||
|
@ -156,19 +188,6 @@ function Peep(config){
|
|||
ctx.restore();
|
||||
|
||||
};
|
||||
self._drawThreshold = function(ctx, threshold){
|
||||
ctx.save();
|
||||
ctx.translate(barWidth*threshold - barWidth/2, 0);
|
||||
|
||||
ctx.strokeStyle = "#000"; //PEEP_STATE_COLORS[2];
|
||||
ctx.lineWidth = 1;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0,0);
|
||||
ctx.lineTo(0,-14);
|
||||
ctx.stroke();
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
// Hit Test
|
||||
self.hitTest = function(x,y,buffer){
|
||||
|
@ -177,6 +196,8 @@ function Peep(config){
|
|||
var dy = self.y-y;
|
||||
var dist2 = dx*dx+dy*dy;
|
||||
var r = radius+buffer;
|
||||
var s;
|
||||
if(s = self.sim.options.scale) r*=s;
|
||||
return (dist2<r*r);
|
||||
};
|
||||
|
||||
|
|
|
@ -45,6 +45,17 @@ function Simulations(){
|
|||
});
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
// HELPERS AND STUFF //
|
||||
///////////////////////
|
||||
|
||||
// Get Child!
|
||||
self.getChildByID = function(id){
|
||||
return self.sims.find(function(sim){
|
||||
return sim.id==id;
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function Sim(config){
|
||||
|
@ -53,17 +64,17 @@ function Sim(config){
|
|||
self.config = config;
|
||||
self.networkConfig = config.network;
|
||||
self.container = config.container;
|
||||
self.options = config.options || {};
|
||||
|
||||
self.id = config.id;
|
||||
|
||||
// Canvas
|
||||
self.fullscreenOffset = {x:0, y:0};
|
||||
if(config.fullscreen){
|
||||
var container = $("#simulations_container");
|
||||
var simOffset = self.container.dom.getBoundingClientRect();
|
||||
self.canvas = createCanvas(container.clientWidth, container.clientHeight);
|
||||
self.canvas.style.left = -simOffset.x;
|
||||
self.canvas.style.top = -simOffset.y;
|
||||
self.fullscreenOffset.x = config.x + simOffset.x;
|
||||
self.fullscreenOffset.y = config.y + simOffset.y;
|
||||
}else{
|
||||
self.canvas = createCanvas(config.width||500, config.height||500);
|
||||
self.canvas.style.left = config.x || 0;
|
||||
|
@ -122,10 +133,12 @@ function Sim(config){
|
|||
self.mouse.lastX -= canvasBounds.x;
|
||||
self.mouse.lastY -= canvasBounds.y;
|
||||
if(config.fullscreen){
|
||||
self.mouse.x -= self.fullscreenOffset.x;
|
||||
self.mouse.y -= self.fullscreenOffset.y;
|
||||
self.mouse.lastX -= self.fullscreenOffset.x;
|
||||
self.mouse.lastY -= self.fullscreenOffset.y;
|
||||
var fullscreenOffsetX = config.x + simOffset.x;
|
||||
var fullscreenOffsetY = config.y + simOffset.y;
|
||||
self.mouse.x -= fullscreenOffsetX;
|
||||
self.mouse.y -= fullscreenOffsetY;
|
||||
self.mouse.lastX -= fullscreenOffsetX;
|
||||
self.mouse.lastY -= fullscreenOffsetY;
|
||||
}
|
||||
|
||||
// Connector-Cutter
|
||||
|
@ -161,7 +174,9 @@ function Sim(config){
|
|||
ctx.save();
|
||||
ctx.scale(2,2);
|
||||
if(config.fullscreen){
|
||||
ctx.translate(self.fullscreenOffset.x, self.fullscreenOffset.y);
|
||||
var fullscreenOffsetX = config.x + simOffset.x;
|
||||
var fullscreenOffsetY = config.y + simOffset.y;
|
||||
ctx.translate(fullscreenOffsetX, fullscreenOffsetY);
|
||||
}
|
||||
|
||||
// Draw all of it!
|
||||
|
@ -234,7 +249,11 @@ function Sim(config){
|
|||
var toIndex = self.peeps.indexOf(c.to);
|
||||
savedNetwork.connections.push([fromIndex, toIndex]);
|
||||
});
|
||||
return JSON.stringify(savedNetwork);
|
||||
return '{\n'+
|
||||
'\t"contagion":'+savedNetwork.contagion+",\n"+
|
||||
'\t"peeps":'+JSON.stringify(savedNetwork.peeps)+",\n"+
|
||||
'\t"connections":'+JSON.stringify(savedNetwork.connections)+",\n"+
|
||||
'}';
|
||||
};
|
||||
|
||||
////////////////
|
||||
|
@ -249,7 +268,7 @@ function Sim(config){
|
|||
};
|
||||
self.removePeep = function(peep){
|
||||
self.removeAllConnectedTo(peep); // delete all connections
|
||||
self.peeps.splice(self.peeps.indexOf(peep),1); // BYE peep
|
||||
removeFromArray(self.peeps, peep); // BYE peep
|
||||
};
|
||||
self.addConnection = function(from, to, uncuttable){
|
||||
|
||||
|
|
|
@ -48,10 +48,21 @@ function Boxes(){
|
|||
box.style.backgroundImage = "url("+config.img+")"
|
||||
}
|
||||
|
||||
// button:
|
||||
if(config.button){
|
||||
box.classList.add("button");
|
||||
if(config.onclick) box.onclick = config.onclick;
|
||||
// Replace "next" buttons!
|
||||
var next;
|
||||
if(next = box.querySelector("next")){
|
||||
|
||||
// Create next button
|
||||
var nextButton = document.createElement("div");
|
||||
nextButton.className = "next_button";
|
||||
nextButton.innerHTML = next.innerHTML;
|
||||
nextButton.onclick = function(){
|
||||
slideshow.next();
|
||||
};
|
||||
|
||||
// Replace it in parent!
|
||||
next.parentNode.replaceChild(nextButton, next);
|
||||
|
||||
}
|
||||
|
||||
// Add to array
|
||||
|
@ -80,5 +91,10 @@ function Boxes(){
|
|||
var toHide = self.getChildByID(id);
|
||||
toHide.style.display = "none";
|
||||
};
|
||||
self.removeChildByID = function(id){
|
||||
var removeBox = self.getChildByID(id);
|
||||
self.dom.removeChild(removeBox);
|
||||
removeFromArray(self.boxes, removeBox);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,36 @@ function Slideshow(){
|
|||
// Clear?
|
||||
if(slide.clear) self.clear();
|
||||
|
||||
// Remove stuff
|
||||
slide.remove = slide.remove || [];
|
||||
slide.remove.forEach(function(childConfig){
|
||||
switch(childConfig.type){
|
||||
case "box":
|
||||
self.boxes.removeChildByID(childConfig.id);
|
||||
break;
|
||||
case "sim":
|
||||
//self.simulations.removeChildByID(childConfig);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// Move stuff
|
||||
slide.move = slide.move || [];
|
||||
slide.move.forEach(function(childConfig){
|
||||
switch(childConfig.type){
|
||||
case "box":
|
||||
//self.boxes.add(childConfig);
|
||||
break;
|
||||
case "sim":
|
||||
var sim = self.simulations.getChildByID(childConfig.id);
|
||||
sim.config.x = (childConfig.x===undefined) ? sim.config.x : childConfig.x;
|
||||
sim.config.y = (childConfig.y===undefined) ? sim.config.y : childConfig.y;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// Add stuff
|
||||
slide.add = slide.add || [];
|
||||
slide.add.forEach(function(childConfig){
|
||||
switch(childConfig.type){
|
||||
case "box":
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 240 KiB |
Loading…
Reference in New Issue