JSFiddle - React, Tailwind, and code Playground

by tfoller

HTML

<link type="text/css" rel="stylesheet" href="https://alikim.com/_v1_jsm/css/controls.css">

JavaScript

import * as CONTROLS from 'https://alikim.com/_v1_jsm/controls.js'

import {
  hsvRgb
} from 'https://alikim.com/_v1_jsm/glsl_ported.js'

import * as THREE from 'https://unpkg.com/three/build/three.module.js'

const cont = document.documentElement;
const [w, h] = [cont.clientWidth - 20, cont.clientHeight - 20];
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(50, w / h, 0.1, 100);


const renderer = new THREE.WebGLRenderer();
renderer.setSize(w, h);
document.body.appendChild(renderer.domElement);

const hlp = new THREE.AxesHelper(3);

const geo = new THREE.SphereGeometry(2, 16, 16);

const cnt = geo.getAttribute('position').count;
const clr = [];
for (let i = 0; i < cnt; i++) 
clr.push(...hsvRgb([Math.random(), 1, 1]).map(e => e * 255));

geo.setAttribute('color', new THREE.BufferAttribute(new Uint8Array(clr), 3, true));

const sphere = new THREE.Mesh(
  geo,
  new THREE.MeshBasicMaterial({
    color: 0xffffff,
    vertexColors: true,
  }),
);

scene.background = new THREE.Color(0x002200);
scene.add(hlp).add(sphere);

camera.position.set(5, 3, 5);
camera.lookAt(0, 0, 0);

const render = () => {
  sphere.rotation.x += 0.007;
  sphere.rotation.y += 0.003;
  sphere.rotation.y += 0.001;
  renderer.render(scene, camera);
};

const state = {
  play: true
};

const maybeRender = () => {
  if (!state.play) render()
};

const framerate = 60;
const fpsint = 1000 / framerate;
let elapsed, now, then;

let tid = 0;
const animate = newtime => {

  if (!state.play) return;
  requestAnimationFrame(animate);

  if (!newtime) then = newtime = window.performance.now();

  now = newtime;
  elapsed = now - then;

  if (!fpsint || elapsed > fpsint) {

    then = now - (elapsed % fpsint);

    render();
  }
};

CONTROLS.create({
  cont: renderer.domElement,
  cam: camera,
  type: 'Orbital',
  overlay: true,
  lookAt: [0, 0, 0],
  callback: maybeRender
});

animate();