Three.js Elements with fixed position

by Gregg Tavares

HTML

<canvas id="c"></canvas>

<div id="content">
  <div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - multiple elements - webgl</div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/three.min.js"></script>

<script id="template" type="notjs">
			<div class="scene"></div>
			<div class="description">Scene $</div>
</script>

CSS

* {
  box-sizing: border-box;
  -moz-box-sizing: border-box;
}

body {
  color: #000;
  font-family:Monospace;
  font-size:13px;

  background-color: #fff;
  margin: 0;
}

#info {
  position: absolute;
  top: 0; width: 100%;
  padding: 5px;
  text-align:center;
}

#content {
  position: absolute;
  top: 0; width: 100%;
  z-index: 1;
  padding: 3em 0 0 0;
}

a {
  color: #0080ff;
}

#c {
  position: fixed;
  left: 0;
  width: 100%;
  height: 100%;
}

.list-item {
  display: inline-block;
  margin: 1em;
  padding: 1em;
  box-shadow: 1px 2px 4px 0px rgba(0,0,0,0.25);
}

.list-item .scene {
  width: 200px;
  height: 200px;
}

.list-item .description {
  color: #888;
  font-family: sans-serif;
  font-size: large;
  width: 200px;
  margin-top: 0.5em;
}

JavaScript

var canvas;

var scenes = [], renderer;
var frameCount = 0;

init();
animate();

function init() {

  canvas = document.getElementById( "c" );

  var geometries = [
    new THREE.BoxBufferGeometry( 1, 1, 1 ),
    new THREE.SphereBufferGeometry( 0.5, 12, 8 ),
    new THREE.DodecahedronBufferGeometry( 0.5 ),
    new THREE.CylinderBufferGeometry( 0.5, 0.5, 1, 12 )
  ];

  var template = document.getElementById( "template" ).text;
  var content = document.getElementById( "content" );

  for ( var i =  0; i < 40; i ++ ) {

    var scene = new THREE.Scene();

    // make a list item
    var element = document.createElement( "div" );
    element.className = "list-item";
    element.innerHTML = template.replace( '$', i + 1 );

    // Look up the element that represents the area
    // we want to render the scene
    scene.userData.element = element.querySelector( ".scene" );
    content.appendChild( element );

    var camera = new THREE.PerspectiveCamera( 50, 1, 1, 10 );
    camera.position.z = 2;
    scene.userData.camera = camera;

    // add one random mesh to each scene
    var geometry = geometries[ geometries.length * Math.random() | 0 ];

    var material = new THREE.MeshStandardMaterial( {

      color: new THREE.Color().setHSL( Math.random(), 1, 0.75 ),
      roughness: 0.5,
      metalness: 0,
      flatShading: true

    } );

    scene.add( new THREE.Mesh( geometry, material ) );

    scene.add( new THREE.HemisphereLight( 0xaaaaaa, 0x444444 ) );

    var light = new THREE.DirectionalLight( 0xffffff, 0.5 );
    light.position.set( 1, 1, 1 );
    scene.add( light );

    scenes.push( scene );

  }


  renderer = new THREE.WebGLRenderer( { canvas: canvas, antialias: true } );
  renderer.setClearColor( 0xffffff, 1 );
  renderer.setPixelRatio( window.devicePixelRatio );

}

function updateSize() {

  var width = canvas.clientWidth;
  var height = canvas.clientHeight;

  if ( canvas.width !== width || canvas.height !== height ) {

    renderer.setSize( width,...