【问题标题】:How to make responsive canvas with a 3d model using three.js?如何使用 three.js 制作带有 3d 模型的响应式画布?
【发布时间】:2018-05-25 04:26:04
【问题描述】:

我正在制作一个网页,我在其中创建了一个画布来使用threejs 显示一个3d 对象(一个立方体)。我将此画布添加到一个 div 中(如几个文档中所示)。
问题是,当我将屏幕大小更改为小画布并且对象变小时,效果很好,但是当屏幕变大时,画布会扩展并占据整个页面。
我正在寻找的是保持同时分配宽度和高度的尺寸
提前致谢。

<!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>

【问题讨论】:

  • 我不知道你在问什么——当屏幕变大时,画布就变大了,这不就是你所说的“响应式”吗?如果您希望画布保持一定大小,则应在 CSS 中设置 width: 500px;max-width: 500px;
  • 正是我所说的答案,是的,我也希望画布保持其大小。因为当我放大屏幕时,画布采用屏幕的大小而不是容器的大小,甚至添加了最大宽度但仍然溢出。
  • 我认为问题出在 onWindowResize 函数中,因为我使用屏幕上的测量值,但我找不到如何分配画布的测量值。
  • 你可以使用contenedor.clientWidthcontenedor.clientHeight
  • 哇!它奏效了,但你可以解释为什么会这样。非常感谢

标签: javascript css html three.js


【解决方案1】:

这并不奇怪,您正在使用整个窗口的宽度/高度而不是实际的容器 div 宽度/高度来调整渲染器的大小,那么您会期待什么...?

尝试将onWindowResize 替换为:

function onWindowResize() {

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

    camera.updateProjectionMatrix();

    renderer.setSize(contenedor.clientWidth, contenedor.clientHeight);
}

【讨论】:

    【解决方案2】:

    您可以使用 javascript 媒体查询来更改对象的位置或相机的位置,而不是更改画布的大小。请参阅下面对我有帮助的代码。

    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);
        }

    【讨论】:

    • 参考从 (function media(x){ ) 开始查询
    猜你喜欢
    • 2021-02-20
    • 2017-02-12
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多