Click the above image to see a recreation of a previous Flash experiment (source code here), using Three.js. And see below for the source code used to create this thing.
// shim layer with setTimeout fallback set to 60 frames per second
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var canvas,
stage,
container,
scene,
camera,
renderer,
projector,
light;
var w = 800;
var h = 600;
var VIEW_ANGLE = 45;
var ASPECT = w/h;
var NEAR = .1;
var FAR = 10000;
var centerX = 0;
var centerY = 0;
var centerZ = 0;
var radius = 175;
var cameraRadius = 1000;
var cameraX = cameraRadius;
var cameraY = cameraRadius;
var cameraZ = cameraRadius;
var theta = 0;
var group;
var objects = [];
var numObjects = 0;
var orbitSteps = 1000;
var orbitSpeed = Math.PI*2/orbitSteps;
var objectInterval;
var objectPosition;
var direction = 1;
var index = 0;
var startingObjects = 400;
onload = init;
function init() {
canvas = document.getElementById("myCanvas");
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR );
camera.position.x = cameraX;
camera.position.y = cameraY;
camera.position.z = cameraZ;
camera.lookAt(scene.position);
scene.add( camera );
projector = new THREE.Projector();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( w, h );
light = new THREE.SpotLight();
light.position.set( centerX, centerY, 160 );
scene.add(light);
canvas.appendChild( renderer.domElement );
renderer.render(scene,camera);
initObjects();
onEnterFrame();
}
function initObjects() {
group = new THREE.Object3D();
group.position.x = centerX;
group.position.y = centerY;
group.position.x = centerZ;
for(var i=0;i<startingObjects;i++) {
addObject();
}
scene.add(group);
}
function addObject() {
var sphereMaterial = new THREE.MeshLambertMaterial({
color: Math.round(Math.random()*0xffffff)
});
var obj = new THREE.Mesh(
new THREE.SphereGeometry(8,8,8), // radius,segments,rings
sphereMaterial);
obj.position.x = 0;
obj.position.y = 0;
obj.position.z = 0;
obj.overdraw = true;
group.add(obj);
objects.push(obj);
numObjects = objects.length;
objectInterval = orbitSteps/numObjects;
}
function onEnterFrame() {
requestAnimFrame(onEnterFrame);
renderer.render(scene,camera);
for(var i = 0; i < numObjects; i++) {
objectPosition = orbitSpeed*objectInterval*i; // each object is individually updated
objects[i].position.x = radius * (Math.cos(theta + objectPosition) * (Math.pow(5,Math.cos(theta+objectPosition)) - 2 * Math.cos(4 * (theta+objectPosition)) - Math.pow(Math.sin((theta+objectPosition)/12),4)));
objects[i].position.y = radius * (Math.sin(theta + objectPosition) * (Math.pow(5,Math.cos(theta+objectPosition)) - 2 * Math.cos(4 * (theta+objectPosition)) - Math.pow(Math.sin((theta+objectPosition)/12),4)));
objects[i].position.z = centerZ + radius * Math.sin(theta + objectPosition) - radius*1*(Math.sin((radius/radius + 3) * (theta + objectPosition)));
}
group.rotation.x += .002;
group.rotation.y += .004;
group.rotation.z += .008;
theta += (orbitSpeed*direction);
}
