html5-canvasthree.js

Putting three.js animation inside of div


This is three.js animation code example:

<script defer="defer">
  var angularSpeed = 0.2; 
  var lastTime = 0;
  function animate(){
    var time = (new Date()).getTime();
    var timeDiff = time - lastTime;
    var angleChange = angularSpeed * timeDiff * 2 * Math.PI / 1000;
    plane.rotation.z += angleChange;
    lastTime = time;
    renderer.render(scene, camera);
    requestAnimationFrame(function(){
        animate();
    });
  }
  var renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
  var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  camera.position.y = -450;
  camera.position.z = 400;
  camera.rotation.x = 45 * (Math.PI / 180);
  var scene = new THREE.Scene();
  var plane = new THREE.Mesh(new THREE.PlaneGeometry(300, 300), new THREE.MeshNormalMaterial());
  plane.overdraw = true;
  scene.add(plane);
  animate();
 </script>

I would like to bind this animation code to some specific div via div id. So, animation would be displayed inside of div. That would allow me to easily manipulate animation location with css. I was having in mind something like this:

html:

<canvas id="myCanvas" width="578" height="200"></canvas>

javascript:

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
// do stuff here

But I haven't found a way to do something like this with three.js. As you can see in code example, there is no canvas element that I can refer to. Any ideas?


Solution

  • You can use a pattern like the following:

    <div id="canvas"></div>
    
    #canvas {
        background-color: #000;
        width: 200px;
        height: 200px;
        border: 1px solid black;
        margin: 100px;
        padding: 0px;
        position: static; /* fixed or static */
        top: 100px;
        left: 100px;
    }
    
    const container = document.getElementById( 'canvas' );
    document.body.appendChild( container );
    
    const renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( 200, 200 );
    container.appendChild( renderer.domElement );
    

    Fiddle: https://jsfiddle.net/uf4c0ws9/

    Also see THREE.js Ray Intersect fails by adding div

    three.js r.150