Pleasing Balls (2)

In this example below you will see how to do a Pleasing Balls (2) with some HTML / CSS and Javascript

Rotating particles, using the core JavaScript from my Orrey. Inspired by https://beesandbombs.tumblr.com/image/158720584694

Thumbnail
This awesome code was written by 2Mogs, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright 2Mogs ©
  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Pleasing Balls (2)</title>
  
  
  
      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  <div id="wrapper"></div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenLite.min.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/2Mogs/pleasing-balls-2-LyWOPa */
body{
				background: #202020;
			}

/*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();
	}

}());

Comments