public
Created

A CodePen by Jack Rugile. Canvas Orbital Trails - Click and drag anywhere on the screen to create new trails.

  • Download Gist
index.html
HTML
1 2 3 4 5 6 7
<div id="control-panel">
<p>Click and drag to make more!</p>
<label>Trails: </label>
<input type="checkbox" id="trail" name="trail" checked/>
<button id="clear">Clear</button>
</div>
<canvas id="c"></canvas>
script.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){window.setTimeout(a,1E3/60)}}();
 
document.onselectstart = function() {
return false;
};
var c = document.getElementById('c');
var ctx = c.getContext('2d');
c.width = cw = window.innerWidth;
c.height = ch = window.innerHeight;
var rand = function(rMi, rMa){return ~~((Math.random()*(rMa-rMi+1))+rMi);}
ctx.lineCap = 'round';
var orbs = [];
var orbCount = 30;
var radius;
 
var trailCB = document.getElementById('trail');
var trail = trailCB.checked;
var clearer = document.getElementById('clear');
 
function createOrb(mx,my){
var dx = (cw/2) - mx;
var dy = (ch/2) - my;
var dist = Math.sqrt(dx * dx + dy * dy);
var angle = Math.atan2(dy, dx);
orbs.push({
x: mx,
y: my,
lastX: mx,
lastY: my,
hue: 0,
colorAngle: 0,
angle: angle + Math.PI/2,
//size: .5+dist/250,
size: rand(1,3)/2,
centerX: cw/2,
centerY: ch/2,
radius: dist,
speed: (rand(5,10)/1000)*(dist/750)+.015,
alpha: 1 - Math.abs(dist)/cw,
draw: function() {
ctx.strokeStyle = 'hsla('+this.colorAngle+',100%,50%,1)';
ctx.lineWidth = this.size;
ctx.beginPath();
ctx.moveTo(this.lastX, this.lastY);
ctx.lineTo(this.x, this.y);
ctx.stroke();
},
update: function(){
var mx = this.x;
var my = this.y;
this.lastX = this.x;
this.lastY = this.y;
var x1 = cw/2;
var y1 = ch/2;
var x2 = mx;
var y2 = my;
var rise = y1-y2;
var run = x1-x2;
var slope = -(rise/run);
var radian = Math.atan(slope);
var angleH = Math.floor(radian*(180/Math.PI));
if(x2 < x1 && y2 < y1){angleH += 180;}
if(x2 < x1 && y2 > y1){angleH += 180;}
if(x2 > x1 && y2 > y1){angleH += 360;}
if(y2 < y1 && slope =='-Infinity'){angleH = 90;}
if(y2 > y1 && slope =='Infinity'){angleH = 270;}
if(x2 < x1 && slope =='0'){angleH = 180;}
if(isNaN(angleH)){angleH = 0;}
this.colorAngle = angleH;
this.x = this.centerX + Math.sin(this.angle*-1) * this.radius;
this.y = this.centerY + Math.cos(this.angle*-1) * this.radius;
this.angle += this.speed;
}
});
}
 
function orbGo(e){
var mx = e.pageX - c.offsetLeft;
var my = e.pageY - c.offsetTop;
createOrb(mx,my);
}
 
function turnOnMove(){
c.addEventListener('mousemove', orbGo, false);
}
 
function turnOffMove(){
c.removeEventListener('mousemove', orbGo, false);
}
 
function toggleTrails(){
trail = trailCB.checked;
}
 
function clear(){
orbs = [];
}
 
c.addEventListener('mousedown', orbGo, false);
c.addEventListener('mousedown', turnOnMove, false);
c.addEventListener('mouseup', turnOffMove, false);
trailCB.addEventListener('change', toggleTrails, false);
clearer.addEventListener('click', clear, false);
 
var count = 100;
while(count--){
createOrb(cw/2, ch/2+(count*2));
}
 
var loop = function(){
window.requestAnimFrame(loop);
if(trail){
ctx.fillStyle = 'rgba(0,0,0,.1)';
ctx.fillRect(0,0,cw,ch);
} else {
ctx.clearRect(0,0,cw,ch);
}
var i = orbs.length;
while(i--){
var orb = orbs[i];
var updateCount = 3;
while(updateCount--){
orb.update();
orb.draw(ctx);
}
}
}
loop();
style.css
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
body {
background: #000;
color: #fff;
font: 100%/20px helvetica, arial, sans-serif;
}
 
canvas {
display: block;
height: 100%;
left: 0;
margin: 0;
padding: 0;
position: absolute;
top: 0;
width: 100%
}
 
#control-panel {
background: rgba(0,0,0,.75);
border: 1px solid #333;
left: 20px;
padding: 10px 15px;
position: absolute;
top: 20px;
z-index: 2;
}
 
p {
font-size: 12px;
margin: 0 0 5px;
}
 
label {
font-size: 12px;
font-weight: bold;
}
 
button {
display: block;
margin: 10px 0 0;
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.