JSFiddle - React, Tailwind, and code Playground

by tfoller

HTML

<canvas id="main_canvas" width="500" height="300"></canvas>

CSS

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

*:focus {
    outline: none;
}

body {
  background: #112233;
  width: 100vw;
  height: 100vh;
}

canvas {
  display: block;
  border: solid 1px grey;
  box-sizing: content-box;
  margin: 10px;
}

JavaScript

import * as THREE from 'https://alikim.com/jsm/three.module.js'

import { OrbitControls } from 'https://alikim.com/jsm/OrbitControls.js'

const get = id => document.getElementById(id);

// 3D

const canvas = get('main_canvas');
const [w, h] = [canvas.width, canvas.height];
const renderer = new THREE.WebGLRenderer({
  antialias: true,
  canvas: canvas,
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(w, h);

const [near, far] = [1, 50];
const mid = -0.5 * (near + far);
const camera = new THREE.PerspectiveCamera(45, w / h, near, far);

const scene = new THREE.Scene();
scene.background = new THREE.Color(0, 0, 0.3);

const cube = new THREE.Mesh(
  new THREE.BoxGeometry(10, 5, 2),
  new THREE.MeshLambertMaterial({ color: 0x008000 }));
cube.position.z = mid;

const axesHelper = new THREE.AxesHelper(15);
axesHelper.position.z = mid;

const controls = new OrbitControls(camera, renderer.domElement);
controls.target.copy(cube.position);

const dirLight = new THREE.DirectionalLight(0xffffff, 0.5);
dirLight.position.subVectors(camera.position, cube.position);

scene.add(axesHelper).add(cube).add(dirLight);

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

const render = () => { 
  cube.rotation.x += 0.01;
  renderer.render(scene, camera); 
};

const state = {pl: true};

const animate = newtime => {
  
  if(!state.pl) return;
  requestAnimationFrame(animate);

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

  now = newtime;
  elapsed = now - then;

  if (!fpsint || elapsed > fpsint) {

    then = now - (elapsed % fpsint);

    dirLight.position.subVectors(camera.position, cube.position);

    render();
  }
};

animate();