can draw sims and bs in backgroudn or whatever

This commit is contained in:
Nicky Case 2018-03-27 15:20:22 -04:00
parent ed9c3ff488
commit e95c54cf07
13 changed files with 296 additions and 221 deletions

View File

@ -3,13 +3,6 @@ var PEEP_STATE_COLORS = {
2: "#dd4040"
};
var _hack_SHOW_BOTH_STATES = false;
var _hack_HIDE_BARS = false;
var _hack_REINTEGRATION_PUZZLE = false;
var testingImage = new Image();
testingImage.src = "img/testing.png";
function Peep(config){
var self = this;
@ -51,7 +44,7 @@ function Peep(config){
}
// Friends connected... or infected
var friends = getConnected(self);
var friends = self.sim.getConnected(self);
self.numFriends = friends.length;
self.numInfectedFriends = 0;
friends.forEach(function(friend){
@ -113,7 +106,7 @@ function Peep(config){
// LABEL FOR INFECTED/FRIENDS, BAR, AND CONTAGION LEVEL //
//////////////////////////////////////////////////////////
if(!_hack_HIDE_BARS && !self._hack_TESTED){
//if(!_hack_HIDE_BARS && !self._hack_TESTED){
ctx.save();
@ -143,36 +136,10 @@ function Peep(config){
// The color fills
if(self.numFriends>0){
if(!_hack_SHOW_BOTH_STATES){
ctx.fillStyle = PEEP_STATE_COLORS[2]; // state = 2 infected
ctx.beginPath();
ctx.rect(-barWidth/2, -barHeight/2, barWidth*(self.numInfectedFriends/self.numFriends), barHeight);
ctx.fill();
}else{
var ratio = self.numInfectedFriends/self.numFriends;
if((!_hack_REINTEGRATION_PUZZLE && self.state==1)
|| (_hack_REINTEGRATION_PUZZLE && self.state==2)){
var w = barWidth*(1-ratio);
ctx.fillStyle = PEEP_STATE_COLORS[1];
ctx.beginPath();
ctx.rect(-barWidth/2, -barHeight/2, w, barHeight);
ctx.fill();
ctx.fillStyle = PEEP_STATE_COLORS[2];
ctx.beginPath();
ctx.rect(-barWidth/2+w, -barHeight/2, barWidth*(ratio), barHeight);
ctx.fill();
}else{
var w = barWidth*(ratio);
ctx.fillStyle = PEEP_STATE_COLORS[2];
ctx.beginPath();
ctx.rect(-barWidth/2, -barHeight/2, w, barHeight);
ctx.fill();
ctx.fillStyle = PEEP_STATE_COLORS[1];
ctx.beginPath();
ctx.rect(-barWidth/2+w, -barHeight/2, barWidth*(1-ratio), barHeight);
ctx.fill();
}
}
ctx.fillStyle = PEEP_STATE_COLORS[2]; // state = 2 infected
ctx.beginPath();
ctx.rect(-barWidth/2, -barHeight/2, barWidth*(self.numInfectedFriends/self.numFriends), barHeight);
ctx.fill();
}
// The outline
@ -187,20 +154,7 @@ function Peep(config){
// a pointer for contagion level
ctx.translate(0, barHeight/2+2);
if(!_hack_REINTEGRATION_PUZZLE){
if(CONTAGION_THRESHOLD && CONTAGION_THRESHOLD>0){
self._drawThreshold(ctx, CONTAGION_THRESHOLD);
}
if(CONTAGION_THRESHOLD_2 && CONTAGION_THRESHOLD_2>0){
self._drawThreshold(ctx, CONTAGION_THRESHOLD_2);
}
}else{
if(self.state==1){
self._drawThreshold(ctx, 1/3);
}else{
self._drawThreshold(ctx, 2/3);
}
}
self._drawThreshold(ctx, CONTAGION_THRESHOLD);
// Percent
ctx.font = '8px sans-serif';
@ -214,11 +168,6 @@ function Peep(config){
}
// AM I BEING TESTED
if(self._hack_TESTED){
ctx.drawImage(testingImage, -30, -85, 60, 60);
}
ctx.restore();
};

View File

@ -53,8 +53,8 @@ Cursor is allowed to flow EVERYWHERE though...
<script src="js/sim/Peep.js"></script>
<script src="js/sim/Connection.js"></script>
<!--script src="js/sim/Drawing.js"></script>
<script src="js/sim/Game.js"></script-->
<script src="js/sim/ConnectorCutter.js"></script>
<!--script src="js/sim/Game.js"></script-->
<script src="js/sim/Simulations.js"></script>
<script src="js/main.js"></script>

View File

@ -7,9 +7,11 @@ SLIDES.push(
],
sims:[
{
x: 400,
y: 10,
network: {
contagion: 0.25,
peeps: [ [100,100],[200,200] ],
peeps: [ [100,100],[200,200],[400,150] ],
connections: [ [0,1] ]
}
}

View File

@ -35,4 +35,9 @@ function createCanvas(canvas, width, height){
return canvas;
}
}
// Copy an object
function cloneObject(obj){
return JSON.parse(JSON.stringify(obj));
}

View File

@ -8,12 +8,21 @@ window.onload = function(){
// Initializing the Mouse
Mouse.init(document.body);
// Animation loop IS update loop, whatever
// Animation loop IS update loop for now, whatever
function update(){
// Update
simulations.update();
slideshow.update();
pencil.update();
Mouse.update();
// Draw
simulations.draw();
pencil.draw();
window.requestAnimationFrame(update);
}
window.requestAnimationFrame(update);

View File

@ -14,7 +14,7 @@ function Connection(config){
// Draw
self.draw = function(ctx){
ctx.strokeStyle = "#444";
ctx.lineWidth = self.uncuttable ? 6 : 2; // thick=uncuttable
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);

View File

@ -0,0 +1,120 @@
function ConnectorCutter(config){
var self = this;
self.config = config;
self.sim = config.sim;
// Connecting/Cutting
self.connectFrom = null;
self.connectTo = null;
self.isCutting = false;
self.cutTrail = [];
// Update!
self.state = 0; // 0-nothing | 1-connecting | 2-cutting
self.update = function(){
var mouse = self.sim.mouse;
// JUST CLICKED, and state=0... can either start connecting or cutting!
if(mouse.justPressed && self.state===0){
// Clicked on a peep?
var peepClicked = self.sim.getHoveredPeep(20);
if(peepClicked){
self.state = 1; // START CONNECTING
self.connectFrom = peepClicked;
}else{
self.state = 2; // START ERASING
}
}
// JUST RELEASED, and state!=0... can either stop connecting or cutting!
if(mouse.justReleased && self.state!==0){
// End connect?
if(self.state==1){
var peepReleased = self.sim.getHoveredPeep(20);
if(peepReleased){
self.sim.addConnection(self.connectFrom, peepReleased);
}
}
// back to normal
self.state = 0;
}
// In "NORMAL" state... tell Pencil what frame to go to
if(self.state==0){
var peepHovered = self.sim.getHoveredPeep(20); // buffer of 20px
pencil.gotoFrame( peepHovered ? 1 : 0 );
}
// In "CONNECTING" state... show where to connect to
if(self.state==1){
// Connect to a nearby hovered peep?
var peepHovered = self.sim.getHoveredPeep(20); // buffer of 20px
if(peepHovered==self.connectFrom) peepHovered=null; // if same, nah
self.connectTo = peepHovered ? peepHovered : mouse;
// Pencil's always DARK
pencil.gotoFrame(1);
}
// In "CUTTING" state... cut intersected lines! & add to trail
if(self.state==2){
// Try cutting
var line = [mouse.lastX, mouse.lastY, mouse.x, mouse.y];
self.sim.tryCuttingConnections(line);
// Add to trail
self.cutTrail.unshift([mouse.x,mouse.y]); // add to start
if(self.cutTrail.length>10){
self.cutTrail.pop(); // remove from end
}
// Pencil's always RED
pencil.gotoFrame(2);
}else{
self.cutTrail.pop(); // oh, and if not cutting, pop from end anyway
}
};
// Draw
self.draw = function(ctx){
ctx.lineJoin = "round";
ctx.lineCap = "round";
// 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();
}
// Cutting!
if(self.cutTrail.length>0){
ctx.strokeStyle = "#dd4040";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(self.cutTrail[0][0], self.cutTrail[0][1]);
for(var i=1; i<self.cutTrail.length; i++){
ctx.lineTo(self.cutTrail[i][0], self.cutTrail[i][1]);
}
ctx.stroke();
}
};
}

View File

@ -1,75 +0,0 @@
function Drawing(){
var self = this;
// Update!
self.update = function(){
// Connection
if(self.connectFrom){
// Over any peeps? Connect to THAT! Else, connect to Mouse
var peepHovered = _mouseOverPeep(CONNECT_TO_BUFFER); // buffer of 20px
if(peepHovered==self.connectFrom) peepHovered=null; // if same, nah
self.connectTo = peepHovered ? peepHovered : Mouse;
}
// Erase
if(self.isErasing){
self.eraseTrail.unshift([Mouse.x,Mouse.y]); // add to start
if(self.eraseTrail.length>10){
self.eraseTrail.pop(); // remove from end
}
}else{
self.eraseTrail.pop(); // remove from end
}
};
// Connection!
self.connectFrom = null;
self.connectTo = null;
self.startConnect = function(from){
self.connectFrom = from;
};
self.endConnect = function(){
self.connectFrom = null;
};
// Erase!
self.isErasing = false;
self.eraseTrail = [];
self.startErase = function(){
self.isErasing = true;
};
self.endErase = function(){
self.isErasing = false;
};
// Draw
self.draw = function(ctx){
// Connecting...
if(self.connectFrom){
ctx.strokeStyle = "#ccc";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(self.connectFrom.x, self.connectFrom.y);
ctx.lineTo(self.connectTo.x, self.connectTo.y);
ctx.stroke();
}
// Erase
if(self.eraseTrail.length>0){
ctx.strokeStyle = "#dd4040";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(self.eraseTrail[0][0], self.eraseTrail[0][1]);
for(var i=1; i<self.eraseTrail.length; i++){
ctx.lineTo(self.eraseTrail[i][0], self.eraseTrail[i][1]);
}
ctx.stroke();
}
};
}

View File

@ -3,13 +3,6 @@ var PEEP_STATE_COLORS = {
2: "#dd4040"
};
var _hack_SHOW_BOTH_STATES = false;
var _hack_HIDE_BARS = false;
var _hack_REINTEGRATION_PUZZLE = false;
var testingImage = new Image();
testingImage.src = "img/testing.png";
function Peep(config){
var self = this;
@ -17,7 +10,8 @@ function Peep(config){
// Properties
self.x = config.x;
self.y = config.y;
self.state = config.state;
self.infected = config.infected;
self.sim = config.sim;
// Update:
self.numFriends = 0;
@ -31,8 +25,8 @@ function Peep(config){
// Face position!
var faceVector = {
x: (Mouse.x-self.x)/5,
y: (Mouse.y-self.y)/5
x: (self.sim.mouse.x-self.x)/5,
y: (self.sim.mouse.y-self.y)/5
};
faceVector.mag = Math.sqrt(faceVector.x*faceVector.x + faceVector.y*faceVector.y);
var max_distance = 5;
@ -51,17 +45,17 @@ function Peep(config){
}
// Friends connected... or infected
var friends = getConnected(self);
var friends = self.sim.getFriendsOf(self);
self.numFriends = friends.length;
self.numInfectedFriends = 0;
friends.forEach(function(friend){
if(friend.state==2) self.numInfectedFriends++;
if(friend.infected) self.numInfectedFriends++;
});
};
// Draw
var radius = 20;
var radius = 25;
var barWidth = 30;
var barHeight = 10;
self.draw = function(ctx){
@ -70,8 +64,7 @@ function Peep(config){
ctx.translate(self.x, self.y);
// Circle
//ctx.fillStyle = (self.state==1) ? "#ccc" : "#dd4040"; //"#ffdf00";
var myColor = PEEP_STATE_COLORS[self.state];
var myColor = self.infected ? PEEP_STATE_COLORS[2] : PEEP_STATE_COLORS[1];
ctx.fillStyle = myColor;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, Math.TAU, false);
@ -88,6 +81,7 @@ function Peep(config){
// Face
ctx.save();
ctx.translate(self.faceX, self.faceY);
ctx.scale(1.25, 1.25);
ctx.fillStyle = "rgba(0,0,0,0.5)";
if(self.faceBlink){
ctx.beginPath();
@ -113,7 +107,7 @@ function Peep(config){
// LABEL FOR INFECTED/FRIENDS, BAR, AND CONTAGION LEVEL //
//////////////////////////////////////////////////////////
if(!_hack_HIDE_BARS && !self._hack_TESTED){
//if(!_hack_HIDE_BARS && !self._hack_TESTED){
ctx.save();
@ -143,36 +137,10 @@ function Peep(config){
// The color fills
if(self.numFriends>0){
if(!_hack_SHOW_BOTH_STATES){
ctx.fillStyle = PEEP_STATE_COLORS[2]; // state = 2 infected
ctx.beginPath();
ctx.rect(-barWidth/2, -barHeight/2, barWidth*(self.numInfectedFriends/self.numFriends), barHeight);
ctx.fill();
}else{
var ratio = self.numInfectedFriends/self.numFriends;
if((!_hack_REINTEGRATION_PUZZLE && self.state==1)
|| (_hack_REINTEGRATION_PUZZLE && self.state==2)){
var w = barWidth*(1-ratio);
ctx.fillStyle = PEEP_STATE_COLORS[1];
ctx.beginPath();
ctx.rect(-barWidth/2, -barHeight/2, w, barHeight);
ctx.fill();
ctx.fillStyle = PEEP_STATE_COLORS[2];
ctx.beginPath();
ctx.rect(-barWidth/2+w, -barHeight/2, barWidth*(ratio), barHeight);
ctx.fill();
}else{
var w = barWidth*(ratio);
ctx.fillStyle = PEEP_STATE_COLORS[2];
ctx.beginPath();
ctx.rect(-barWidth/2, -barHeight/2, w, barHeight);
ctx.fill();
ctx.fillStyle = PEEP_STATE_COLORS[1];
ctx.beginPath();
ctx.rect(-barWidth/2+w, -barHeight/2, barWidth*(1-ratio), barHeight);
ctx.fill();
}
}
ctx.fillStyle = PEEP_STATE_COLORS[2]; // state = 2 infected
ctx.beginPath();
ctx.rect(-barWidth/2, -barHeight/2, barWidth*(self.numInfectedFriends/self.numFriends), barHeight);
ctx.fill();
}
// The outline
@ -187,20 +155,7 @@ function Peep(config){
// a pointer for contagion level
ctx.translate(0, barHeight/2+2);
if(!_hack_REINTEGRATION_PUZZLE){
if(CONTAGION_THRESHOLD && CONTAGION_THRESHOLD>0){
self._drawThreshold(ctx, CONTAGION_THRESHOLD);
}
if(CONTAGION_THRESHOLD_2 && CONTAGION_THRESHOLD_2>0){
self._drawThreshold(ctx, CONTAGION_THRESHOLD_2);
}
}else{
if(self.state==1){
self._drawThreshold(ctx, 1/3);
}else{
self._drawThreshold(ctx, 2/3);
}
}
self._drawThreshold(ctx, self.sim.contagion);
// Percent
ctx.font = '8px sans-serif';
@ -212,12 +167,7 @@ function Peep(config){
ctx.restore();
}
// AM I BEING TESTED
if(self._hack_TESTED){
ctx.drawImage(testingImage, -30, -85, 60, 60);
}
//}
ctx.restore();
@ -248,8 +198,8 @@ function Peep(config){
// Infect
self.infect = function(){
self.state = 2;
}
self.infected = true;
};
}
function _mouseOverPeep(buffer){
@ -259,13 +209,6 @@ function _mouseOverPeep(buffer){
});
return result;
}
function addPeep(x,y, state){
var peep = new Peep({
x:x, y:y,
state: state ? state : 1
});
peeps.push(peep);
}
function removePeep(peep){
removeAllConnectedTo(peep); // remove connections first
peeps.splice(peeps.indexOf(peep),1); // BYE peep

View File

@ -13,12 +13,15 @@ function Simulations(){
self.sims = [];
// Clear All Sims
self.clear = function(){
self.sims.forEach(function(sim){
self.dom.removeChild(sim.canvas);
sim.kill();
});
};
// Show Sims
self.showSims = function(simConfigs){
self.clear();
simConfigs.forEach(function(simConfig){
@ -28,6 +31,20 @@ function Simulations(){
});
};
// Update
self.update = function(){
self.sims.forEach(function(sim){
sim.update();
});
};
// Draw
self.draw = function(){
self.sims.forEach(function(sim){
sim.draw();
});
};
}
function Sim(config){
@ -38,8 +55,17 @@ function Sim(config){
// 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.ctx = self.canvas.getContext('2d');
// Mouse, offset!
self.mouse = {x:0, y:0};
// Connector-Cutter
self.connectorCutter = new ConnectorCutter({sim:self});
// Networks... clear/init
self.clear = function(){
self.peeps = [];
@ -61,14 +87,72 @@ function Sim(config){
// Connections
self.networkConfig.connections.forEach(function(c){
var from = peeps[c[0]],
to = peeps[c[1]],
var from = self.peeps[c[0]],
to = self.peeps[c[1]],
uncuttable = c[2];
self.addConnection(from, to, uncuttable);
});
// Contagion
self.contagion = self.networkConfig.contagion;
};
// Update
self.update = function(){
// "Mouse", offset!
var canvasBounds = self.canvas.getBoundingClientRect();
self.mouse = cloneObject(Mouse);
self.mouse.x -= canvasBounds.x;
self.mouse.y -= canvasBounds.y;
self.mouse.lastX -= canvasBounds.x;
self.mouse.lastY -= canvasBounds.y;
// Connector-Cutter
self.connectorCutter.update();
// Connections & Peeps
self.connections.forEach(function(connection){
connection.update();
});
self.peeps.forEach(function(peep){
peep.update();
});
};
// Draw
self.draw = function(){
// Retina
var ctx = self.ctx;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.save();
ctx.scale(2,2);
// Draw all of it!
self.connectorCutter.draw(ctx);
self.connections.forEach(function(connection){
connection.draw(ctx);
});
self.peeps.forEach(function(peep){
peep.draw(ctx);
});
ctx.restore();
};
// Kill
self.kill = function(){
self.clear();
};
////////////////
// HELPERS... //
////////////////
// Add Peeps/Connections
self.addPeep = function(x, y, infected){
var peep = new Peep({ x:x, y:y, infected:infected, sim:self });
@ -93,12 +177,33 @@ function Sim(config){
return connection;
};
// Update
self.update = function(){
self.getFriendsOf = function(peep){
var friends = [];
for(var i=0; i<self.connections.length; i++){ // in either direction
var c = self.connections[i];
if(c.from==peep) friends.push(c.to);
if(c.to==peep) friends.push(c.from);
}
return friends;
};
self.getHoveredPeep = function(mouseBuffer){
return self.peeps.find(function(peep){
return peep.hitTest(self.mouse.x, self.mouse.y, mouseBuffer);
});
};
self.tryCuttingConnections = function(line){
for(var i=self.connections.length-1; i>=0; i--){ // going BACKWARDS coz killing connections
var c = self.connections[i];
if(c.uncuttable) continue; // don't touch the UNCUTTABLES
if(c.hitTest(line)) self.connections.splice(i,1);
}
};
// INIT NOW
//////////////
// INIT NOW //
//////////////
self.init();
}

View File

@ -29,6 +29,11 @@ function Pencil(){
"#ff5555"
];
// Go to frame?
self.gotoFrame = function(frame){
self.sprite.gotoFrame(frame);
};
// Update
self.update = function(){
@ -47,6 +52,11 @@ function Pencil(){
self.x = Mouse.x;
self.y = Mouse.y;
};
// Draw
self.draw = function(){
// Move DOM there
self.canvas.style.left = self.x-_margin;
self.canvas.style.top = self.y-_size+_margin;
@ -59,10 +69,13 @@ function Pencil(){
// Draw pencil's dot
if(!Mouse.pressed){
ctx.save();
ctx.fillStyle = self.colors[self.sprite.currentFrame];
ctx.beginPath();
ctx.arc(0, 0, 5, 0, Math.TAU);
ctx.globalAlpha = 0.5;
ctx.arc(0, 0, 8, 0, Math.TAU);
ctx.fill();
ctx.restore();
}
// Draw pencil

View File

@ -58,4 +58,8 @@ function Slideshow(){
self.dom.innerHTML = "";
};
// Update
self.update = function(){
};
}