UNPKG

@adhiban/three-mesh-ui

Version:

a library on top of three.js to help in creating 3D user interfaces, with minor changes ;)

243 lines (175 loc) 5.93 kB
import * as THREE from 'three'; import { VRButton } from 'three/examples/jsm/webxr/VRButton.js'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; import { BoxLineGeometry } from 'three/examples/jsm/geometries/BoxLineGeometry.js'; import ThreeMeshUI from '../src/three-mesh-ui.js'; import FontJSON from './assets/Roboto-msdf.json'; import FontImage from './assets/Roboto-msdf.png'; import { Object3D } from 'three'; const WIDTH = window.innerWidth; const HEIGHT = window.innerHeight; let scene, camera, renderer, controls; window.addEventListener( 'load', init ); window.addEventListener( 'resize', onWindowResize ); // function init() { scene = new THREE.Scene(); scene.background = new THREE.Color( 0x505050 ); camera = new THREE.PerspectiveCamera( 60, WIDTH / HEIGHT, 0.1, 100 ); renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( WIDTH, HEIGHT ); renderer.xr.enabled = true; document.body.appendChild( VRButton.createButton( renderer ) ); document.body.appendChild( renderer.domElement ); controls = new OrbitControls( camera, renderer.domElement ); camera.position.set( 0, 1.6, 0.75 ); controls.target = new THREE.Vector3( 0, 1.5, -1.8 ); controls.update(); // ROOM const room = new THREE.LineSegments( new BoxLineGeometry( 6, 6, 6, 10, 10, 10 ).translate( 0, 3, 0 ), new THREE.LineBasicMaterial( { color: 0x808080 } ) ); scene.add( room ); // TEXT PANEL const justifications = [ 'start', // 'start' or ThreeMeshUI.JustifyContent.START, 'end', // 'end' or ThreeMeshUI.JustifyContent.END, 'center', // 'center' or ThreeMeshUI.JustifyContent.CENTER, 'space-around', // 'space-around' or ThreeMeshUI.JustifyContent.SPACE_AROUND, 'space-between', // 'space-between' or ThreeMeshUI.JustifyContent.SPACE_BETWEEN, 'space-evenly' // 'space-evenly' or ThreeMeshUI.JustifyContent.SPACE_EVENLY ]; for ( let i = 0; i < justifications.length; i++ ) { const contentDirection = justifications[ i ]; makeTextPanelColumn( i, contentDirection ); makeTextPanelRow( i, contentDirection ); } // renderer.setAnimationLoop( loop ); } // function makeTextPanelColumn( index, contentDirection ) { const group = new Object3D(); const title = new ThreeMeshUI.Block( { width: 0.75, height: 0.15, padding: 0.05, backgroundColor: new THREE.Color( 0xff9900 ), justifyContent: 'center', fontFamily: FontJSON, fontTexture: FontImage } ); const titleText = new ThreeMeshUI.Text( { content: contentDirection, fontSize: 0.075 } ); title.add( titleText ); title.position.set( 0, 0.6, 0 ); group.add( title ); const container = new ThreeMeshUI.Block( { width: 0.7, height: 1, padding: 0.05, justifyContent: contentDirection, alignItems: 'center', contentDirection: 'column', fontFamily: FontJSON, fontTexture: FontImage } ); const letters = 'ABC'; const colors = [ 0xff9900, 0xff0099, 0x00ff99, 0x99ff00, 0x9900ff, 0x0099ff ]; for ( let i = 0; i < letters.length; i ++ ) { const blockText = new ThreeMeshUI.Block( { width: 0.125, height: 0.125, margin: 0.01, borderRadius: 0.02, backgroundColor: new THREE.Color(colors[i]), justifyContent: 'center', alignItems: 'center', offset:0.001 } ); const text = new ThreeMeshUI.Text( { content: letters[ i ] } ); blockText.add( text ); container.add( blockText ); } // container.rotation.x = -0.25; group.add( container ); group.position.set( -0.4 * 5 + (index%6 ) * 0.8 , 2.15 + Math.floor( index / 6 ) * -1.25, -2 ); scene.add( group ); } function makeTextPanelRow( index, contentDirection ) { const group = new Object3D(); const title = new ThreeMeshUI.Block( { width: 1.4, height: 0.15, padding: 0.05, backgroundColor: new THREE.Color( 0xff9900 ), justifyContent: 'center', textAlign: 'left', fontFamily: FontJSON, fontTexture: FontImage } ); const titleText = new ThreeMeshUI.Text( { content: `.set({justifyContent: "${contentDirection}"})`, fontSize: 0.075 } ); title.add( titleText ); title.position.set( -2.3, 0, 0 ); group.add( title ); const container = new ThreeMeshUI.Block( { width: 3, height: 0.2, padding: 0.05, justifyContent: contentDirection, alignItems: 'center', contentDirection: 'row', fontFamily: FontJSON, fontTexture: FontImage } ); const letters = 'ABC'; const colors = [ 0xff9900, 0xff0099, 0x00ff99, 0x99ff00, 0x9900ff, 0x0099ff ]; for ( let i = 0; i < letters.length; i ++ ) { const blockText = new ThreeMeshUI.Block( { width: 0.125, height: 0.125, margin: 0.01, borderRadius: 0.02, backgroundColor: new THREE.Color(colors[i]), justifyContent: 'center', alignItems: 'center', offset:0.001 } ); const text = new ThreeMeshUI.Text( { content: letters[ i ] } ); blockText.add( text ); container.add( blockText ); } // container.rotation.x = -0.25; group.add( container ); // group.position.set( -0.4 * 5 + (index%6 ) * 0.8 , 2.15 + Math.floor( index / 6 ) * -1.25, -2 ); group.position.set( 0.7 ,1.35 + (index%6 ) * -0.225, -2 ); scene.add( group ); } // handles resizing the renderer when the viewport is resized function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } // function loop() { // Don't forget, ThreeMeshUI must be updated manually. // This has been introduced in version 3.0.0 in order // to improve performance ThreeMeshUI.update(); controls.update(); renderer.render( scene, camera ); }