``````<div id="container">
<canvas id="mycanvas" width="640" height="480">
</canvas>

<div>

<div>Clear Scene Graph</div>
<button class="controller" onclick="sceneGraph = []"> CLEAR </button>

<div> Total Particles: <span id="partCount">0</span> </div>
</div>
</div>
``````
``````#container {
display: flex;
flex-direction: row;
}

button.controller {
min-width: 122px;
border: none;
font-family: 'helvetica';
background: #7371e0;
color: white
}``````
``````let sceneGraph = [];
let globalTime = 0;
let initTime = 0;

class Particle {
constructor(cx, cy, r, fill, orbit) {
this.cx = cx;
this.cy = cy;
this.r = r;
this.fill = fill;
this.orbit = orbit;
}

update(ctx) {
if(this.orbit){
let {x,y} = this.orbit.update();
this.cx = x;
this.cy = y;
}
ctx.fillStyle = this.fill;
ctx.beginPath();
ctx.arc(this.cx, this.cy, this.r, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
}
}

/**
Orbiter is simply a form of parametric equation, given a parameter t, it will spew out a co-ordinate x,y
*/
class Orbit {
constructor(x, y, r, lifeTime, initPos) {
this.x = x;
this.y = y;
this.r = r;
this.curPos = initPos % (2*Math.PI);
this.initPos = initPos % (2*Math.PI);
this.initTime = globalTime;
}

update() {
// for x,y co-ordinate we need the angle theta, which is curPos,
let curTime = globalTime;
// we need the difference to calculate the curPos
let deltaTime = curTime - this.initTime;
// in N ms, it completes 2Pi radians
// in 1ms, it completes 2Pi/N radians
// in k ms, it completes 2*k*Pi/N radians
let curPos = this.initPos + (2 * deltaTime * Math.PI) / this.lifeTime;
// since it is cyclic, i.e. it completes a cycle, we can simply take a modulo
this.curPos = curPos % (2 * Math.PI);

// we have the angle, thus, we can find the x,y co-ordinates using formulas
// x(theta) = R*sin(theta) + cx
// y(theta) = R*sin(theta) + cy
let xVal = this.r * Math.cos(this.curPos) + this.x;
let yVal = this.r * Math.sin(this.curPos) + this.y;
return { x: xVal, y: yVal };
}
}

function redrawSurface() {
let canvas = document.getElementById("mycanvas");
globalTime = Date.now() - initTime;

let ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (obj of sceneGraph) {
obj.update(ctx);
}
document.getElementById("partCount").innerHTML = sceneGraph.length.toString();
requestAnimationFrame(redrawSurface);
}

// generate random parameters for particle
let x = Math.floor(Math.random() * 640);
let y = Math.floor(Math.random() * 480);
let r = Math.ceil(Math.random() * 4 + 1);
let color = `rgb(\${Math.ceil(Math.random(0) * 255)}, \${Math.ceil(
Math.random(0) * 255
)}, \${Math.ceil(Math.random(0) * 255)})`;

// generate random orbit for particle
let Ox = Math.floor(Math.random() * 540) + 50;
let Oy = Math.floor(Math.random() * 380) + 50;
let Or = Math.ceil(Math.random()*150) + 100;
let Olt = Math.ceil(Math.random() * 25000) + 1000;
let Oip = Math.floor(Math.random() * 2 * Math.PI);

let orbit = new Orbit(Ox, Oy, Or, Olt, Oip);
let part = new Particle(x, y, r, color, orbit);
sceneGraph.push(part);
console.log(part);
}

let canvas = document.getElementById("mycanvas");
let ctx = canvas.getContext("2d");
initTime = Date.now();

for(let i=0; i<100; i++){