Skip to content

Instantly share code, notes, and snippets.

@tsur
Created August 15, 2015 23:28
Show Gist options
  • Save tsur/f55239e08b0592c70b9b to your computer and use it in GitHub Desktop.
Save tsur/f55239e08b0592c70b9b to your computer and use it in GitHub Desktop.
dots-world
<div>
<span class="start">Start</span> -
<span class="stop">Stop</span> -
<span class="pause">Pause</span> -
<span class="resume">Resume</span>
</div>
<canvas id="animation"></canvas>
'use strict';
const GLOBAL_PLAYABLE = true;
function _animation(state) {
state = state || {};
return _animationHandler(state);
}
function _animationHandler(state) {
state = {
//Animation controls
pause: false,
play: false,
engine: null,
//Animation data
colors: [],
transitions: [],
pixels: [],
components: [],
numParticles: 100,
width: window.innerWidth,
height: window.innerHeight,
startedAt: new Date(),
started: false,
sketch: null,
// Mouse coords
mx: 0,
my: 0,
impulsX: 0,
impulsY: 0,
impulsToX: 0,
impulsToY: 0,
//Animations Transactions
transRepeatIndex: 0,
transRepeatTimes: 0
};
return {
pause: _pause(state),
resume: _resume(state),
start: _start(state),
stop: _stop(state),
destroy: _destroy(state),
create: _create(state)
};
}
function _initState(state) {
var genRandomWhiteColor = function genRandomWhiteColor() {
return Math.random() * 125 + 130;
};
return function() {
state.pixels = new Array();
_.forEach(_.range(state.numParticles), function() {
var whiteColorGrade = genRandomWhiteColor();
var pixel = {
x: Math.random() * state.width,
y: state.height / 2,
toX: 0,
toY: state.height / 2 + 45,
color: Math.random() * 200 + 55,
angle: Math.random() * Math.PI * 2,
size: 0,
toSize: Math.random() * 4 + 1,
r: 0,
g: 0,
b: 0,
toR: whiteColorGrade,
toG: whiteColorGrade,
toB: whiteColorGrade,
flightMode: 0
};
pixel.toX = pixel.x;
pixel.speedX = 0;
pixel.speedY = 0;
state.pixels.push(pixel);
});
};
}
function _sketch(state) {
return function(sketch) {
sketch.draw = function() {
if (state.pause === false) {
if (state.play && GLOBAL_PLAYABLE) {
_.forEach(state.components, function(component) {
if (component) component.update(sketch);
});
sketch.background(0, 0);
_.forEach(state.components, function(component) {
if (component) component.draw(sketch);
});
}
}
};
sketch.setup = function() {
sketch.size(state.width, state.height);
sketch.background(0, 0);
sketch.fill(0, 0, 0);
sketch.noStroke();
sketch.frameRate(60);
};
sketch.mouseMoved = function() {
state.mx = sketch.mouseX;
state.my = sketch.mouseY;
};
state.sketch = sketch;
};
}
function _canvas() {
return document.getElementById('animation');
}
function _initEngine(state) {
return function() {
state.engine = new Processing(_canvas(), _sketch(state));
state.pause = false;
state.play = true;
};
}
function _initListeners(state) {
return function() {
//Resize options
window.addEventListener('resize', function() {
state.width = window.innerWidth;
state.height = window.innerHeight;
state.sketch.size(state.width, state.height);
});
};
}
function _start(state){
return function(fn){
state.started = true;
if(fn)fn();
}
}
function _stop(state){
return function(fn){
state.started = false;
state.startedAt = new Date();
state.impulsX= 0;
state.impulsY= 0;
state.impulsToX= 0;
state.impulsToY= 0;
_initState(state)();
if(fn)fn();
}
}
function _create(state) {
_initColors(state)();
_initTransitions(state)();
_initComponents(state)();
return function(fn) {
_initState(state)();
_initEngine(state)();
_initListeners(state)();
if(fn)fn();
};
}
function _initColors(state) {
return function() {
var whiteGradient = Math.random() * 255;
state.colors = [{
r: function r() {
return Math.random() * 255;
},
g: function g() {
return 0;
},
b: function b() {
return 0;
}
}, {
r: function r() {
return Math.random() * 255;
},
g: function g() {
return Math.random() * 255;
},
b: function b() {
return Math.random() * 255;
}
}, {
r: function r() {
return 0;
},
g: function g() {
return Math.random() * 255;
},
b: function b() {
return 0;
}
}, {
r: function r() {
return 0;
},
g: function g() {
return 0;
},
b: function b() {
return Math.random() * 255;
}
}, {
r: function r() {
return Math.random() * 255;
},
g: function g() {
return 0;
},
b: function b() {
return Math.random() * 255;
}
}, {
r: function r() {
return whiteGradient;
},
g: function g() {
return whiteGradient;
},
b: function b() {
return whiteGradient;
}
}];
};
}
function _initTransitions(state) {
return function() {
state.transitions = [
// random position
function() {
_.forEach(state.pixels, function(pixel) {
if (pixel.flightMode != 2) {
pixel.toX = Math.random() * state.width;
pixel.toY = Math.random() * state.height;
pixel.speedX = Math.cos(pixel.angle) * Math.random() * 3;
pixel.speedY = Math.sin(pixel.angle) * Math.random() * 3;
pixel.fixedSize = false;
}
});
},
//white flash
function() {
_.forEach(state.pixels, function(pixel) {
if (pixel.flightMode != 2) {
pixel.r = 255;
pixel.g = 255;
pixel.b = 255;
pixel.size = Math.random() * 50 + 50;
pixel.fixedSize = false;
}
});
},
// change size
function() {
_.forEach(state.pixels, function(pixel) {
if (pixel.flightMode != 2) {
pixel.toSize = Math.random() * 10 + 1;
pixel.fixedSize = false;
}
});
},
// circle shape
function() {
var r = Math.floor(Math.random() * 250 + 100);
var rgb_circle = state.colors[Math.floor(Math.random() * state.colors.length)];
_.forEach(state.pixels, function(pixel, i) {
if (pixel.flightMode != 2) {
pixel.toSize = Math.random() * 4 + 1;
pixel.toX = state.width / 2 + Math.cos(i * 3.6 * Math.PI / 180) * r;
pixel.toY = state.height / 2 + Math.sin(i * 3.6 * Math.PI / 180) * r;
pixel.speedX = (Math.random() - 0.5) / 2;
pixel.speedY = (Math.random() - 0.5) / 2;
pixel.toR = rgb_circle.r();
pixel.toG = rgb_circle.g();
pixel.toB = rgb_circle.b();
pixel.fixedSize = false;
state.impulsX = 0;
state.impulsY = 0;
}
});
}
];
};
}
function _initComponents(state) {
var universe = {
update: function update() {
state.impulsX = state.impulsX + (state.impulsToX - state.impulsX) / 30;
state.impulsY = state.impulsY + (state.impulsToY - state.impulsY) / 30;
// move to tox
_.forEach(state.pixels, function(p) {
var a = Math.abs(p.toX - state.mx) * Math.abs(p.toX - state.mx);
var b = Math.abs(p.toY - state.my) * Math.abs(p.toY - state.my);
var c = Math.sqrt(a + b);
p.x = p.x + (p.toX - p.x) / 10;
p.y = p.y + (p.toY - p.y) / 10;
p.size = p.size + (p.toSize - p.size) / 10;
p.r = p.r + (p.toR - p.r) / 10;
p.g = p.g + (p.toG - p.g) / 10;
p.b = p.b + (p.toB - p.b) / 10;
// Mouse Interaction
if (p.flightMode != 2) {
if (c < 120) {
if (p.flightMode == 0) {
p.degree = Math.atan2(p.y - state.my, p.x - state.mx) * 180 / Math.PI + Math.random() * 180 - 90;
p.degreeSpeed = Math.random() * 1 + 0.5;
p.frame = 0;
}
p.flightMode = 1;
} else {
p.flightMode = 0;
}
}
if (p.flightMode == 0) {
// change position
p.toX += p.speedX;
p.toY += p.speedY;
// check for bounds
if (p.x < 0) {
p.x = state.width;
p.toX = state.width;
}
if (p.x > state.width) {
p.x = 0;
p.toX = 0;
}
if (p.y < 0) {
p.y = state.height;
p.toY = state.height;
}
if (p.y > state.height) {
p.y = 0;
p.toY = 0;
}
}
// seek mouse
if (p.flightMode == 1) {
p.toX = state.mx + Math.cos((p.degree + p.frame) % 360 * Math.PI / 180) * c;
p.toY = state.my + Math.sin((p.degree + p.frame) % 360 * Math.PI / 180) * c;
p.frame += p.degreeSpeed;
p.degreeSpeed += 0.01;
}
if (p.flightMode != 2) {
// add impuls
p.toX += Math.floor(state.impulsX * p.size / 30);
p.toY += Math.floor(state.impulsY * p.size / 30);
}
});
// set an choord
var r1 = Math.floor(Math.random() * state.pixels.length);
var r2 = Math.floor(Math.random() * state.pixels.length);
if (!state.pixels[r1].fixedSize && state.pixels[r1].flightMode != 2) {
state.pixels[r1].size = Math.random() * 30;
}
if (!state.pixels[r2].fixedSize && state.pixels[r2].flightMode != 2) {
state.pixels[r2].size = Math.random() * 30;
}
if (new Date().getTime() - state.startedAt.getTime() >= 2000 && state.started) {
state.startedAt = new Date();
state.impulsX = Math.random() * 800 - 400;
state.impulsY = -Math.random() * 400;
var transIndex = Math.floor(Math.random() * state.transitions.length);
state.transitions[transIndex]();
}
state.fixedSize = false;
},
draw: function draw(sketch) {
_.forEach(state.pixels, function(pixel) {
sketch.fill(Math.floor(pixel.r), Math.floor(pixel.g), Math.floor(pixel.b));
sketch.ellipse(pixel.x, pixel.y, pixel.size, pixel.size);
});
}
};
return function() {
state.components = [universe];
};
}
function _pause(state) {
return function(fn) {
state.pause = true;
if(fn)fn();
};
}
function _resume(state) {
return function(fn) {
state.pause = false;
if(fn)fn();
};
}
function _destroy(state) {
return function(fn) {
state.sketch.fill(0);
state.sketch.rect(0, 0, state.width, state.height);
state.sketch.exit();
state = undefined;
if(fn)fn();
};
}
window.addEventListener('load', function() {
const animation = _animation();
animation.create();
document
.querySelector('.start')
.addEventListener('click', event => {
animation.start();
});
document
.querySelector('.stop')
.addEventListener('click', event => {
animation.stop();
});
document
.querySelector('.pause')
.addEventListener('click', event => {
animation.pause();
});
document
.querySelector('.resume')
.addEventListener('click', event => {
animation.resume();
});
});
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/processing.js/1.4.9/processing.min.js"></script>
html, body {
height:100%;
width:100%;
margin:0;
background-color:#000;
overflow:hidden;
}
div {
position:absolute;
left: 20px;
top: 20px;
border: 1px solid grey;
padding: 10px;
border-radius: 10px;
z-index: 10;
color: grey;
}
canvas {
z-index : 2;
}
span {
color: grey;
cursor: pointer;
}
span:hover{
color: white;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment