Trouble restricting Three.js scene to a div

I have successfully created a scene in a full window. Now I need to restrict it to a div in a web page. Here is the successful code for the full page:

	<script>

        //Set Global Variables
        var specs;
        var width, height, length, bwidth, bheight, blength, groundy;
        bwidth = 20*20; bheight = 10*20, blength = 40*20;
        groundy = bheight/2

        // Our Javascript will go here.
        // Set Scene Camera and Renderer

        var scene = new THREE.Scene();
        scene.background = new THREE.Color( 0xcce0ff );
		scene.fog = new THREE.Fog( 0xcce0ff, 1500, 2000 );
        var camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 2000 );
        var controls = new THREE.OrbitControls( camera );

        var renderer = new THREE.WebGLRenderer( {antialias: true } );
        renderer.setPixelRatio( window.devicePixelRatio );
        renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( renderer.domElement );

        camera.position.set(bwidth * -1.25, bheight + 0, blength * 1.25);

        // change aspect and view port size on widow resize

        window.addEventListener( 'resize', onWindowResize, false );

        function onWindowResize(){
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize( window.innerWidth, window.innerHeight );

        }

        // Loader
        var loader = new THREE.TextureLoader();
        
        // lights
			var light, materials;
			scene.add( new THREE.AmbientLight( 0x666666 ) );
			light = new THREE.DirectionalLight( 0xdfebff, 1 );
			light.position.set( 50, 200, 100 );
			light.position.multiplyScalar( 1.3 );
			light.castShadow = true;
			light.shadow.mapSize.width = 1024;
			light.shadow.mapSize.height = 1024;
			var d = 300;
			light.shadow.camera.left = - d;
			light.shadow.camera.right = d;
			light.shadow.camera.top = d;
			light.shadow.camera.bottom = - d;
			light.shadow.camera.far = 1000;
            scene.add( light );
            
        // ground
			var groundTexture = loader.load( 'assets/Grass_Texture.jpg' );
			groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
			groundTexture.repeat.set( 50, 50 );
			groundTexture.anisotropy = 16;
			var groundMaterial = new THREE.MeshLambertMaterial( { map: groundTexture } );
			var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 20000, 20000 ), groundMaterial );
			mesh.position.y = - groundy;
			mesh.rotation.x = - Math.PI / 2;
			mesh.receiveShadow = true;
            scene.add( mesh );
            

        //add geometry

        var geometry = new THREE.BoxGeometry( bwidth, bheight, blength );
        var material = new THREE.MeshLambertMaterial( { color: 0xdddddd } );
        /*var wallMaterial =
        [
            new MeshLambertMaterial ({ map: new THREE.TextureLoader( 'file.png' ) load(), side: THREE.Doubleside } )


        ] */
        var cube = new THREE.Mesh( geometry, material );
        
        scene.add( cube );

    

        //render scene in animate loop

        function animate() {
        requestAnimationFrame( animate );
        renderer.render( scene, camera );
        }
    animate();
	</script>

I have copy/pasted the main script area from the code above into a model.js file in my js folder and linked to it in the new web page in the head section like so:

<script src="js/model.js"></script>

I have created a canvas div in my html inside the div where the scene should appear:

<div id=model>
    <div id="canvas"></div>
</div><!--model-->

I get nothing inside the div. I’m sure it’s something simple but I’m stumped. Appreciate any help.

Here’s the model.js code:

  //Set Global Variables
  var specs;
  var width, height, length, bwidth, bheight, blength, groundy;
  bwidth = 20*20; bheight = 10*20, blength = 40*20;
  groundy = bheight/2

// Set Scene Camera and Renderer

var scene = new THREE.Scene();
scene.background = new THREE.Color( 0xcce0ff );
scene.fog = new THREE.Fog( 0xcce0ff, 1500, 2000 );

var controls = new THREE.OrbitControls( camera );

var renderer = new THREE.WebGLRenderer( { antialias: true } );
var container = document.getElementById('canvas');
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( container.innerWidth, container.innerHeight );
container.appendChild( renderer.domElement );

var camera = new THREE.PerspectiveCamera( 75, container.innerWidth / container.innerHeight, 0.1, 2000 );
camera.position.set(bwidth * -1.25, bheight + 0, blength * 1.25);

// change aspect and view port size on widow resize

//window.addEventListener( 'resize', onWindowResize, false );

function onWindowResize(){
camera.aspect = container.innerWidth / container.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( container.innerWidth, container.innerHeight );

}

// Loader
var loader = new THREE.TextureLoader();
        
// lights
var light, materials;
scene.add( new THREE.AmbientLight( 0x666666 ) );
light = new THREE.DirectionalLight( 0xdfebff, 1 );
light.position.set( 50, 200, 100 );
light.position.multiplyScalar( 1.3 );
light.castShadow = true;
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
var d = 300;
light.shadow.camera.left = - d;
light.shadow.camera.right = d;
light.shadow.camera.top = d;
light.shadow.camera.bottom = - d;
light.shadow.camera.far = 1000;
scene.add( light );
            
// ground
var groundTexture = loader.load( 'assets/Grass_Texture.jpg' );
groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
groundTexture.repeat.set( 50, 50 );
groundTexture.anisotropy = 16;
var groundMaterial = new THREE.MeshLambertMaterial( { map: groundTexture } );
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), groundMaterial );
mesh.position.y = - groundy;
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
scene.add( mesh );
            

//add geometry

var geometry = new THREE.BoxGeometry( bwidth, bheight, blength );
var material = new THREE.MeshLambertMaterial( { color: 0xdddddd } );
/*var wallMaterial =
[
     new MeshLambertMaterial ({ map: new THREE.TextureLoader( 'file.png' ) load(), side: THREE.Doubleside } )


] */
var cube = new THREE.Mesh( geometry, material );
        
scene.add( cube );

    

//render scene in animate loop

function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}

animate();

Thanks in advance for any help.

Try it like that:

var drawingSurface = document.getElementById( 'canvas' );
var renderer = new THREE.WebGLRenderer( { antialias: true, canvas: drawingSurface } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( 400, 400 ); // some width and height values

// innerWidth and innerHeight are properties of window so this code does not work
// renderer.setSize( container.innerWidth, container.innerHeight );

// don't do this. the canvas element is already attached to the DOM
// container.appendChild( renderer.domElement ); 

Your markup should look like this:

<div id="container">
    <div id="canvas"></div>
</div>

Thank you Mugen87. Very helpful.

If I want the setSize of the renderer to by dynamic based on the size of the canvas how would I refer to it? The scene needs to resize with the div.

Your suggestion:
renderer.setSize( 400, 400 );

Would I use:
renderer.setSize(drawingSurface.width, drawingSurface.height);

Also, in my code “model” is a div for my html template and the “canvas” div is where I want the scene to render. So I wouldn’t need to change that would I? I probably should not have posted it. Sorry.

 <div id="model">
      <div id="canvas"></div>
 </div>

Take a look at the 4th example from here:

1 Like

Sry, there is a mistake in my markup. I meant it like that.

<div id="container">
    <canvas id="canvas"></canvas>
</div>

Besides, i’ve realized that i have misread your code. It was everything fine except of renderer.setSize( container.innerWidth, container.innerHeight );. Just have a look at the post of @prisoner849

Hello, is there any working code, that I can copy and paste to see it actually working. I’m new in this and I have trouble understanding how it works. I see pieces here, pieces there but not full working code that I can use. Thanks for your help.
The idea is to put my full working animation of the cube, in a little part of a

inside my web-page
1 Like