Threejs canvas size based on container

three js responsive canvas
threejs material
three.js examples
resize threejs canvas
three js resize object
three js dynamic size
threejs resize on window resize
three js mesh

How can I calculate canvas size based on its container? To avoid scrolling.

If I set the size based on window the canvas is too big.


Well,that's not difficult.Set your render's size will work.

container = document.getElementById('container');
renderer.setSize($(container).width(), $(container).height());
container.appendChild(renderer.domElement);

Three.js Responsive Design, Next we tell the id=c element to be 100% the size of its container which in this case In three.js we can set the canvas's drawingbuffer size by calling renderer. Note that if you want to use three.js to draw into the canvas you're better off using a RenderTarget which is covered in this article.. A common use case for canvas textures is to provide text in a scene.


Arguably the best way to resize three.js use to code it so it just accepts whatever size the canvas is as set by CSS. That way, no matter how you use the canvas your code will work, no need to change it for different situations.

First off when setting the initial aspect ratio there's no reason to set it because we're going to set it in response to the size of the canvas being different so it's just a waste of code to set it twice

// There's no reason to set the aspect here because we're going
// to set it every frame anyway so we'll set it to 2 since 2
// is the the aspect for the canvas default size (300w/150h = 2)
const camera = new THREE.PerspectiveCamera(70, 2, 1, 1000);

Then we need some code that will resize the canvas to match its display size

function resizeCanvasToDisplaySize() {
  const canvas = renderer.domElement;
  // look up the size the canvas is being displayed
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;

  // adjust displayBuffer size to match
  if (canvas.width !== width || canvas.height !== height) {
    // you must pass false here or three.js sadly fights the browser
    renderer.setSize(width, height, false);
    camera.aspect = width / height;
    camera.updateProjectionMatrix();

    // update any render target sizes here
  }
}

Call this in your render loop before rendering

function animate(time) {
  time *= 0.001;  // seconds

  resizeCanvasToDisplaySize();

  mesh.rotation.x = time * 0.5;
  mesh.rotation.y = time * 1;

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

requestAnimationFrame(animate);

Here's 3 examples, the only difference between the 3 examples is the CSS and whether we make the canvas or three.js makes the canvas

Example 1: fullscreen, We make the canvas

"use strict";

const  renderer = new THREE.WebGLRenderer({canvas: document.querySelector("canvas")});

// There's no reason to set the aspect here because we're going
// to set it every frame anyway so we'll set it to 2 since 2
// is the the aspect for the canvas default size (300w/150h = 2)
const  camera = new THREE.PerspectiveCamera(70, 2, 1, 1000);
camera.position.z = 400;

const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshPhongMaterial({
  color: 0x555555,
  specular: 0xffffff,
  shininess: 50,
  shading: THREE.SmoothShading
});

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

const light1 = new THREE.PointLight(0xff80C0, 2, 0);
light1.position.set(200, 100, 300);
scene.add(light1);

function resizeCanvasToDisplaySize() {
  const canvas = renderer.domElement;
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;
  if (canvas.width !== width ||canvas.height !== height) {
    // you must pass false here or three.js sadly fights the browser
    renderer.setSize(width, height, false);
    camera.aspect = width / height;
    camera.updateProjectionMatrix();

    // set render target sizes here
  }
}

function animate(time) {
  time *= 0.001;  // seconds

  resizeCanvasToDisplaySize();

  mesh.rotation.x = time * 0.5;
  mesh.rotation.y = time * 1;

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

requestAnimationFrame(animate);
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<canvas></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>

How to resize canvas without resizing renderer or , I'd like to find an efficient way to resize the canvas to match the size of the browser window, without resizing or scaling the contents of the canvas – ie. if I'm � I have ThreeJs rendering into an existing canvas element, which is inside the main page partial. However, when ThreeJs actually runs, it moves the canvas element to the very end (directly above the body closing tag). Because ThreeJs is moving the existing canvas element out of place, the Angular routing isn't working correctly.


I think that the best way to resize the canvas is not the accepted answer above. Every animationframe @gman will run the function resizeCanvasToDisplaySize, doing multiple calculations.

I think that the best way is to create a window event lister 'resize' and a boolean saying wether the user resized or not. In the animation frame you can check wether the user resized. If he resized, you can resize the canvas in the animationframe.

let resized = false

// resize event listener
window.addEventListener('resize', function() {
    resized = true
})

function animate(time) {
    time *= 0.001

    if (resized) resize()

    // rotate the cube
    cube.rotation.x += 0.01
    cube.rotation.y += 0.01

    // render the view
    renderer.render(scene, camera)

    // animate
    requestAnimationFrame(animate)
}

function resize() {
    resized = false

    // update the size
    renderer.setSize(window.innerWidth, window.innerHeight)

    // update the camera
    const canvas = renderer.domElement
    camera.aspect = canvas.clientWidth/canvas.clientHeight
    camera.updateProjectionMatrix()
}

Trouble restricting Three.js scene to a div - Questions, <script> //Set Global Variables var specs; var width, height, length, bwidth, bheight, blength, groundy; Threejs canvas size based on container. Using canvas as ThreeJS texture. GitHub Gist: instantly share code, notes, and snippets.


Maybe I'm missing the point here - but why do the existing suggestions involve resizing the canvas from within the animation loop?

You'd want your animation loop to do as little as possible, as it will ideally be repeated 30+ times a second, and should be optimized to run as efficiently as possible - affording the maximum fps to the slowest system running it.

I think there's no harm in calling the resize function from within the resize event listener - much like Meindert Stijfhals suggested below.

Something like this:

var container = renderer.domElement.parentElement;
container.addEventListener('resize', onContainerResize);

function onContainerResize() {
    var box = container.getBoundingClientRect();
    renderer.setSize(box.width, box.height);

    camera.aspect = box.width/box.height
    camera.updateProjectionMatrix()
    // optional animate/renderloop call put here for render-on-changes
}

If you have some kind of render-only-on-changes set up, you can call the render function at the end of the resize function. Otherwise the next time the render loop does fire it should just render with the new settings.

Responsive Container - Questions, I tried window resize, but that didn't work. CanvasRenderer(); var container = document.getElementById("canvas"); var w = container. ( particle ); // and to the array of particles. particles.push(particle); } } // there isn't a built in� [page:Texture] → [name] Creates a texture from a canvas element. This is almost the same as the base [page:Texture Texture] class, except that it sets [page:Texture.needsUpdate needsUpdate] to *true* immediately.


Of course the answer provided by @gman is the full-fledged answer. However, to recap the possible scenarios, one has to assume the two possibilities, which is the reason why the answers differ drastically.

The first possibility is when the container is the global(head) object: window, or maybe <body> or <frameset>, in which case, the most convenient method would be using window.addEventListener('resize', onResize()) { ... }.

The second possibility, is the one which has been originally asked: when the container of the Three.js WebGL output should be responsive. In that case, whether the container is canvas, a section or a div, the best way to handle the resizing is to target the container in DOM, and use the renderer.setsize() method by passing it the container's clientWidth and clientHeight, and then calling onResize() function in the render loop function, which its complete implementation is aforementioned by @gman. In this particular case, there is no need to use addEventListener.

Three.js By CSS, But if instead you based the size of the canvas off its clientWidth and clientHeight then it would just always work. The user can make container and set it's CSS to� Three.js: Resize and Canvas. 2015-04-19 . As promised, resizing and attaching to a custom canvas in Three.js.. We will start with code from the getting started post and simply add event handlers for resizing the window:


Three.js: Resize and Canvas, innerWidth / window.innerHeight; camera.updateProjectionMatrix(); });. Calling the setSize function on the renderer will resize the underlying� ThreeJS renders to a <canvas> element. You can't render directly to a <div>. What you want is to wrap your threejs <canvas> in your jumbotron <;div&gt;, then write a


What is a good way to put ThreeJS into a Div?, What you want is to wrap your threejs <canvas> in your jumbotron <div>, then write a script to dynamically resize it to fill the jumbotron (or just specify a fixed width container.appendChild( renderer.domElement );. code aussi in jsfiddle : Edit Why are there no pure OOP-based JavaScript frameworks implemented? Three.js WebGL Canvas Texture Text Example. GitHub Gist: instantly share code, notes, and snippets.


CSS based size by default? � Issue #4903 � mrdoob/three.js � GitHub, But if instead you based the size of the canvas off its clientWidth and clientHeight then it would just always work. The user can make container� container is not a <canvas> element. containter.style.width and container.style.height are strings such as "200px" on them, and setSize expect just numbers such as 200. Change these lines to this, and you should be able to go from there: