| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 | <!-- Licensed under a BSD license. See license.html for license --><!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">    <title>Three.js - Multiple Scenes - CSS Selector</title>    <style>    #c {      position: absolute;      left: 0;      top: 0;      width: 100%;      height: 100%;      display: block;      z-index: -1;    }    *[data-diagram] {      display: inline-block;      width: 5em;      height: 3em;    }    .left {      float: left;      margin-right: .25em;    }    .right {      float: right;      margin-left: .25em;    }    p {      margin: 1em auto;      max-width: 500px;      font-size: xx-large;    }    </style>  </head>  <body>    <canvas id="c"></canvas>    <p>      <span data-diagram="box" class="left"></span>      I love boxes. Presents come in boxes.      When I find a new box I'm always excited to find out what's inside.    </p>    <p>      <span data-diagram="pyramid" class="right"></span>      When I was a kid I dreamed of going on an expedition inside a pyramid      and finding a undiscovered tomb full of mummies and treasure.    </p>  </body><script type="importmap">{  "imports": {    "three": "../../build/three.module.js"  }}</script><script type="module">import * as THREE from 'three';function main() {	const canvas = document.querySelector( '#c' );	const renderer = new THREE.WebGLRenderer( { antialias: true, canvas, alpha: true } );	const sceneElements = [];	function addScene( elem, fn ) {		sceneElements.push( { elem, fn } );	}	function makeScene() {		const scene = new THREE.Scene();		const fov = 45;		const aspect = 2; // the canvas default		const near = 0.1;		const far = 5;		const camera = new THREE.PerspectiveCamera( fov, aspect, near, far );		camera.position.set( 0, 1, 2 );		camera.lookAt( 0, 0, 0 );		{			const color = 0xFFFFFF;			const intensity = 3;			const light = new THREE.DirectionalLight( color, intensity );			light.position.set( - 1, 2, 4 );			scene.add( light );		}		return { scene, camera };	}	const sceneInitFunctionsByName = {		'box': () => {			const { scene, camera } = makeScene();			const geometry = new THREE.BoxGeometry( 1, 1, 1 );			const material = new THREE.MeshPhongMaterial( { color: 'red' } );			const mesh = new THREE.Mesh( geometry, material );			scene.add( mesh );			return ( time, rect ) => {				mesh.rotation.y = time * .1;				camera.aspect = rect.width / rect.height;				camera.updateProjectionMatrix();				renderer.render( scene, camera );			};		},		'pyramid': () => {			const { scene, camera } = makeScene();			const radius = .8;			const widthSegments = 4;			const heightSegments = 2;			const geometry = new THREE.SphereGeometry( radius, widthSegments, heightSegments );			const material = new THREE.MeshPhongMaterial( {				color: 'blue',				flatShading: true,			} );			const mesh = new THREE.Mesh( geometry, material );			scene.add( mesh );			return ( time, rect ) => {				mesh.rotation.y = time * .1;				camera.aspect = rect.width / rect.height;				camera.updateProjectionMatrix();				renderer.render( scene, camera );			};		},	};	document.querySelectorAll( '[data-diagram]' ).forEach( ( elem ) => {		const sceneName = elem.dataset.diagram;		const sceneInitFunction = sceneInitFunctionsByName[ sceneName ];		const sceneRenderFunction = sceneInitFunction( elem );		addScene( elem, sceneRenderFunction );	} );	function resizeRendererToDisplaySize( renderer ) {		const canvas = renderer.domElement;		const width = canvas.clientWidth;		const height = canvas.clientHeight;		const needResize = canvas.width !== width || canvas.height !== height;		if ( needResize ) {			renderer.setSize( width, height, false );		}		return needResize;	}	const clearColor = new THREE.Color( '#000' );	function render( time ) {		time *= 0.001;		resizeRendererToDisplaySize( renderer );		renderer.setScissorTest( false );		renderer.setClearColor( clearColor, 0 );		renderer.clear( true, true );		renderer.setScissorTest( true );		const transform = `translateY(${window.scrollY}px)`;		renderer.domElement.style.transform = transform;		for ( const { elem, fn } of sceneElements ) {			// get the viewport relative position of this element			const rect = elem.getBoundingClientRect();			const { left, right, top, bottom, width, height } = rect;			const isOffscreen =          bottom < 0 ||          top > renderer.domElement.clientHeight ||          right < 0 ||          left > renderer.domElement.clientWidth;			if ( ! isOffscreen ) {				const positiveYUpBottom = renderer.domElement.clientHeight - bottom;				renderer.setScissor( left, positiveYUpBottom, width, height );				renderer.setViewport( left, positiveYUpBottom, width, height );				fn( time, rect );			}		}		requestAnimationFrame( render );	}	requestAnimationFrame( render );}main();</script></html>
 |