Working on a larger -personal- project involving a similar animation. Still tooling with it.
A Pen by Matthew Daniel Brown on CodePen.
Working on a larger -personal- project involving a similar animation. Still tooling with it.
A Pen by Matthew Daniel Brown on CodePen.
var scene, camera, renderer; | |
var container, HEIGHT, | |
WIDTH, fieldOfView, aspectRatio, | |
nearPlane, farPlane, stats, | |
geometry, particleCount, | |
i, h, color, size, | |
materials = [], | |
mouseX = 0, | |
mouseY = 0, | |
windowHalfX, windowHalfY, cameraZ, | |
fogHex, fogDensity, parameters = {}, | |
parameterCount, particles; | |
init(); | |
requestAnimationFrame(animate); | |
function init() { | |
HEIGHT = window.innerHeight; | |
WIDTH = window.innerWidth; | |
windowHalfX = WIDTH / 2; | |
windowHalfY = HEIGHT / 2; | |
fieldOfView = 75; | |
aspectRatio = WIDTH / HEIGHT; | |
nearPlane = 1; | |
farPlane = 3000; | |
cameraZ = farPlane / 3; | |
fogHex = 0xff0000; | |
fogDensity = 0.0007; | |
camera = new THREE.PerspectiveCamera(fieldOfView, aspectRatio, nearPlane, farPlane); | |
camera.position.z = cameraZ; | |
scene = new THREE.Scene(); | |
//scene.fog = new THREE.FogExp2(fogHex, fogDensity); | |
container = document.createElement('div'); | |
document.body.appendChild(container); | |
document.body.style.margin = 0; | |
document.body.style.overflow = 'hidden'; | |
particleCount = 10000; | |
//particles.geometry.colors[i] = new THREE.Color().setHSL(((i/len) + time) % 1, 1, 0.5); | |
//particles.geometry.colorsNeedUpdate = true; | |
material = new THREE.PointsMaterial({ | |
size: 4, | |
//color: 0xffffff, //, | |
//transparent: true, | |
//opacity: .8,//, | |
//blending: THREE.AdditiveBlending, | |
depthTest: true, | |
depthWrite: true, | |
sizeAttenuation: true, | |
vertexColors: THREE.VertexColors | |
}); | |
var colors = [[255, 0, 0], [0, 255, 0], [128, 0, 255], [255, 255, 0]]; | |
var pointColors = []; | |
for (c = 0; c < colors.length; c++) { | |
var col = colors[c]; | |
geometry = new THREE.Geometry(); | |
for (i = 0; i < particleCount; i++) { | |
var vertex = new THREE.Vector3(); | |
p = spherePointPicking(600- (c*100)); | |
vertex.x = p.x; | |
vertex.y = p.y; | |
vertex.z = p.z; | |
geometry.vertices.push(vertex); | |
geometry.colors.push(new THREE.Color(col[0]/255, col[1]/255, col[2]/255)); | |
} | |
particles = new THREE.Points(geometry, material); | |
particles.sortParticles = true; | |
//particles.rotation.x = Math.random() * 6; | |
//particles.rotation.y = Math.random() * 6; | |
//particles.rotation.z = Math.random() * 6; | |
scene.add(particles); | |
} | |
//var light = new THREE.PointLight( 0xffffff, 10, 1000, 0 ); | |
//light.position.set( 500, 500, 500 ); | |
//scene.add( light ); | |
renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); | |
renderer.setPixelRatio(window.devicePixelRatio); | |
renderer.setSize(WIDTH, HEIGHT); | |
container.appendChild(renderer.domElement); | |
stats = new Stats(); | |
stats.domElement.style.position = 'absolute'; | |
stats.domElement.style.top = '0px'; | |
stats.domElement.style.right = '0px'; | |
container.appendChild(stats.domElement); | |
window.addEventListener('resize', onWindowResize, false); | |
document.addEventListener('mousemove', onDocumentMouseMove, false); | |
document.addEventListener('touchstart', onDocumentTouchStart, false); | |
document.addEventListener('touchmove', onDocumentTouchMove, false); | |
} | |
function animate() { | |
requestAnimationFrame(animate); | |
render(); | |
stats.update(); | |
} | |
function render() { | |
var time = Date.now() * 0.0005; | |
camera.position.x += (mouseX - camera.position.x) * 0.05; | |
camera.position.y += (-mouseY - camera.position.y) * 0.05; | |
camera.lookAt(scene.position); | |
for (i = 0; i < scene.children.length; i++) { | |
var object = scene.children[i]; | |
if (object instanceof THREE.Points) { | |
if(i==0) object.rotation.y = time/6; | |
if(i==1) object.rotation.y = -time/2; | |
if(i==2) object.rotation.y = time/2; | |
if(i==3) object.rotation.y = time; | |
} | |
} | |
//Every particle has its own color... | |
//var len = particleCount; | |
//for(var i = 0; i < len; i++) | |
// particles.geometry.colors[i] = new THREE.Color().setHSL(((i/len) + time) % 1, 1, 0.5); | |
//particles.geometry.colorsNeedUpdate = true; | |
renderer.render(scene, camera); | |
} | |
function onDocumentMouseMove(e) { | |
mouseX = e.clientX - windowHalfX; | |
mouseY = e.clientY - windowHalfY; | |
} | |
function onDocumentTouchStart(e) { | |
if (e.touches.length === 1) { | |
e.preventDefault(); | |
mouseX = e.touches[0].pageX - windowHalfX; | |
mouseY = e.touches[0].pageY - windowHalfY; | |
} | |
} | |
function onDocumentTouchMove(e) { | |
if (e.touches.length === 1) { | |
e.preventDefault(); | |
mouseX = e.touches[0].pageX - windowHalfX; | |
mouseY = e.touches[0].pageY - windowHalfY; | |
} | |
} | |
function onWindowResize() { | |
windowHalfX = window.innerWidth / 2; | |
windowHalfY = window.innerHeight / 2; | |
camera.aspect = window.innerWidth / window.innerHeight; | |
camera.updateProjectionMatrix(); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
} | |
function spherePointPicking(radius){ | |
var u1 = Math.random(); | |
var u2 = Math.random(); | |
var s = Math.acos(2 * u1 - 1) - Math.PI / 2; | |
var t = 2 * Math.PI * u2; | |
return {x : radius * Math.cos(s) * Math.cos(t), | |
y : radius * Math.cos(s) * Math.sin(t), | |
z : radius * Math.sin(s) | |
} | |
} |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r11/Stats.min.js"></script> |
html { | |
background: black; | |
} |