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