<div class="triggers">
<span data-disabled="true" data-color="#3D8CD0">CLICK</span>
<span data-disabled="true" data-color="#D32A7B">TO</span>
<span data-disabled="true" data-color="#2AD37A">SWITCH</span>
</div>
body {
font-family: 'Titillium Web', sans-serif;
margin: 0;
overflow: hidden;
}
.triggers {
bottom: 20px;
color: white;
left: 50%;
position: absolute;
text-align: center;
transform: translateX(-50%);
width: 100%;
z-index: 10;
span {
cursor: pointer;
display: inline-block;
font-size: 14px;
margin: 0 20px;
padding: 2px 4px;
transition: opacity .5s, color .5s;
&[data-disabled="true"] {
opacity: 0.3;
pointer-events: none;
}
&:hover {
color: red;
}
}
}
View Compiled
// Options
const particleCount = 6000;
const particleSize = .3;
const defaultAnimationSpeed = 1,
morphAnimationSpeed = 18,
color = '#FFFFFF';
// Triggers
const triggers = document.getElementsByTagName('span')
// Renderer
var renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// Ensure Full Screen on Resize
function fullScreen () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
window.addEventListener('resize', fullScreen, false)
// Scene
var scene = new THREE.Scene();
// Camera and position
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.y = -45;
camera.position.z = 45;
// Lighting
var light = new THREE.AmbientLight( 0xFFFFFF, 1 );
scene.add( light );
// Orbit Controls
var controls = new THREE.OrbitControls( camera );
controls.update();
// Particle Vars
var particles = new THREE.Geometry();
var texts = [];
var pMaterial = new THREE.PointCloudMaterial({
size: particleSize,
});
// Texts
var loader = new THREE.FontLoader();
var typeface = 'https://dl.dropboxusercontent.com/s/bkqic142ik0zjed/swiss_black_cond.json?';
loader.load( typeface, ( font ) => {
Array.from(triggers).forEach((trigger, idx) => {
texts[idx] = {};
texts[idx].geometry = new THREE.TextGeometry( trigger.textContent, {
font: font,
size: window.innerWidth * 0.02,
height: 4,
curveSegments: 10,
});
THREE.GeometryUtils.center( texts[idx].geometry )
texts[idx].particles = new THREE.Geometry();
texts[idx].points = THREE.GeometryUtils.randomPointsInGeometry(texts[idx].geometry, particleCount);
createVertices(texts[idx].particles, texts[idx].points)
enableTrigger(trigger, idx);
});
});
// Particles
for (var p = 0; p < particleCount; p++) {
var vertex = new THREE.Vector3();
vertex.x = 0;
vertex.y = 0;
vertex.z = 0;
particles.vertices.push(vertex);
}
function createVertices (emptyArray, points) {
for (var p = 0; p < particleCount; p++) {
var vertex = new THREE.Vector3();
vertex.x = points[p]['x'];
vertex.y = points[p]['y'];
vertex.z = points[p]['z'];
emptyArray.vertices.push(vertex);
}
}
function enableTrigger(trigger, idx){
trigger.setAttribute('data-disabled', false);
trigger.addEventListener('click', () => {
morphTo(texts[idx].particles, trigger.dataset.color);
})
if (idx == 0) {
morphTo(texts[idx].particles, trigger.dataset.color);
}
}
var particleSystem = new THREE.PointCloud(
particles,
pMaterial
);
particleSystem.sortParticles = true;
// Add the particles to the scene
scene.add(particleSystem);
// Animate
const normalSpeed = (defaultAnimationSpeed/100),
fullSpeed = (morphAnimationSpeed/100)
let animationVars = {
speed: normalSpeed,
color: color,
rotation: -45
}
function animate() {
particleSystem.rotation.y += animationVars.speed;
particles.verticesNeedUpdate = true;
camera.position.z = animationVars.rotation;
camera.position.y = animationVars.rotation;
camera.lookAt( scene.position );
particleSystem.material.color = new THREE.Color( animationVars.color );
window.requestAnimationFrame( animate );
renderer.render( scene, camera );
}
animate();
function morphTo (newParticles, color = '#FFFFFF') {
TweenMax.to(animationVars, .1, {
ease: Power4.easeIn,
speed: fullSpeed,
onComplete: slowDown
});
TweenMax.to(animationVars, 2, {
ease: Linear.easeNone,
color: color
});
// particleSystem.material.color.setHex(color);
for (var i = 0; i < particles.vertices.length; i++){
TweenMax.to(particles.vertices[i], 2, {
ease: Elastic.easeOut.config( 0.1, .3),
x: newParticles.vertices[i].x,
y: newParticles.vertices[i].y,
z: newParticles.vertices[i].z
})
}
console.log(animationVars.rotation)
TweenMax.to(animationVars, 2, {
ease: Elastic.easeOut.config( 0.1, .3),
rotation: animationVars.rotation == 45 ? -45 : 45,
})
}
function slowDown () {
TweenMax.to(animationVars, 0.3, {ease:
Power2.easeOut, speed: normalSpeed, delay: 0.2});
}
This Pen doesn't use any external CSS resources.