Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make responsive canvas with a 3d model using three.js?

I'm making a web page where I created a canvas to show a 3d object (a cube) using threejs. I added this canvas into a div (as shown in several documentations).
The prolem is that when I change the size of the screen to small the canvas and the object become small, that works well, but when the screen changes to large the canvas extends and occupies the whole page.
What I am looking for is to maintain the dimensions that assign both width and height
Thanks in advance.

<!DOCTYPE html>
<html>
	<head>
		<meta charset= UFT-8>		
		<title>tema</title>
		<style type="text/css">
			
			div{
				width: 50%;
				margin-left: 20px;
				margin-right: 100px;
				margin-top: 20px;
				margin-bottom: 20px;
				border: 2px solid blue;
}
		</style>
	</head>
	<body>
		<section class="menu">
			<div id="container"></div>
			
			<script src="https://ajax.googleapis.com/ajax/libs/threejs/r76/three.min.js" ></script>
		
			<script type="text/javascript">
				function init(){

			width = 500;
			height = 500;	

			scene = new THREE.Scene();

			camera = new THREE.PerspectiveCamera( 75, width/height, 0.1, 1000 );

			camera.position.z = 500;

			renderer = new THREE.WebGLRenderer();
			renderer.setSize( width, height);
			renderer.setClearColor( 0xffffff);
			renderer.setPixelRatio( window.devicePixelRatio );
			

			contenedor = document.getElementById('container');

			contenedor.appendChild(renderer.domElement);

			

			var obj = new THREE.CubeGeometry(100,100,100);
			var material = new THREE.MeshNormalMaterial();

			
			body = new THREE.Mesh(obj,material);
			

			scene.add( body );



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

			}

			function onWindowResize() {
				
				camera.aspect = window.innerWidth/ window.innerHeight;

				camera.updateProjectionMatrix();
				renderer.setSize( window.innerWidth, window.innerHeight );

			}


			var animate = function () {

				requestAnimationFrame( animate );

		
				body.rotation.x+=0.01;
				body.rotation.y+=0.01;
					


				renderer.render(scene, camera);
			};
			init();
			animate();
			
			</script>
		</section>
	</body>
</html>
like image 206
lesly peña Avatar asked Sep 06 '25 03:09

lesly peña


2 Answers

It's not really surprising, you are resizing the renderer with the whole window width/height instead of the actual container div width/height, so what would you expect...?

Try to replace onWindowResize with that:

function onWindowResize() {

    camera.aspect = contenedor.clientWidth / contenedor.clientHeight;

    camera.updateProjectionMatrix();

    renderer.setSize(contenedor.clientWidth, contenedor.clientHeight);
}
like image 147
Felipe Avatar answered Sep 07 '25 18:09

Felipe


Instead of changing the size of the canvas, you can change the position of the object or the position of the camera by using javascript media queries. Refer to the below code it helped in my case.

loader.load('assets/check.glb', handle_load);
var mesh;
    function handle_load(gltf) {

        console.log(gltf);
        mesh = gltf.scene;
        console.log(mesh.children[0]);
        mesh.children[0].material = new THREE.MeshLambertMaterial();
		scene.add( mesh );
        mesh.position.z = 3;
        mesh.position.x = 1.8;
        mesh.position.y = -0.4;
        mesh.rotation.x = 0.3;
		function media(x) {
  if (x.matches) { 
        mesh.position.z = 1;
        mesh.position.x = 0;
        mesh.position.y =-0.4;
       
  } else {
        mesh.position.z = 3;
        mesh.position.x = 1.8;
        mesh.position.y = -0.4;
    
  }
}

var x = window.matchMedia("(max-width: 700px)")
media(x) 
x.addListener(media);
    }
like image 20
Moncy Yohannan Avatar answered Sep 07 '25 18:09

Moncy Yohannan