<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});
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.js
  2. https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js
  3. https://s3-us-west-2.amazonaws.com/s.cdpn.io/605067/OrbitControls.js
  4. https://s3-us-west-2.amazonaws.com/s.cdpn.io/605067/GeometryUtils.js