Three.js如何将对象放置在屏幕的左半边(宽度和高度)

时间:2019-05-16 08:14:37

标签: javascript three.js tween orbit-controls

单击按钮后,我希望整个3D对象(宽度和高度)适合屏幕的左侧,并在屏幕的右侧显示div HTML信息。

如何在屏幕左侧放置对象?可以设置margin(px)吗?

var camera, scene, renderer;
var geometry, material, mesh;
var lookDirection = new THREE.Vector3();

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
    camera.position.z = 1;

    scene = new THREE.Scene();
 
    geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
    material = new THREE.MeshNormalMaterial();

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

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );
    
    controls = new THREE.OrbitControls( camera, renderer.domElement );
    controls.mouseButtons = {
      LEFT: THREE.MOUSE.RIGHT, 
      MIDDLE: THREE.MOUSE.MIDDLE, 
      RIGHT: THREE.MOUSE.LEFT
    }
    controls.enableZoom = false;
    

}

function animate() {

    requestAnimationFrame( animate );

    renderer.render( scene, camera );
    
    controls.update();
    
    TWEEN.update();

}

function fit(){
	
    controls.enabled = false;

    var box = new THREE.Box3().setFromObject(mesh);
    var boxSize = box.getSize(new THREE.Vector3()).length();
    var boxCenter = box.getCenter(new THREE.Vector3());

    var halfSizeToFitOnScreen = boxSize * 0.5;
    var halfFovY = THREE.Math.degToRad(camera.fov * 0.5);
    var distance = halfSizeToFitOnScreen / Math.tan(halfFovY);

    // compute a unit vector that points in the direction the camera is now
    // in the xz plane from the center of the box
    const direction = (new THREE.Vector3())
        .subVectors(camera.position, boxCenter)
        .multiply(new THREE.Vector3(1, 0, 1))
        .normalize();

    // tween animation
    var from = camera.position;
    var to = direction.multiplyScalar(distance).add(boxCenter);

    var tween = new TWEEN.Tween(from)
        .to(to, 1000)
        .easing(TWEEN.Easing.Quadratic.InOut)
        .onUpdate(function () {
            camera.position.set(this.x, this.y, this.z);

            // update the Trackball controls to handle the new size
            controls.enabled = true;
            controls.target.copy(boxCenter);
            controls.update();
        })
        .start();
  
}

document.getElementById("btn").addEventListener("click", fit);
body {
  margin: 0;
  overflow: hidden;
}

button {
  position: fixed;
  top: 0;
  left: 0;
}
<button id="btn">Fit</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://sole.github.io/tween.js/build/tween.min.js"></script>

谢谢!

2 个答案:

答案 0 :(得分:0)

听起来像您实际上只是在问一个HTML / JavaScript问题

一种方法是使用弹性盒

function fit(){
   const elem = document.querySelector('#panes> .right');
   elem.style.display = elem.style.display == 'none' ? '' : 'none';
  
}

document.getElementById("btn").addEventListener("click", fit);
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
body {
  margin: 0;
}

canvas {
  display: block;
  width: 100%;
  height: 100%;
}
#panes {
  display: flex;
  width: 100vw;
  height: 100vh;
}
#panes>.left,
#panes>.right {
  flex: 1 1 50%;
  height: 100%;
}

#panes>.left {
  padding: 1em;
  text-align: center;
  background: red;
}

#panes>.right {
  padding: 1em;
  background: blue;
  color: white;
}

button {
  position: fixed;
  top: 0;
  left: 0;
}
<div id="panes">
  <div class="left"> Stuff On Left</div>
  <div class="right" style="display: none;">Stuff on right</div>
</div>
<button id="btn">Fit</button>

然后将画布插入左窗格,并使用a better example设置画布大小的方法

var camera, scene, renderer;
var geometry, material, mesh;
var lookDirection = new THREE.Vector3();

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera( 70, 2, 0.01, 10 );
    camera.position.z = 1;

    scene = new THREE.Scene();
 
    geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
    material = new THREE.MeshNormalMaterial();

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

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    document.querySelector("#panes>.left").appendChild( renderer.domElement );
    
    controls = new THREE.OrbitControls( camera, renderer.domElement );
    controls.mouseButtons = {
      LEFT: THREE.MOUSE.RIGHT, 
      MIDDLE: THREE.MOUSE.MIDDLE, 
      RIGHT: THREE.MOUSE.LEFT
    }
    controls.enableZoom = false;
    

}

function resizeRendererToDisplaySize(renderer) {
  const canvas = renderer.domElement;
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;
  const needResize = canvas.width !== width || canvas.height !== height;
  if (needResize) {
    renderer.setSize(width, height, false);
  }
  return needResize;
}

function animate() {

  if (resizeRendererToDisplaySize(renderer)) {
    const canvas = renderer.domElement;
    camera.aspect = canvas.clientWidth / canvas.clientHeight;
    camera.updateProjectionMatrix();
  }

    renderer.render( scene, camera );
    
    controls.update();
    
    TWEEN.update();

    requestAnimationFrame( animate );

}

function fit(){
   const elem = document.querySelector('#panes> .right');
   elem.style.display = elem.style.display == 'none' ? '' : 'none';
  
}

document.getElementById("btn").addEventListener("click", fit);
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
body {
  margin: 0;
}

canvas {
  display: block;
  width: 100%;
  height: 100%;
}
#panes {
  display: flex;
  width: 100vw;
  height: 100vh;
}
#panes>.left,
#panes>.right {
  flex: 1 1 50%;
  height: 100%;
}

#panes>.right {
  padding: 1em;
  background: blue;
  color: white;
}

button {
  position: fixed;
  top: 0;
  left: 0;
}
<div id="panes">
  <div class="left"></div>
  <div class="right" style="display: none;">Stuff on right</div>
</div>
<button id="btn">Fit</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://sole.github.io/tween.js/build/tween.min.js"></script>

答案 1 :(得分:0)

我希望现在回答这个问题不晚,但是我发现了一些您可能正在寻找的东西。选中Is there ANY way to have the three.js camera lookat being rendered off-center?

camera = new THREE.PerspectiveCamera( for, aspect, near, far );

camera.setViewOffset( fullWidth, fullHeight, widthOffset, heightOffset, viewWidth, viewHeight );

将widthOffset和heightOffset作为参数将摄像机的目标滑到任意一侧。