You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					199 lines
				
				5.6 KiB
			
		
		
			
		
	
	
					199 lines
				
				5.6 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								<!-- 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 - Copy</title>
							 | 
						||
| 
								 | 
							
								    <style>
							 | 
						||
| 
								 | 
							
								    canvas {
							 | 
						||
| 
								 | 
							
								      width: 100%;
							 | 
						||
| 
								 | 
							
								      height: 100%;
							 | 
						||
| 
								 | 
							
								      display: block;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    *[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>
							 | 
						||
| 
								 | 
							
								    <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>
							 | 
						||
| 
								 | 
							
								<!-- Import maps polyfill -->
							 | 
						||
| 
								 | 
							
								<!-- Remove this when import maps will be widely supported -->
							 | 
						||
| 
								 | 
							
								<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<script type="importmap">
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  "imports": {
							 | 
						||
| 
								 | 
							
								    "three": "../../build/three.module.js",
							 | 
						||
| 
								 | 
							
								    "three/addons/": "../../examples/jsm/"
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								</script>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<script type="module">
							 | 
						||
| 
								 | 
							
								import * as THREE from 'three';
							 | 
						||
| 
								 | 
							
								import {TrackballControls} from 'three/addons/controls/TrackballControls.js';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function main() {
							 | 
						||
| 
								 | 
							
								  const canvas = document.createElement('canvas');
							 | 
						||
| 
								 | 
							
								  const renderer = new THREE.WebGLRenderer({canvas, alpha: true});
							 | 
						||
| 
								 | 
							
								  renderer.setScissorTest(true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const sceneElements = [];
							 | 
						||
| 
								 | 
							
								  function addScene(elem, fn) {
							 | 
						||
| 
								 | 
							
								    const ctx = document.createElement('canvas').getContext('2d');
							 | 
						||
| 
								 | 
							
								    elem.appendChild(ctx.canvas);
							 | 
						||
| 
								 | 
							
								    sceneElements.push({elem, ctx, fn});
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function makeScene(elem) {
							 | 
						||
| 
								 | 
							
								    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);
							 | 
						||
| 
								 | 
							
								    scene.add(camera);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const controls = new TrackballControls(camera, elem);
							 | 
						||
| 
								 | 
							
								    controls.noZoom = true;
							 | 
						||
| 
								 | 
							
								    controls.noPan = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      const color = 0xFFFFFF;
							 | 
						||
| 
								 | 
							
								      const intensity = 1;
							 | 
						||
| 
								 | 
							
								      const light = new THREE.DirectionalLight(color, intensity);
							 | 
						||
| 
								 | 
							
								      light.position.set(-1, 2, 4);
							 | 
						||
| 
								 | 
							
								      camera.add(light);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return {scene, camera, controls};
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const sceneInitFunctionsByName = {
							 | 
						||
| 
								 | 
							
								    'box': (elem) => {
							 | 
						||
| 
								 | 
							
								      const {scene, camera, controls} = makeScene(elem);
							 | 
						||
| 
								 | 
							
								      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();
							 | 
						||
| 
								 | 
							
								        controls.handleResize();
							 | 
						||
| 
								 | 
							
								        controls.update();
							 | 
						||
| 
								 | 
							
								        renderer.render(scene, camera);
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    'pyramid': (elem) => {
							 | 
						||
| 
								 | 
							
								      const {scene, camera, controls} = makeScene(elem);
							 | 
						||
| 
								 | 
							
								      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();
							 | 
						||
| 
								 | 
							
								        controls.handleResize();
							 | 
						||
| 
								 | 
							
								        controls.update();
							 | 
						||
| 
								 | 
							
								        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 render(time) {
							 | 
						||
| 
								 | 
							
								    time *= 0.001;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (const {elem, fn, ctx} of sceneElements) {
							 | 
						||
| 
								 | 
							
								      // get the viewport relative position of this element
							 | 
						||
| 
								 | 
							
								      const rect = elem.getBoundingClientRect();
							 | 
						||
| 
								 | 
							
								      const {left, right, top, bottom, width, height} = rect;
							 | 
						||
| 
								 | 
							
								      const rendererCanvas = renderer.domElement;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      const isOffscreen =
							 | 
						||
| 
								 | 
							
								          bottom < 0 ||
							 | 
						||
| 
								 | 
							
								          top > window.innerHeight ||
							 | 
						||
| 
								 | 
							
								          right < 0 ||
							 | 
						||
| 
								 | 
							
								          left > window.innerWidth;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (!isOffscreen) {
							 | 
						||
| 
								 | 
							
								        // make sure the renderer's canvas is big enough
							 | 
						||
| 
								 | 
							
								        if (rendererCanvas.width < width || rendererCanvas.height < height) {
							 | 
						||
| 
								 | 
							
								          renderer.setSize(width, height, false);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // make sure the canvas for this area is the same size as the area
							 | 
						||
| 
								 | 
							
								        if (ctx.canvas.width !== width || ctx.canvas.height !== height) {
							 | 
						||
| 
								 | 
							
								          ctx.canvas.width = width;
							 | 
						||
| 
								 | 
							
								          ctx.canvas.height = height;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        renderer.setScissor(0, 0, width, height);
							 | 
						||
| 
								 | 
							
								        renderer.setViewport(0, 0, width, height);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        fn(time, rect);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // copy the rendered scene to this element's canvas
							 | 
						||
| 
								 | 
							
								        ctx.globalCompositeOperation = 'copy';
							 | 
						||
| 
								 | 
							
								        ctx.drawImage(
							 | 
						||
| 
								 | 
							
								            rendererCanvas,
							 | 
						||
| 
								 | 
							
								            0, rendererCanvas.height - height, width, height,  // src rect
							 | 
						||
| 
								 | 
							
								            0, 0, width, height);                              // dst rect
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    requestAnimationFrame(render);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  requestAnimationFrame(render);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								main();
							 | 
						||
| 
								 | 
							
								</script>
							 | 
						||
| 
								 | 
							
								</html>
							 | 
						||
| 
								 | 
							
								
							 |