/*Downloaded from https://www.codeseek.co/2Mogs/pleasing-balls-2-LyWOPa */
(function(){
'use strict';
/* Using a constant for 2xPI is a good process saver.
It is called Tau because: http://tauday.com */
var wrapper, canvas, context, width, height,
starCanvas, starContext,
Tau=Math.PI*2, PI180=Math.PI/180,
systems=[];
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, element){
window.setTimeout(callback, 1000 / 60);
};
})();
/* PlanetarySystem */
var PlanetarySystem = function(id='pSys'){
Object.defineProperty(this, 'id', { value:id, writable:true} );
Object.defineProperty(this, 'x', { value:0, writable:true });
Object.defineProperty(this, 'y', { value:0, writable:true });
Object.defineProperty(this, 'allBodies', { value:[], writable:true });
Object.defineProperty(this, 'allBodiesLookup', { value:{}, writable:true }); // fast id lookup for children
Object.defineProperty(this, 'numBodies', { value:0, writable:true });
}
PlanetarySystem.prototype.addBody = function(vo) {
vo.parentSystem = this;
vo.parentBody = vo.parentBody === null ? this : this.allBodiesLookup[vo.parentBody];
var body = new PlanetaryBody(vo);
body.update();
this.allBodies.push(body);
this.allBodiesLookup[vo.id] = body;
this.numBodies += 1;
}
PlanetarySystem.prototype.setSpeedFactor = function(value){
var body;
for(var i=0; i<this.numBodies; i++){
body = this.allBodies[i];
body.setSpeedFactor(value);
}
}
PlanetarySystem.prototype.update = function(){
var body;
for(var i=0; i<this.numBodies; i++){
body = this.allBodies[i];
body.update();
}
}
PlanetarySystem.prototype.fxTimer = function(){
var that = this;
setInterval( function(){
for(var i=1; i<that.numBodies; i++){ // I'm ignoring the first - using it as a background
that.allBodies[i].scaleAndRadius();
}
}, 3000 );
}
/* PlanetaryBody */
var PlanetaryBody = function(vo){
Object.defineProperty(this, 'id', { value:vo.id, writable:true} );
Object.defineProperty(this, 'diameter', { value:vo.diameter, writable:true });
Object.defineProperty(this, 'colour', { value:vo.colour, writable:true });
Object.defineProperty(this, 'x', { value:0, writable:true });
Object.defineProperty(this, 'y', { value:0, writable:true });
Object.defineProperty(this, 'vx', { value:0, writable:true });
Object.defineProperty(this, 'vy', { value:0, writable:true });
Object.defineProperty(this, 'degrees', { value:vo.degrees, writable:true });
Object.defineProperty(this, 'speedBase', { value:vo.speed, writable:true });
Object.defineProperty(this, 'speed', { value:vo.speed , writable:true });
Object.defineProperty(this, 'orbitalRadius', { value:vo.orbitalRadius, writable:true });
Object.defineProperty(this, 'parentSystem', { value:vo.parentSystem, writable:true });
Object.defineProperty(this, 'parentBody', { value:vo.parentBody, writable:true });
Object.defineProperty(this, 'fxState', { value:vo.fxState, writable:true });
Object.defineProperty(this, 'inOrbitalRadius', { value:vo.inOrbitalRadius, writable:true });
Object.defineProperty(this, 'outOrbitalRadius', { value:vo.outOrbitalRadius, writable:true });
Object.defineProperty(this, 'inDiameter', { value:vo.inDiameter, writable:true });
Object.defineProperty(this, 'outDiameter', { value:vo.outDiameter, writable:true });
if(this.fxState){
this.diameter = this.inDiameter;
this.orbitalRadius = this.inOrbitalRadius;
} else if (this.fxState){
this.diameter = this.outDiameter;
this.orbitalRadius = this.outOrbitalRadius;
}
return this;
}
PlanetaryBody.prototype.update = function(){
var angle = this.degrees * PI180;
this.degrees += this.speed;
this.vx = this.orbitalRadius * Math.cos(angle);
this.vy = this.orbitalRadius * Math.sin(angle);
// update position
if(this.parentBody != null){
this.x = this.vx + this.parentBody.x;
this.y = this.vy + this.parentBody.y;
}
}
PlanetaryBody.prototype.scaleAndRadius = function(){
this.fxState = !this.fxState;
var newDiameter = this.fxState ? this.inDiameter : this.outDiameter;
var newOrbitalRadius = this.fxState ? this.inOrbitalRadius : this.outOrbitalRadius;
TweenLite.to(this, 1.5, {orbitalRadius:newOrbitalRadius, diameter:newDiameter, ease:easeOutBounce});
}
/* init() */
function init(){
wrapper = document.getElementById("wrapper");
canvas = createCanvas("canvas", width, height);
wrapper.appendChild(canvas);
context = canvas.getContext("2d");
setupEvents();
resizeCanvas();
/* Define new PlanetarySystem and set values */
var system1 = new PlanetarySystem('pSys1');
systems.push(system1);
system1.x = width * .5;
system1.y = height * .5;
system1.addBody({id:'sun', diameter:80, degrees:0, speed:1, fxState:false, inOrbitalRadius:0, outOrbitalRadius:0, inDiameter:50, outDiameter:50, colour:'#FDFE1D', orbitalRadius:0, parentBody:null});
system1.addBody({id:'ball1', diameter:50, degrees:0, speed:4, fxState:true, inOrbitalRadius:0, outOrbitalRadius:65, inDiameter:50, outDiameter:14, colour:'#202020', orbitalRadius:0, parentBody:'sun'});
system1.addBody({id:'ball2', diameter:14, degrees:180, speed:4, fxState:false, inOrbitalRadius:0, outOrbitalRadius:65, inDiameter:50, outDiameter:14, colour:'#202020', orbitalRadius:65, parentBody:'sun'});
system1.fxTimer();
}
/* Methods */
function createCanvas(id, w, h){
var tCanvas = document.createElement("canvas");
tCanvas.width = w;
tCanvas.height = h;
tCanvas.id = id;
return tCanvas;
}
function setupEvents(){
window.onresize = resizeCanvas;
}
function resizeCanvas(){
var rect = wrapper.getBoundingClientRect();
width = window.innerWidth;
height = window.innerHeight - rect.top -2;
canvas.width = width;
canvas.height = height;
for(var i=0; i<systems.length; i++){
systems[i].x = width * .5;
systems[i].y = height * .5;
}
}
function update(){
for(var loop=systems.length, i=0; i<loop; i++){
systems[i].update();
}
}
function draw(){
context.save();
var system;
for(var i=0; i<systems.length; i++){
system = systems[i];
var planetaryBody;
for(var loop=system.numBodies, j=0; j<loop; j+=1) {
planetaryBody = system.allBodies[j];
context.beginPath();
context.arc(planetaryBody.x, planetaryBody.y, planetaryBody.diameter, 0, Tau, false);
if(planetaryBody.isRing){
context.strokeStyle = planetaryBody.colour;
context.lineWidth = planetaryBody.ringWidth;
context.stroke();
}
else{
context.fillStyle = planetaryBody.colour;
context.fill();
}
}
}
context.restore();
}
function animate(){
context.clearRect(0, 0, width, height);
update();
draw();
if(!testSlow){
requestAnimFrame(animate);
}
}
init();
var PI = Math.PI,
halfPI = PI/2,
backSwing = 1.5, //1.70158
easeLinear = function (t, b, c, d) {
return c*t/d + b;
},
easePower0 = easeLinear,
easeInSine = function (t, b, c, d) {
return c * (1 - Math.cos(t/d * (halfPI))) + b;
},
easeOutSine = function (t, b, c, d) {
return c * Math.sin(t/d * (halfPI)) + b;
},
easeInOutSine = function (t, b, c, d) {
return c/2 * (1 - Math.cos(PI*t/d)) + b;
},
easeInQuad = function (t, b, c, d) {
return c*(t/=d)*t + b;
},
easeOutQuad = function (t, b, c, d) {
return -c * (t/=d)*(t-2) + b;
},
easeInOutQuad = function (t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t + b;
return -c/2 * ((--t)*(t-2) - 1) + b;
},
easeInPower1 = easeInQuad,
easeOutPower1 = easeInOutQuad,
easeOutPower1 = easeInOutQuad,
easeInExpo = function (t, b, c, d) {
return c * Math.pow(2, 10 * (t/d - 1)) + b;
},
easeOutExpo = function (t, b, c, d) {
return c * (-Math.pow(2, -10 * t/d) + 1) + b;
},
easeInOutExpo = function (t, b, c, d) {
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
},
easeInBack = function (t, b, c, d, s) {
if (s == undefined) s = backSwing;
return c*(t/=d)*t*((s+1)*t - s) + b;
},
easeOutBack = function (t, b, c, d, s) {
if (s == undefined) s = backSwing;
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
},
easeInOutBack = function (t, b, c, d, s) {
if (s == undefined) s = backSwing;
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
},
easeOutBounce = function (t, b, c, d) {
if ((t/=d) < (1/2.75)) {
return c*(7.5625*t*t) + b;
} else if (t < (2/2.75)) {
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
} else if (t < (2.5/2.75)) {
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
} else {
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
}
};
/*** TWEENING END ***/
var testSlow = false;
if(testSlow){
var w = setInterval(function(){
animate();
},(1000/30));
}
else{
animate();
}
}());