JSFiddle - React, Tailwind, and code Playground
by tfoller
HTML
<canvas id="main_canvas" width="500" height="300"></canvas>
<div><button id="play">play</button></div>
CSS
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background: #112233;
width: 100vw;
height: 100vh;
}
#main_canvas {
display: block;
box-sizing: content-box;
border: solid 1px grey;
margin: 10px;
}
#play, #test {
padding: 3px 5px;
cursor: pointer;
margin-left: 10px;
}
JavaScript
import * as THREE from 'https://unpkg.com/three/build/three.module.js'
import { hslRgb } from 'https://alikim.com/jsm/glsl.module.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, 1000];
const camera = new THREE.PerspectiveCamera(45, w / h, near, far);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0.05, 0, 0.05);
const light = {};
light.dir = new THREE.DirectionalLight(0xffffff, 0.8);
light.dir.position.set(1, 1, 1);
Object.keys(light).forEach(k => { scene.add(light[k]) });
const PI2 = 2 * Math.PI;
const geo = new THREE.BoxGeometry(1, 1, 1);
const mat = new THREE.MeshLambertMaterial();
const cube = [];
for(let i = 0; i < 100; i++) {
cube[i] = new THREE.Mesh(geo, mat.clone());
cube[i].material.color = new THREE.Color(...hslRgb([Math.random(), 0.9, 0.5]));
const sz = 20 + 50 * Math.random();
cube[i].scale.set(sz, sz, sz);
const x = 200 * 2 * (Math.random() - 0.5);
const y = 100 * 2 * (Math.random() - 0.5);
const z = 100 * 2 * (Math.random() - 0.5);
cube[i].position.set(x, y, -0.5 * (near + far) + z);
cube[i].rotation.set(PI2 * Math.random(), PI2 * Math.random(), PI2 * Math.random());
scene.add(cube[i]);
}
// render the same scene on texture
function objectSelector(renderer, scene, camera, obj, light, w, h) {
const nm = ['renderer', 'scene', 'camera', 'obj', 'light', 'w', 'h'];
Array.from(arguments).forEach((v, i) => { this[nm[i]] = v });
const opt = {
magFilter: THREE.NearestFilter,
minFilter: THREE.NearestFilter,
};
this.outputRT = new THREE.WebGLRenderTarget(1, 1, opt);
}
objectSelector.prototype.render = function (x, y) {
const bg = this.scene.background;
this.scene.background = null;
const amb =...