A Pen by Sepand Ansari on CodePen.
Last active
September 11, 2015 14:23
-
-
Save sepans/f0cb08a52269a6a3e8ab to your computer and use it in GitHub Desktop.
particles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="container"></div> | |
<div id='sections'> | |
<section class="step active"> | |
<div class="title">Title</div> | |
data not too large and managable | |
</section> | |
<section class="step"> | |
<div class="title">Title 2</div> | |
your data grows as your business grows | |
</section> | |
<section class="step"> | |
<div class="title">Title 3</div> | |
Examine data more closely | |
</section> | |
<section class="step"> | |
<div class="title">Title 4</div> | |
discover relations in your data | |
</section> | |
<section class="step"> | |
<div class="title">Title 5</div> | |
Get the big picture | |
</section> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var group; | |
var container, stats; | |
var particlesData = []; | |
var camera, scene, renderer; | |
var positions, colors; | |
var pointCloud; | |
var particlePositions; | |
var linesMesh; | |
var maxParticleCount = 1000; | |
var particleCount = 300; | |
var r = 800; | |
var rHalf = r / 2; | |
var effectController = { | |
showDots: true, | |
showLines: true, | |
minDistance: 10, | |
limitConnections: false, | |
maxConnections: 20, | |
particleCount: 300 | |
} | |
init(); | |
animate(); | |
function initGUI() { | |
var gui = new dat.GUI(); | |
gui.add(effectController, "showDots").onChange(function(value) { | |
pointCloud.visible = value; | |
}); | |
gui.add(effectController, "showLines").onChange(function(value) { | |
linesMesh.visible = value; | |
}); | |
gui.add(effectController, "minDistance", 10, 300); | |
gui.add(effectController, "limitConnections"); | |
gui.add(effectController, "maxConnections", 0, 30, 1); | |
gui.add(effectController, "particleCount", 0, maxParticleCount, 1).onChange(function(value) { | |
particleCount = parseInt(value); | |
particles.drawcalls[0].count = particleCount; | |
}); | |
} | |
/* | |
setTimeout(function() { | |
addDots(); | |
}, 2500); | |
setTimeout(function() { | |
zoom(1200); | |
}, 4000); | |
setTimeout(function() { | |
zoom(1750); | |
}, 10000); | |
setTimeout(animateConnections, 12000); | |
*/ | |
var scrollFunctions = [ addDots, function() {zoom(800)}, animateConnections, function() {zoom(1750)}]; | |
var scrollFunctionsCalled = [false, false, false, false]; | |
function initScroll() { | |
var sectionPositions = []; | |
var sections = document.querySelectorAll('.step');//$('.step'); | |
var startPos; | |
[].forEach.call(sections,function(d,i) { | |
var top = d.getBoundingClientRect().top; | |
if(i === 0) { | |
startPos = top; | |
} | |
sectionPositions.push(top - startPos); | |
}); | |
var $document = $(this); | |
// thia ia nor good! refactor! | |
$document.scroll(function() { | |
for (var i = sectionPositions.length-1; i >= 0 ; i--) { | |
if ($document.scrollTop() >= sectionPositions[i] + 700) { | |
// console.log(' section' + i, scrollFunctionsCalled[i] ); | |
if(!scrollFunctionsCalled[i]) { | |
//$(sections).removeClass('active'); | |
//$(sections[i+1]).addClass('active'); | |
sections[i].classList.remove('active'); | |
sections[i+1].classList.add('active'); | |
console.log(i+1,sections[i+1], sections[i+1].classList); | |
//sections[] | |
scrollFunctions[i](); | |
scrollFunctionsCalled[i] = true; | |
} | |
break; | |
} | |
} | |
}) | |
} | |
function init() { | |
//initGUI(); | |
initScroll(); | |
container = document.getElementById('container'); | |
// | |
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 4000); | |
camera.position.z = 1750; | |
controls = new THREE.OrbitControls(camera, container); | |
scene = new THREE.Scene(); | |
group = new THREE.Group(); | |
scene.add(group); | |
/* | |
var helper = new THREE.BoxHelper( new THREE.Mesh( new THREE.BoxGeometry( r, r, r ) ) ); | |
helper.material.color.setHex( 0x030303 ); | |
helper.material.blending = THREE.AdditiveBlending; | |
helper.material.transparent = true; | |
group.add( helper ); | |
*/ | |
var segments = maxParticleCount * maxParticleCount; | |
positions = new Float32Array(segments * 3); | |
colors = new Float32Array(segments * 3); | |
var pMaterial = new THREE.PointCloudMaterial({ | |
color: 0xC5C5FF, | |
size: 3, | |
blending: THREE.AdditiveBlending, | |
transparent: true, | |
sizeAttenuation: false | |
}); | |
particles = new THREE.BufferGeometry(); | |
particlePositions = new Float32Array(maxParticleCount * 3); | |
for (var i = 0; i < maxParticleCount; i++) { | |
var x = Math.random() * r - r / 2; | |
var y = Math.random() * r - r / 2; | |
var z = Math.random() * r - r / 2; | |
particlePositions[i * 3] = x; | |
particlePositions[i * 3 + 1] = y; | |
particlePositions[i * 3 + 2] = z; | |
// add it to the geometry | |
particlesData.push({ | |
velocity: new THREE.Vector3(0, 0, 0), | |
//velocity: new THREE.Vector3( -1 + Math.random() * 2, -1 + Math.random() * 2, -1 + Math.random() * 2 ), | |
numConnections: 0 | |
}); | |
} | |
particles.drawcalls.push({ | |
start: 0, | |
count: particleCount, | |
index: 0 | |
}); | |
particles.addAttribute('position', new THREE.DynamicBufferAttribute(particlePositions, 3)); | |
// create the particle system | |
pointCloud = new THREE.PointCloud(particles, pMaterial); | |
group.add(pointCloud); | |
var geometry = new THREE.BufferGeometry(); | |
geometry.addAttribute('position', new THREE.DynamicBufferAttribute(positions, 3)); | |
geometry.addAttribute('color', new THREE.DynamicBufferAttribute(colors, 3)); | |
geometry.computeBoundingSphere(); | |
geometry.drawcalls.push({ | |
start: 0, | |
count: 0, | |
index: 0 | |
}); | |
var material = new THREE.LineBasicMaterial({ | |
vertexColors: 0xFF0000, //THREE.VertexColors, | |
blending: THREE.AdditiveBlending, | |
transparent: true | |
}); | |
linesMesh = new THREE.Line(geometry, material, THREE.LinePieces); | |
group.add(linesMesh); | |
// | |
renderer = new THREE.WebGLRenderer({ | |
antialias: true | |
}); | |
renderer.setPixelRatio(window.devicePixelRatio); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
renderer.gammaInput = true; | |
renderer.gammaOutput = true; | |
container.appendChild(renderer.domElement); | |
// | |
stats = new Stats(); | |
stats.domElement.style.position = 'absolute'; | |
stats.domElement.style.top = '0px'; | |
container.appendChild(stats.domElement); | |
window.addEventListener('resize', onWindowResize, false); | |
/* | |
setTimeout(function() { | |
addDots(); | |
}, 2500); | |
setTimeout(function() { | |
zoom(1200); | |
}, 4000); | |
setTimeout(function() { | |
zoom(1750); | |
}, 10000); | |
setTimeout(animateConnections, 12000); | |
*/ | |
} | |
function onWindowResize() { | |
camera.aspect = window.innerWidth / window.innerHeight; | |
camera.updateProjectionMatrix(); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
} | |
function animate() { | |
var vertexpos = 0; | |
var colorpos = 0; | |
var numConnected = 0; | |
for (var i = 0; i < particleCount; i++) | |
particlesData[i].numConnections = 0; | |
for (var i = 0; i < particleCount; i++) { | |
// get the particle | |
var particleData = particlesData[i]; | |
particlePositions[i * 3] += particleData.velocity.x; | |
particlePositions[i * 3 + 1] += particleData.velocity.y; | |
particlePositions[i * 3 + 2] += particleData.velocity.z; | |
if (particlePositions[i * 3 + 1] < -rHalf || particlePositions[i * 3 + 1] > rHalf) | |
particleData.velocity.y = -particleData.velocity.y; | |
if (particlePositions[i * 3] < -rHalf || particlePositions[i * 3] > rHalf) | |
particleData.velocity.x = -particleData.velocity.x; | |
if (particlePositions[i * 3 + 2] < -rHalf || particlePositions[i * 3 + 2] > rHalf) | |
particleData.velocity.z = -particleData.velocity.z; | |
if (effectController.limitConnections && particleData.numConnections >= effectController.maxConnections) | |
continue; | |
// Check collision | |
for (var j = i + 1; j < particleCount; j++) { | |
var particleDataB = particlesData[j]; | |
if (effectController.limitConnections && particleDataB.numConnections >= effectController.maxConnections) | |
continue; | |
var dx = particlePositions[i * 3] - particlePositions[j * 3]; | |
var dy = particlePositions[i * 3 + 1] - particlePositions[j * 3 + 1]; | |
var dz = particlePositions[i * 3 + 2] - particlePositions[j * 3 + 2]; | |
var dist = Math.sqrt(dx * dx + dy * dy + dz * dz); | |
if (dist < effectController.minDistance) { | |
particleData.numConnections++; | |
particleDataB.numConnections++; | |
var alpha = 1.0 - dist / effectController.minDistance; | |
positions[vertexpos++] = particlePositions[i * 3]; | |
positions[vertexpos++] = particlePositions[i * 3 + 1]; | |
positions[vertexpos++] = particlePositions[i * 3 + 2]; | |
positions[vertexpos++] = particlePositions[j * 3]; | |
positions[vertexpos++] = particlePositions[j * 3 + 1]; | |
positions[vertexpos++] = particlePositions[j * 3 + 2]; | |
colors[colorpos++] = alpha; | |
colors[colorpos++] = alpha; | |
colors[colorpos++] = alpha; | |
colors[colorpos++] = alpha; | |
colors[colorpos++] = alpha; | |
colors[colorpos++] = alpha; | |
numConnected++; | |
} | |
} | |
} | |
linesMesh.visible = effectController.showLines; | |
linesMesh.geometry.drawcalls[0].count = numConnected * 2; | |
linesMesh.geometry.attributes.position.needsUpdate = true; | |
linesMesh.geometry.attributes.color.needsUpdate = true; | |
pointCloud.geometry.attributes.position.needsUpdate = true; | |
requestAnimationFrame(animate); | |
stats.update(); | |
render(); | |
} | |
//var i = 0; | |
function render() { | |
var time = Date.now() * 0.001; | |
group.rotation.y = time * 0.02; | |
renderer.render(scene, camera); | |
} | |
function addDots() { | |
var tween = new createjs.Tween(particles.drawcalls[0]).to({ | |
count: 800 | |
}, 4000, createjs.Ease.getPowInOut(4)); | |
} | |
function animateConnections() { | |
var minDistTween = new createjs.Tween(effectController).to({ | |
minDistance: r / 6 | |
}, 8000, createjs.Ease.getPowInOut(4)); | |
} | |
function zoom(zoomTo) { | |
var zTween = new createjs.Tween(camera.position).to({ | |
z: zoomTo ? zoomTo : 1200 | |
}, 5000, createjs.Ease.getPowInOut(4)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
<script src="http://threejs.org/examples/js/libs/dat.gui.min.js"></script> | |
<script src="http://threejs.org/build/three.min.js"></script> | |
<script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script> | |
<script src="http://threejs.org/examples/js/libs/stats.min.js"></script> | |
<script src="https://code.createjs.com/tweenjs-0.6.1.min.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
color: #cccccc; | |
font-family: Monospace; | |
font-size: 13px; | |
text-align: center; | |
background-color: #000000; | |
margin: 0px; | |
/*overflow: hidden;*/ | |
height: 100%; | |
} | |
body { | |
height: 100%; | |
} | |
#container { | |
position: fixed; | |
top: 50px; | |
pointer-events:none; | |
} | |
#sections { | |
width: 100%; | |
overflow-y: scroll; | |
height: 100%; | |
margin-top: 150px; | |
} | |
section { | |
height: 850px; | |
overflow-y: hide; | |
opacity: 0.1; | |
font-size: 16px; | |
transition: opacity 1s ease-in; | |
margin-top: 100px; | |
} | |
section.active { | |
opacity: 0.9; | |
} | |
.step .title { | |
font-size: 24px; | |
} | |
a { | |
color: #0080ff; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment