Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hyperabsolute/759d067019f2330da7feaccbb8e66d0a to your computer and use it in GitHub Desktop.
Save hyperabsolute/759d067019f2330da7feaccbb8e66d0a to your computer and use it in GitHub Desktop.
Brain Neurons on Steroids in Space with 3D Negative Ionic Tractor Beam Deflectors in Quazispacial Rotation Mode

Brain Neurons on Steroids in Space with 3D Negative Ionic Tractor Beam Deflectors in Quazispacial Rotation Mode

These are neurons - inside the human brain, on steroids in space... sending negative ionic tractor beam intercept signals. Enjoy and share | Sander Nizni

A Pen by Sander Nizni on CodePen.

License.

<canvas id=c></canvas>
var w = c.width = window.innerWidth,
h = c.height = window.innerHeight,
ctx = c.getContext( '2d' ),
opts = {
range: 250,
baseConnections: 5,
addedConnections: 5,
baseSize: 9,
minSize: .25,
dataToConnectionSize: .33,
sizeMultiplier: .7,
allowedDist: 60,
baseDist: 99,
addedDist: 77,
connectionAttempts: 100,
dataToConnections: .5,
baseSpeed: .001,
addedSpeed: .099,
baseGlowSpeed: .1,
addedGlowSpeed: .4,
rotVelX: .003,
rotVelY: .002,
repaintColor: '#000',
connectionColor: '#65378F',
dataColor: 'orange',
wireframeWidth: .33,
wireframeColor: '#999',
depth: 300,
focalLength: 550,
vanishPoint: {
x: w / 2,
y: h / 2
}
},
squareRange = opts.range * opts.range,
squareAllowed = opts.allowedDist * opts.allowedDist,
mostDistant = opts.depth + opts.range,
sinX = sinY = 0,
cosX = cosY = 0,
connections = [],
data = [],
all = [],
tick = 0,
totalProb = 0,
Tau = Math.PI * 2;
ctx.fillStyle = '#222';
ctx.fillRect( 0, 0, w, h );
ctx.fillStyle = '#ccc';
ctx.font = '50px Verdana';
ctx.fillText( 'Calculating Nodes', w / 2 - ctx.measureText( 'Calculating Nodes' ).width / 2, h / 2 - 15 );
window.setTimeout( init, 4 ); // to render the loading screen
function init(){
var connection = new Connection( 0, 0, 0, opts.baseSize );
connections.push( connection );
all.push( connection );
connection.link();
anim();
}
function Connection( x, y, z, size ){
this.x = x;
this.y = y;
this.z = z;
this.size = size;
this.screen = {};
this.links = [];
this.probabilities = [];
this.isEnd = false;
this.glowSpeed = opts.baseGlowSpeed + opts.addedGlowSpeed * Math.random();
}
Connection.prototype.link = function(){
if( this.size < opts.minSize )
return this.isEnd = true;
var links = [],
connectionsNum = opts.baseConnections + Math.random() * opts.addedConnections |0,
attempt = opts.connectionAttempts,
alpha, beta, len,
cosA, sinA, cosB, sinB,
pos = {},
passedExisting, passedBuffered;
while( links.length < connectionsNum && --attempt > 0 ){
alpha = Math.random() * Math.PI;
beta = Math.random() * Tau;
len = opts.baseDist + opts.addedDist * Math.random();
cosA = Math.cos( alpha );
sinA = Math.sin( alpha );
cosB = Math.cos( beta );
sinB = Math.sin( beta );
pos.x = len * cosA * sinB;
pos.y = len * sinA * sinB;
pos.z = len * cosB;
if( pos.x*pos.x + pos.y*pos.y + pos.z*pos.z < squareRange ){
passedExisting = true;
passedBuffered = true;
for( var i = 0; i < connections.length; ++i )
if( squareDist( pos, connections[ i ] ) < squareAllowed )
passedExisting = false;
if( passedExisting )
for( var i = 0; i < links.length; ++i )
if( squareDist( pos, links[ i ] ) < squareAllowed )
passedBuffered = false;
if( passedExisting && passedBuffered )
links.push( { x: pos.x, y: pos.y, z: pos.z } );
}
}
if( links.length === 0 )
this.isEnd = true;
else {
for( var i = 0; i < links.length; ++i ){
var pos = links[ i ],
connection = new Connection( pos.x, pos.y, pos.z, this.size * opts.sizeMultiplier );
this.links[ i ] = connection;
all.push( connection );
connections.push( connection );
}
for( var i = 0; i < this.links.length; ++i )
this.links[ i ].link();
}
}
Connection.prototype.step = function(){
this.setScreen();
this.screen.color = opts.connectionColor.replace( 'light', 30 + ( ( tick * this.glowSpeed ) % 30 ) ).replace( 'alp', .2 + ( 1 - this.screen.z / mostDistant ) * .8 );
for( var i = 0; i < this.links.length; ++i ){
ctx.moveTo( this.screen.x, this.screen.y );
ctx.lineTo( this.links[ i ].screen.x, this.links[ i ].screen.y );
}
}
Connection.prototype.draw = function(){
ctx.fillStyle = this.screen.color;
ctx.beginPath();
ctx.arc( this.screen.x, this.screen.y, this.screen.scale * this.size, 0, Tau );
ctx.fill();
}
function Data( connection ){
this.glowSpeed = opts.baseGlowSpeed + opts.addedGlowSpeed * Math.random();
this.speed = opts.baseSpeed + opts.addedSpeed * Math.random();
this.screen = {};
this.setConnection( connection );
}
Data.prototype.reset = function(){
this.setConnection( connections[ 0 ] );
this.ended = 2;
}
Data.prototype.step = function(){
this.proportion += this.speed;
if( this.proportion < 1 ){
this.x = this.ox + this.dx * this.proportion;
this.y = this.oy + this.dy * this.proportion;
this.z = this.oz + this.dz * this.proportion;
this.size = ( this.os + this.ds * this.proportion ) * opts.dataToConnectionSize;
} else
this.setConnection( this.nextConnection );
this.screen.lastX = this.screen.x;
this.screen.lastY = this.screen.y;
this.setScreen();
this.screen.color = opts.dataColor.replace( 'light', 40 + ( ( tick * this.glowSpeed ) % 50 ) ).replace( 'alp', .2 + ( 1 - this.screen.z / mostDistant ) * .6 );
}
Data.prototype.draw = function(){
if( this.ended )
return --this.ended; // not sre why the thing lasts 2 frames, but it does
ctx.beginPath();
ctx.strokeStyle = this.screen.color;
ctx.lineWidth = this.size * this.screen.scale;
ctx.moveTo( this.screen.lastX, this.screen.lastY );
ctx.lineTo( this.screen.x, this.screen.y );
ctx.stroke();
}
Data.prototype.setConnection = function( connection ){
if( connection.isEnd )
this.reset();
else {
this.connection = connection;
this.nextConnection = connection.links[ connection.links.length * Math.random() |0 ];
this.ox = connection.x; // original coordinates
this.oy = connection.y;
this.oz = connection.z;
this.os = connection.size; // base size
this.nx = this.nextConnection.x; // new
this.ny = this.nextConnection.y;
this.nz = this.nextConnection.z;
this.ns = this.nextConnection.size;
this.dx = this.nx - this.ox; // delta
this.dy = this.ny - this.oy;
this.dz = this.nz - this.oz;
this.ds = this.ns - this.os;
this.proportion = 0;
}
}
Connection.prototype.setScreen = Data.prototype.setScreen = function(){
var x = this.x,
y = this.y,
z = this.z;
// apply rotation on X axis
var Y = y;
y = y * cosX - z * sinX;
z = z * cosX + Y * sinX;
// rot on Y
var Z = z;
z = z * cosY - x * sinY;
x = x * cosY + Z * sinY;
this.screen.z = z;
// translate on Z
z += opts.depth;
this.screen.scale = opts.focalLength / z;
this.screen.x = opts.vanishPoint.x + x * this.screen.scale;
this.screen.y = opts.vanishPoint.y + y * this.screen.scale;
}
function squareDist( a, b ){
var x = b.x - a.x,
y = b.y - a.y,
z = b.z - a.z;
return x*x + y*y + z*z;
}
function anim(){
window.requestAnimationFrame( anim );
ctx.fillStyle = opts.repaintColor;
ctx.fillRect( 0, 0, w, h );
++tick;
var rotX = tick * opts.rotVelX,
rotY = tick * opts.rotVelY;
cosX = Math.cos( rotX );
sinX = Math.sin( rotX );
cosY = Math.cos( rotY );
sinY = Math.sin( rotY );
if( data.length < connections.length * opts.dataToConnections && Math.random() < .1 ){
var datum = new Data( connections[ 0 ] );
data.push( datum );
all.push( datum );
}
ctx.beginPath();
ctx.lineWidth = opts.wireframeWidth;
ctx.strokeStyle = opts.wireframeColor;
all.map( function( item ){ item.step(); } );
ctx.stroke();
all.sort( function( a, b ){ return b.screen.z - a.screen.z } );
all.map( function( item ){ item.draw(); } );
/*ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.arc( opts.vanishPoint.x, opts.vanishPoint.y, opts.range * opts.focalLength / opts.depth, 0, Tau );
ctx.stroke();*/
}
social("codepen/sander-nizni",
"twitter/hyperabsolute",
"linkedin/sandernizni",
"instagram/hyperabsolute",
"facebook/sander.nizni",
"/sandernizni.wordpress.com",
"light", "Sander says... Try it in full screen, dawg.");
<script src="http://codepen.io/Sander-Nizni/pen/mPoOjg"></script>
/*
SANDER SAYS:
NO WARRANTIES EXPRESSED OR IMPLIED
FOR USING THIS CODE. THIS OR SIMILAR
CODE WAS WRITTEN BEFORE, AND IT WILL
BE WRITTEN AGAIN... BUT IT DOESN'T
MATTER - BECAUSE WE ARE IN THIS
TOGETHER. EVERYTHING COULD HAVE BEEN
ANYTHING ELSE, AND IT WOULD HAVE
JUST AS MUCH MEANING. C'EST LA VIE.
COMPLIMENTS? PARTY INVITATIONS?
RIGHT ON! CONTACT @HYPERABSOLUTE ON
TWITTER OR ON UXRIG.COM
STAY AWESOME | HYPERABSOLUTE
*/
canvas {
position: absolute;
top: 0;
left: 0;
}
/*
SOCIAL STYLES APPEAR BELOW.
ALSO REMEMBER TO REFERENCE THE JS URL IN THE JS PAN SETTINGS: http://codepen.io/Sander-Nizni/pen/mPoOjg
*/
#social-container {
opacity: 0.9;
bottom: 5px;
right: 5px;
}
#social-container p{
padding-bottom: 0;
margin-bottom: 0;
}
#social-container #social-links a {
font-size: 2.8rem;
}
#social-message {
font-size: 1.15rem;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment