Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
A CodePen by Jack Rugile. Canvas Orbital Trails - Click and drag anywhere on the screen to create new trails.
<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>
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();
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.