JSFiddle - React, Tailwind, and code Playground
by Paul West
CSS
body{
overflow: hidden;
margin: 0;
}
.label {
text-align: center;
width: 20px;
height: 20px;
border: 1px solid white;
border-radius: 10px;
color: #4f8;
font-family: sans-serif;
background: rgba( 0, 0, 0, .6 );
}
JavaScript
import * as THREE from "https://cdn.skypack.dev/three@0.136.0";
import {OrbitControls} from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls.js";
import { CSS2DRenderer, CSS2DObject } from 'https://cdn.skypack.dev/three@0.136.0/examples/jsm/renderers/CSS2DRenderer.js';
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(10, 10, 10);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
var labelRenderer = new CSS2DRenderer();
labelRenderer.setSize( innerWidth, innerHeight );
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0px';
document.body.appendChild( labelRenderer.domElement );
var controls = new OrbitControls(camera, labelRenderer.domElement);
var light = new THREE.DirectionalLight(0xffffff, 1.);
light.position.set(10, 20, 30);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
scene.add(new THREE.GridHelper(10, 10));
var box = new THREE.Mesh(new THREE.BoxBufferGeometry(4, 2, 2), new THREE.MeshLambertMaterial({color: 0x0088ff, wireframe: false}));
scene.add(box);
var pos = new THREE.Vector3(2.1, 0, 0);
var normal = new THREE.Vector3().copy(pos).normalize();
var cNormal = new THREE.Vector3();
var cPos = new THREE.Vector3();
var m4 = new THREE.Matrix4();
var div = document.createElement( 'div' );
div.className = 'label';
div.textContent = '1';
div.style.marginTop = '-1em';
var label = new CSS2DObject( div );
label.position.copy(pos);
box.add( label );
renderer.setAnimationLoop(()=>{
cNormal.copy(normal).applyMatrix3(box.normalMatrix);
cPos.copy(pos).applyMatrix4(m4.multiplyMatrices(camera.matrixWorldInverse, box.matrixWorld));
let d = cPos.negate().dot(cNormal);
div.style.visibility = d < 0 ? "hidden" : "visible";
//div.style.opacity = d < 0 ? 0.25 : 1;
...