JSFiddle - React, Tailwind, and code Playground

by gerdonabbink

HTML

<script src="https://rawgit.com/mrdoob/three.js/dev/build/three.min.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/controls/OrbitControls.js"></script>

CSS

html,
body {
  margin: 0;
  padding: 0;
}

JavaScript

const DIMENSION = 1;
const SPHERE_SIZE = 0.15;
const PARTICLE_SIZE = 0.0035;
const PARTICLE_COUNT = 1000;
const PARTICLE_SPEED = 0.1;
const RING_SPEED = 5;
const ELLIPSE_EFFECT = 2;
const MAX_DISTANCE_FROM_SPHERE = 0.2;
const MAX_POINTS = 1000;

const MIN_DISTANCE_FROM_SPHERE = PARTICLE_SIZE * 50;

let particles = [];

let camera, scene, controls, renderer, sphere;

function lerp(a, b, t) {
  return (1 - t) * a + t * b
}

function updateParticlePosition(particle) {
  particle.elapsed += 1;

  let max_distance = MAX_DISTANCE_FROM_SPHERE + MIN_DISTANCE_FROM_SPHERE;
  let normalizeDistance = Math.max((particle.multiply - SPHERE_SIZE) / max_distance, 0);
  let speed = lerp(PARTICLE_SPEED * RING_SPEED, PARTICLE_SPEED, normalizeDistance);
  let effect = lerp(1, ELLIPSE_EFFECT, normalizeDistance);

  particle.float += speed;

  let vec = new THREE.Vector3(
    (1 * Math.sin(toRadians(particle.float)) - 0 * Math.cos(toRadians(particle.float))) * effect,
    particle.yOffset,
    1 * Math.cos(toRadians(particle.float)) - 0 * Math.sin(toRadians(particle.float))
  );

  vec.multiplyScalar(particle.multiply);

  particle.mesh.position.set(vec.x, vec.y, vec.z);
}

let Particle = function(mesh) {
  this.mesh = mesh;
  this.float = Math.random() * 360;
  this.yOffset = Math.random() * 0.05;
  this.ellipseEffect = 2;
  this.multiply = SPHERE_SIZE + (Math.random() * MAX_DISTANCE_FROM_SPHERE + MIN_DISTANCE_FROM_SPHERE);
  this.startMultiply = this.multiply;
  this.elapsed = 0;

  updateParticlePosition(this);

  scene.add(this.mesh);
}

let initThree = function() {
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0xeeeeee);

  camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.01, 10000);

  camera.position.z = DIMENSION * 2;
  camera.position.x = DIMENSION * 0.4;
  camera.position.y = DIMENSION * 0.7;
  camera.updateProjectionMatrix();

  scene.add(camera);

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
 ...