```
var Shape = {
Sphere: function(objs, opts) {
var s = opts.s || 200,
atan2 = Math.atan2,
cos = Math.cos,
acos = Math.acos,
sin = Math.sin,
sqrt = Math.sqrt;
for(var i=0, l=objs.length; i<l; i++) {
var obj = objs[i],
pos = obj.pos,
x = pos.x,
y = pos.y,
z = pos.z,
r = x * x + y * y + z * z,
theta = acos(z / sqrt(r)),
phi = atan2(y, (x || 1));
if(!obj.sphere) {
obj.sphere = new THREE.Vector4();
}
var pos = obj.pos, sphere = obj.sphere;
pos.x = sphere.x = s * sin(theta) * cos(phi);
pos.y = sphere.y = s * sin(theta) * sin(phi);
pos.z = sphere.z = s * cos(theta);
}
}
//...other shapes here...
};
```

```
//transitions object. can be used like
//Trans.linear, or Trans.Elastic.easeOut, etc.
var Trans = {
linear: function(p){
return p;
}
};
(function(){
//add easing equations as methods
//of the transition object/function
//i.e add easeIn/Out to the Elastic/Sine objects
var makeTrans = function(transition, params){
var trans = {
easeIn: function(pos){
return transition(pos, params);
},
easeOut: function(pos){
return 1 - transition(1 - pos, params);
},
easeInOut: function(pos){
return (pos <= 0.5)? transition(2 * pos, params) / 2
: (2 - transition(2 * (1 - pos), params)) / 2;
}
};
for(var p in trans) {
transition[p] = trans[p];
}
return transition;
};
//transition equations
var transitions = {
Sine: function(p){
return 1 - Math.sin((1 - p) * Math.PI / 2);
},
Elastic: function(p, x){
return Math.pow(2, 10 * --p)
* Math.cos(20 * p * Math.PI * (x[0] || 1) / 3);
}
//...other transitions here...
};
//enhance the Trans object with new transitons
for(var p in transitions) {
Trans[p] = makeTrans(transitions[p]);
}
})();
```

```
//draw scene
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 500.0);
loadIdentity();
mvTranslate([0.0, 0.0, -150.0]);
mvRotateX(rx);
mvRotateY(ry);
for(var i=0, l=parts.length, vertices=[]; i<l; i++) {
var p = parts[i].pos;
vertices.push(p.x, p.y, p.z);
}
//create and store and bind vertex data
gl.bindBuffer(gl.ARRAY_BUFFER, ballsPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
ballsPositionBuffer.itemSize,
gl.FLOAT, false, 0, 0);
//set model view and perspective matrix
setMatrixUniforms();
//set color and object scaling
gl.uniform1f(shaderProgram.scaleUniform, s);
gl.uniform3f(shaderProgram.colorUniform, r, g, b);
//draw
gl.drawArrays(gl.POINTS, 0, ballsPositionBuffer.numItems);
```

```
abstract class Transitions extends Function[Float, Float] {
private def easeInVar(x: Float, i: Float = 1.0): Float = apply(i * x);
private def easeOutVar(x: Float, i: Float = 1.0): Float = i - apply(i * (1 - x));
def easeIn(x: Float) = easeInVar(x);
def easeOut(x: Float) = easeOutVar(x);
def easeInOut(x: Float): Float = (if (x <= 0.5) easeInVar(x, 2) else easeOutVar(x, 2)) /2
}
object Transitions {
private val pi = Pi;
def linear(x: Float) = x;
object Sine extends Transitions {
override def apply(x: Float): Float = 1 - sin((1 - x) * pi / 2)
}
object Back extends Transitions {
override def apply(p: Float): Float = {
val x = 1.618;
pow(p, 2) * ((x + 1) * p - x);
}
}
//...other objects here...
}
```

```
Transitions.linear _;
Transitions.Elastic.easeOut _;
```

```
Transitions.Elastic.apply(0.5); //is the same as...
Transitions.Elastic(0.5);
Transitions.Elastic.easeOut.apply(0.5); //is the same as...
Transitions.Elastic.easeOut(0.5);
```