heck yeah saving and stuff
This commit is contained in:
parent
e95c54cf07
commit
0a5bd013b8
|
@ -1,9 +1,14 @@
|
|||
html, body{
|
||||
width:100%;
|
||||
height:100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
body{
|
||||
margin:0;
|
||||
|
||||
font-family: "FuturaHandwritten";
|
||||
font-size: 20px;
|
||||
cursor: none !important;
|
||||
font-size: 22px;
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
/* SIMULATION and SLIDESHOW */
|
||||
|
@ -12,6 +17,8 @@ body{
|
|||
top:0; left:0;
|
||||
width: 100%;
|
||||
height: calc(100% - 60px);
|
||||
overflow: hidden;
|
||||
cursor: none;
|
||||
}
|
||||
#simulations, #slideshow{
|
||||
position: absolute;
|
||||
|
@ -44,6 +51,7 @@ body{
|
|||
width:100px;
|
||||
height:100px;
|
||||
pointer-events: none;
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
/* THIS THING'S WORDS */
|
||||
|
|
|
@ -45,6 +45,7 @@ Cursor is allowed to flow EVERYWHERE though...
|
|||
|
||||
<script src="js/lib/helpers.js"></script>
|
||||
<script src="js/lib/minpubsub.src.js"></script>
|
||||
<script src="js/lib/Key.js"></script>
|
||||
<script src="js/lib/Mouse.js"></script>
|
||||
<script src="js/lib/Sprite.js"></script>
|
||||
|
||||
|
@ -57,9 +58,16 @@ Cursor is allowed to flow EVERYWHERE though...
|
|||
<!--script src="js/sim/Game.js"></script-->
|
||||
<script src="js/sim/Simulations.js"></script>
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
|
||||
<script src="js/chapters/0_Introduction.js"></script>
|
||||
<script src="js/chapters/1_Networks.js"></script>
|
||||
<script src="js/chapters/2_Simple_Contagion.js"></script>
|
||||
<script src="js/chapters/3_Complex_Contagion.js"></script>
|
||||
<script src="js/chapters/4_Bonding_And_Bridging.js"></script>
|
||||
<script src="js/chapters/5_Sandbox.js"></script>
|
||||
<script src="js/chapters/6_Conclusion.js"></script>
|
||||
<script src="js/chapters/7_Credits.js"></script>
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
|
||||
<!-- - - - - - - - - - - - -->
|
||||
<!-- THE SLIDESHOW'S WORDS -->
|
||||
|
|
|
@ -1,20 +1,9 @@
|
|||
// 0 - INTRODUCTION
|
||||
SLIDES.push(
|
||||
{
|
||||
chapter: "1",
|
||||
chapter: "Introduction",
|
||||
boxes:[
|
||||
{words:"_0a", x:20, y:70, w:300, h:200}
|
||||
],
|
||||
sims:[
|
||||
{
|
||||
x: 400,
|
||||
y: 10,
|
||||
network: {
|
||||
contagion: 0.25,
|
||||
peeps: [ [100,100],[200,200],[400,150] ],
|
||||
connections: [ [0,1] ]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// 0 - INTRODUCTION
|
||||
SLIDES.push(
|
||||
{
|
||||
chapter: "Networks",
|
||||
boxes:[
|
||||
{words:"_1a", x:280, y:0, w:400, align:"center"}
|
||||
],
|
||||
sims:[
|
||||
{
|
||||
x: 0,
|
||||
y: 10,
|
||||
fullscreen: true,
|
||||
network: {"contagion":0,"peeps":[[408,87,0],[340,472,0],[285,402,0],[339,76,0],[214,266,0],[219,181,0],[594,146,0],[256,339,0],[273,114,0],[519,137,0],[450,163,0],[635,278,0],[640,199,0],[508,422,0],[438,445,0],[588,360,0],[858,39,0],[902,137,0],[890,344,0],[922,242,0],[390,299,1]],"connections":[[1,2],[2,7],[7,4],[4,5],[5,8],[8,3],[3,0],[0,10],[9,6],[9,10],[6,12],[12,11],[11,15],[15,13],[13,14],[14,1]]},
|
||||
onupdate: function(sim){
|
||||
if(sim.connections.length>5){
|
||||
//console.log("WIN");
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
|
@ -0,0 +1,20 @@
|
|||
//////////////////////////////
|
||||
// KEYS (it's a secret) //////
|
||||
//////////////////////////////
|
||||
|
||||
var KEYS = {
|
||||
32: "space",
|
||||
49: "1",
|
||||
50: "2",
|
||||
8: "delete"
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", function(event){
|
||||
var key = KEYS[event.keyCode];
|
||||
if(key) publish("key/down/"+key);
|
||||
});
|
||||
|
||||
window.addEventListener("keyup", function(event){
|
||||
var key = KEYS[event.keyCode];
|
||||
if(key) publish("key/up/"+key);
|
||||
});
|
|
@ -6,22 +6,19 @@ var Mouse = {
|
|||
x:0, y:0,
|
||||
pressed:false
|
||||
};
|
||||
Mouse.ondown = function(){}; // add your own callback
|
||||
Mouse.onmove = function(){}; // add your own callback
|
||||
Mouse.onup = function(){}; // add your own callback
|
||||
Mouse._ondown = function(event){
|
||||
Mouse.ondown = function(event){
|
||||
Mouse.pressed = true;
|
||||
Mouse._onmove(event);
|
||||
Mouse.ondown();
|
||||
Mouse.onmove(event);
|
||||
publish("mouse/down");
|
||||
};
|
||||
Mouse._onmove = function(event){
|
||||
Mouse.onmove = function(event){
|
||||
Mouse.x = event.clientX;
|
||||
Mouse.y = event.clientY;
|
||||
Mouse.onmove();
|
||||
publish("mouse/move");
|
||||
};
|
||||
Mouse._onup = function(event){
|
||||
Mouse.onup = function(event){
|
||||
Mouse.pressed = false;
|
||||
Mouse.onup();
|
||||
publish("mouse/up");
|
||||
};
|
||||
Mouse.update = function(){
|
||||
|
||||
|
@ -50,15 +47,15 @@ function _touchWrapper(callback){
|
|||
Mouse.init = function(target){
|
||||
|
||||
// Regular mouse
|
||||
target.addEventListener("mousedown", Mouse._ondown);
|
||||
target.addEventListener("mousemove", Mouse._onmove);
|
||||
window.addEventListener("mouseup", Mouse._onup);
|
||||
target.addEventListener("mousedown", Mouse.ondown);
|
||||
target.addEventListener("mousemove", Mouse.onmove);
|
||||
window.addEventListener("mouseup", Mouse.onup);
|
||||
|
||||
// Touch events
|
||||
target.addEventListener("touchstart", _touchWrapper(Mouse._ondown), false);
|
||||
target.addEventListener("touchmove", _touchWrapper(Mouse._onmove), false);
|
||||
target.addEventListener("touchstart", _touchWrapper(Mouse.ondown), false);
|
||||
target.addEventListener("touchmove", _touchWrapper(Mouse.onmove), false);
|
||||
document.body.addEventListener("touchend", function(){
|
||||
Mouse._onup();
|
||||
Mouse.onup();
|
||||
}, false);
|
||||
|
||||
};
|
|
@ -22,8 +22,8 @@ function createCanvas(canvas, width, height){
|
|||
|
||||
// The "canvas" arg not provided? make a new one!
|
||||
if(arguments.length==2){
|
||||
width = arguments[0];
|
||||
height = arguments[1];
|
||||
width = arguments[0];
|
||||
canvas = document.createElement("canvas");
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Copyright(c) 2011 Daniel Lamb <daniellmb.com>
|
||||
* MIT Licensed
|
||||
*/
|
||||
window.c_ = {}; // NICKY - UNIT TESTING
|
||||
(function (context) {
|
||||
var MinPubSub = {};
|
||||
|
||||
|
|
|
@ -27,6 +27,6 @@ window.onload = function(){
|
|||
window.requestAnimationFrame(update);
|
||||
|
||||
// First slide!
|
||||
slideshow.goto(0);
|
||||
slideshow.gotoChapter("Networks");
|
||||
|
||||
}
|
|
@ -48,28 +48,4 @@ function Connection(config){
|
|||
|
||||
};
|
||||
|
||||
}
|
||||
/*
|
||||
Connection.getConnected = function(peep){
|
||||
var results = [];
|
||||
for(var i=0; i<connections.length; i++){ // in either direction
|
||||
var c = connections[i];
|
||||
if(c.from==peep) results.push(c.to);
|
||||
if(c.to==peep) results.push(c.from);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
function removeAllConnectedTo(peep){
|
||||
for(var i=connections.length-1; i>=0; i--){ // backwards index coz we're deleting
|
||||
var c = connections[i];
|
||||
if(c.from==peep || c.to==peep){ // in either direction
|
||||
connections.splice(i,1); // remove!
|
||||
}
|
||||
}
|
||||
}
|
||||
function _makeUncuttable(arrayOfConnections){
|
||||
for(var i=0; i<arrayOfConnections.length; i++){
|
||||
arrayOfConnections[i].push(true);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -20,7 +20,7 @@ function ConnectorCutter(config){
|
|||
if(mouse.justPressed && self.state===0){
|
||||
|
||||
// Clicked on a peep?
|
||||
var peepClicked = self.sim.getHoveredPeep(20);
|
||||
var peepClicked = self.sim.getHoveredPeep(0);
|
||||
if(peepClicked){
|
||||
self.state = 1; // START CONNECTING
|
||||
self.connectFrom = peepClicked;
|
||||
|
@ -48,7 +48,7 @@ function ConnectorCutter(config){
|
|||
|
||||
// In "NORMAL" state... tell Pencil what frame to go to
|
||||
if(self.state==0){
|
||||
var peepHovered = self.sim.getHoveredPeep(20); // buffer of 20px
|
||||
var peepHovered = self.sim.getHoveredPeep(0);
|
||||
pencil.gotoFrame( peepHovered ? 1 : 0 );
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ function ConnectorCutter(config){
|
|||
if(self.state==1){
|
||||
|
||||
// Connect to a nearby hovered peep?
|
||||
var peepHovered = self.sim.getHoveredPeep(20); // buffer of 20px
|
||||
var peepHovered = self.sim.getHoveredPeep(20);
|
||||
if(peepHovered==self.connectFrom) peepHovered=null; // if same, nah
|
||||
self.connectTo = peepHovered ? peepHovered : mouse;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ function Peep(config){
|
|||
// Properties
|
||||
self.x = config.x;
|
||||
self.y = config.y;
|
||||
self.infected = config.infected;
|
||||
self.infected = !!config.infected;
|
||||
self.sim = config.sim;
|
||||
|
||||
// Update:
|
||||
|
@ -107,7 +107,7 @@ function Peep(config){
|
|||
// LABEL FOR INFECTED/FRIENDS, BAR, AND CONTAGION LEVEL //
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
//if(!_hack_HIDE_BARS && !self._hack_TESTED){
|
||||
if(self.sim.contagion>0){
|
||||
|
||||
ctx.save();
|
||||
|
||||
|
@ -167,7 +167,7 @@ function Peep(config){
|
|||
|
||||
ctx.restore();
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
|
||||
|
@ -202,14 +202,3 @@ function Peep(config){
|
|||
};
|
||||
|
||||
}
|
||||
function _mouseOverPeep(buffer){
|
||||
var result;
|
||||
peeps.forEach(function(peep){
|
||||
if(peep.hitTest(Mouse.x, Mouse.y, buffer)) result=peep;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
function removePeep(peep){
|
||||
removeAllConnectedTo(peep); // remove connections first
|
||||
peeps.splice(peeps.indexOf(peep),1); // BYE peep
|
||||
}
|
|
@ -54,10 +54,21 @@ function Sim(config){
|
|||
self.networkConfig = config.network;
|
||||
|
||||
// Canvas
|
||||
self.canvas = createCanvas(500, 500);
|
||||
self.canvas.style.left = config.x || 0;
|
||||
self.canvas.style.top = config.y || 0;
|
||||
self.canvas.style.border = "1px solid #ccc";
|
||||
self.fullscreenOffset = {x:0, y:0};
|
||||
if(config.fullscreen){
|
||||
var container = $("#simulations_container");
|
||||
var simOffset = simulations.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;
|
||||
self.canvas.style.top = config.y || 0;
|
||||
}
|
||||
//self.canvas.style.border = "1px solid #ccc";
|
||||
self.ctx = self.canvas.getContext('2d');
|
||||
|
||||
// Mouse, offset!
|
||||
|
@ -88,10 +99,10 @@ function Sim(config){
|
|||
// Connections
|
||||
self.networkConfig.connections.forEach(function(c){
|
||||
var from = self.peeps[c[0]],
|
||||
to = self.peeps[c[1]],
|
||||
uncuttable = c[2];
|
||||
self.addConnection(from, to, uncuttable);
|
||||
to = self.peeps[c[1]];
|
||||
self.addConnection(from, to, false);
|
||||
});
|
||||
// todo: "start uncuttable"
|
||||
|
||||
// Contagion
|
||||
self.contagion = self.networkConfig.contagion;
|
||||
|
@ -99,6 +110,7 @@ function Sim(config){
|
|||
};
|
||||
|
||||
// Update
|
||||
self.onupdate = config.onupdate || function(){};
|
||||
self.update = function(){
|
||||
|
||||
// "Mouse", offset!
|
||||
|
@ -108,6 +120,12 @@ function Sim(config){
|
|||
self.mouse.y -= canvasBounds.y;
|
||||
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;
|
||||
}
|
||||
|
||||
// Connector-Cutter
|
||||
self.connectorCutter.update();
|
||||
|
@ -120,6 +138,16 @@ function Sim(config){
|
|||
peep.update();
|
||||
});
|
||||
|
||||
// secret editor...
|
||||
// drag Peep
|
||||
if(_draggingPeep){
|
||||
_draggingPeep.x = self.mouse.x+_draggingOffset.x;
|
||||
_draggingPeep.y = self.mouse.y+_draggingOffset.y;
|
||||
}
|
||||
|
||||
// On update! (for arbitrary sim-specific logic)
|
||||
self.onupdate(self);
|
||||
|
||||
};
|
||||
|
||||
// Draw
|
||||
|
@ -128,8 +156,12 @@ function Sim(config){
|
|||
// Retina
|
||||
var ctx = self.ctx;
|
||||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
// todo: smarter redraw coz, wow, retina.
|
||||
ctx.save();
|
||||
ctx.scale(2,2);
|
||||
if(config.fullscreen){
|
||||
ctx.translate(self.fullscreenOffset.x, self.fullscreenOffset.y);
|
||||
}
|
||||
|
||||
// Draw all of it!
|
||||
self.connectorCutter.draw(ctx);
|
||||
|
@ -149,6 +181,61 @@ function Sim(config){
|
|||
self.clear();
|
||||
};
|
||||
|
||||
///////////////////////////////
|
||||
// secret keyboard interface //
|
||||
///////////////////////////////
|
||||
|
||||
// todo: active only when mouse is over MY CANVAS.
|
||||
|
||||
var _draggingPeep = null;
|
||||
var _draggingOffset = {x:0,y:0};
|
||||
subscribe("key/down/space",function(){
|
||||
if(!_draggingPeep){ // prevent double-activation
|
||||
var hoveredPeep = self.getHoveredPeep(0);
|
||||
if(hoveredPeep){
|
||||
_draggingPeep = hoveredPeep;
|
||||
_draggingOffset.x = _draggingPeep.x-self.mouse.x;
|
||||
_draggingOffset.y = _draggingPeep.y-self.mouse.y;
|
||||
}
|
||||
}
|
||||
});
|
||||
subscribe("key/up/space",function(){
|
||||
_draggingPeep = null;
|
||||
});
|
||||
subscribe("key/down/1",function(){
|
||||
_addPeepAtMouse(false);
|
||||
});
|
||||
subscribe("key/down/2",function(){
|
||||
_addPeepAtMouse(true);
|
||||
});
|
||||
var _addPeepAtMouse = function(infected){
|
||||
var overlapPeep = self.getHoveredPeep(20);
|
||||
if(!overlapPeep){
|
||||
self.addPeep(self.mouse.x, self.mouse.y, infected);
|
||||
}
|
||||
};
|
||||
subscribe("key/down/delete",function(){
|
||||
var toDeletePeep = self.getHoveredPeep(0);
|
||||
if(toDeletePeep) self.removePeep(toDeletePeep);
|
||||
});
|
||||
|
||||
self.save = function(){
|
||||
var savedNetwork = {
|
||||
contagion: self.contagion,
|
||||
peeps: [],
|
||||
connections: []
|
||||
};
|
||||
self.peeps.forEach(function(peep){
|
||||
savedNetwork.peeps.push([Math.round(peep.x), Math.round(peep.y), peep.infected?1:0]);
|
||||
});
|
||||
self.connections.forEach(function(c){
|
||||
var fromIndex = self.peeps.indexOf(c.from);
|
||||
var toIndex = self.peeps.indexOf(c.to);
|
||||
savedNetwork.connections.push([fromIndex, toIndex]);
|
||||
});
|
||||
return JSON.stringify(savedNetwork);
|
||||
};
|
||||
|
||||
////////////////
|
||||
// HELPERS... //
|
||||
////////////////
|
||||
|
@ -159,6 +246,10 @@ function Sim(config){
|
|||
self.peeps.push(peep);
|
||||
return peep;
|
||||
};
|
||||
self.removePeep = function(peep){
|
||||
self.removeAllConnectedTo(peep); // delete all connections
|
||||
self.peeps.splice(self.peeps.indexOf(peep),1); // BYE peep
|
||||
};
|
||||
self.addConnection = function(from, to, uncuttable){
|
||||
|
||||
// Don't allow connecting to self...
|
||||
|
@ -187,6 +278,7 @@ function Sim(config){
|
|||
return friends;
|
||||
};
|
||||
self.getHoveredPeep = function(mouseBuffer){
|
||||
mouseBuffer = mouseBuffer || 0;
|
||||
return self.peeps.find(function(peep){
|
||||
return peep.hitTest(self.mouse.x, self.mouse.y, mouseBuffer);
|
||||
});
|
||||
|
@ -198,6 +290,14 @@ function Sim(config){
|
|||
if(c.hitTest(line)) self.connections.splice(i,1);
|
||||
}
|
||||
};
|
||||
self.removeAllConnectedTo = function(peep){
|
||||
for(var i=self.connections.length-1; i>=0; i--){ // backwards index coz we're deleting
|
||||
var c = self.connections[i];
|
||||
if(c.from==peep || c.to==peep){ // in either direction
|
||||
self.connections.splice(i,1); // remove!
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//////////////
|
||||
|
@ -206,4 +306,4 @@ function Sim(config){
|
|||
|
||||
self.init();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue