带按钮的ThreeJS相机控制

时间:2015-08-17 18:12:48

标签: javascript three.js

我非常喜欢google lego build网站上的相机控件。 https://www.buildwithchrome.com/builder

如何使用按钮控制透视图?

放大/缩小并旋转到固定位置会很棒。

我正在使用three.js / examples中的 this 演示。 也许有人可以指导我一个方向。非常感谢你提前!

<div class="perspective">

  <div class="rotate">
    <div class="build-rotate">
          <a data-rotate="315" href="#rotate315"></a>
          <a data-rotate="45" href="#rotate0"></a>
          <a data-rotate="225" href="#rotate225"></a>
          <a data-rotate="135" href="#rotate135"></a>
          <a class="rotate-free" href="#"></a>
          <img src="https://www.buildwithchrome.com/v2-2-1.376043847035368998/img/build/rotate-indicator.png" style="transform: rotate(77.3493023426611deg);">
    </div>
  </div>

    <a href="#" id="zoomIn" class="zoomin">+</a>

    <a href="#" id="zoomOut" class="zoomout">-</a>

  </div>

if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

   var SCREEN_WIDTH = window.innerWidth;
   var SCREEN_HEIGHT = 650;
   var FLOOR = -250;

   var container;

   var camera, scene, controls;
   var renderer;

   var mesh;

   var textureCube;
   var cameraCube, sceneCube;

   var loader;

   var mouseX = 0, mouseY = 0;

   var windowHalfX = window.innerWidth / 2;
   var windowHalfY = window.innerHeight / 2;

   init();
   animate();

   function init() {


     // CAMERA

     camera = new THREE.PerspectiveCamera( 25, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
     camera.position.set( 185, 40, 170 );

     controls = new THREE.OrbitControls( camera, previewDiv );
     controls.maxPolarAngle = Math.PI / 2;
     controls.minDistance = 200;
     controls.maxDistance = 500;

     // SCENE

     scene = new THREE.Scene();

     // SKYBOX

     sceneCube = new THREE.Scene();
     cameraCube = new THREE.PerspectiveCamera( 25, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
     sceneCube.add( cameraCube );

     var r = "textures/cube/pisa/";
     var urls = [ r + "px.jpg", r + "nx.jpg",
            r + "py.jpg", r + "ny.jpg",
            r + "pz.jpg", r + "nz.jpg" ];


     textureCube = THREE.ImageUtils.loadTextureCube( urls );

     var shader = THREE.ShaderLib[ "cube" ];
     shader.uniforms[ "tCube" ].value = textureCube;

     var material = new THREE.ShaderMaterial( {

       fragmentShader: shader.fragmentShader,
       vertexShader: shader.vertexShader,
       uniforms: shader.uniforms,
       depthWrite: false,
       side: THREE.BackSide

     } ),

     mesh = new THREE.Mesh( new THREE.BoxGeometry( 100, 100, 100 ), material );
     sceneCube.add( mesh );

     // LIGHTS

     var light = new THREE.PointLight( 0xffffff, 1 );
     light.position.set( 2, 5, 1 );
     light.position.multiplyScalar( 30 );
     scene.add( light );

     var light = new THREE.PointLight( 0xffffff, 0.75 );
     light.position.set( -12, 4.6, 2.4 );
     light.position.multiplyScalar( 30 );
     scene.add( light );

     scene.add( new THREE.AmbientLight( 0x050505 ) );

     // RENDERER

     renderer = new THREE.WebGLRenderer( { antialias: true } );
     renderer.setPixelRatio( window.devicePixelRatio );
     renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
     renderer.domElement.style.position = "relative";

     renderer.autoClear = false;

     var previewDiv = document.getElementById("preview");
     previewDiv.appendChild (renderer.domElement);

     //

     renderer.gammaInput = true;
     renderer.gammaOutput = true;


     // EVENTS

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

     // LOADER

     var start = Date.now();

     // new way via CTMLoader and separate parts

     loaderCTM = new THREE.CTMLoader( true );
     document.body.appendChild( loaderCTM.statusDomElement );

     var position = new THREE.Vector3( -105, -78, -40 );
     var scale = new THREE.Vector3( 30, 30, 30 );

     loaderCTM.loadParts( "models/ctm/camaro/camaro.js", function( geometries, materials ) {

       hackMaterials( materials );

       for ( var i = 0; i < geometries.length; i ++ ) {

         var mesh = new THREE.Mesh( geometries[ i ], materials[ i ] );
         mesh.position.copy( position );
         mesh.scale.copy( scale );
         scene.add( mesh );

       }

       loaderCTM.statusDomElement.style.display = "none";

       var end = Date.now();

       console.log( "load time:", end - start, "ms" );

     }, { useWorker: true } );

   }

   //

   function hackMaterials( materials ) {

     for ( var i = 0; i < materials.length; i ++ ) {

       var m = materials[ i ];

       if ( m.name.indexOf( "Body" ) !== -1 ) {

         var mm = new THREE.MeshPhongMaterial( { map: m.map } );

         mm.envMap = textureCube;
         mm.combine = THREE.MixOperation;
         mm.reflectivity = 0.75;

         materials[ i ] = mm;

       } else if ( m.name.indexOf( "mirror" ) !== -1 ) {

         var mm = new THREE.MeshPhongMaterial( { map: m.map } );

         mm.envMap = textureCube;
         mm.combine = THREE.MultiplyOperation;

         materials[ i ] = mm;

       } else if ( m.name.indexOf( "glass" ) !== -1 ) {

         var mm = new THREE.MeshPhongMaterial( { map: m.map } );

         mm.envMap = textureCube;
         mm.color.copy( m.color );
         mm.combine = THREE.MixOperation;
         mm.reflectivity = 0.25;
         mm.opacity = m.opacity;
         mm.transparent = true;

         materials[ i ] = mm;

       } else if ( m.name.indexOf( "Material.001" ) !== -1 ) {

         var mm = new THREE.MeshPhongMaterial( { map: m.map } );

         mm.shininess = 30;
         mm.color.setHex( 0x404040 );
         mm.metal = true;

         materials[ i ] = mm;

       }

       materials[ i ].side = THREE.DoubleSide;

     }

   }

   //

   function createScene( geometry, materials, x, y, z, s ) {

     loader.statusDomElement.style.display = "none";

     geometry.center();

     hackMaterials( materials );

     var material = new THREE.MeshFaceMaterial( materials );

     mesh = new THREE.Mesh( geometry, material );
     mesh.position.set( x, y, z );
     mesh.scale.set( s, s, s );
     scene.add( mesh );

   }

   //

   function onWindowResize( event ) {

     SCREEN_WIDTH = window.innerWidth;
     SCREEN_HEIGHT = window.innerHeight;

     renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );

     camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
     camera.updateProjectionMatrix();

     cameraCube.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
     cameraCube.updateProjectionMatrix();

   }


   function onDocumentMouseMove(event) {

     mouseX = ( event.clientX - windowHalfX );
     mouseY = ( event.clientY - windowHalfY );

   }

   //

   function animate() {

     requestAnimationFrame( animate );

     render();

   }

   function render() {

     controls.update();

     cameraCube.rotation.copy( camera.rotation );

     renderer.clear();
     renderer.render( sceneCube, cameraCube );
     renderer.render( scene, camera );

   }
.scene{
  position: relative;
  width: 1000px;
  height: 1000px;
  background-color: #eee;
 
}

.perspective{
  position: absolute;
  left: 24px;
  top: 24px;
 
  width: 60px;
  z-index: 10;
}

.rotate {
    border-radius: 5px;
    width: 60px;
    height: 60px;
    background: #fff;
    margin-bottom: 24px;
    position: relative;
}

.rotate .build-rotate {
    position: absolute;
    height: 40px;
    width: 40px;
    top: 50%;
    left: 50%;
    margin-top: -20px;
    margin-left: -20px;
    -webkit-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
}

.rotate .build-rotate a {
    float: left;
    width: 20px;
    margin: 0;
    padding: 0;
    height: 20px;
    position: relative;
    z-index: 26;
    background: transparent url(https://www.buildwithchrome.com/v2-2-1.376043847035368998/img/v2/builder-rotator-bg.png) no-repeat 0 0;
    background-size: 40px 240px;
}

.rotate .build-rotate a:nth-child(1) {
    background-position: 0 0;
}

.rotate .build-rotate a:nth-child(1):hover {
    background-position: 0 -160px;
}

.rotate .build-rotate a:nth-child(2) {
    background-position: -20px 0;
}

.rotate .build-rotate a:nth-child(2):hover {
    background-position: -20px -40px;
}

.rotate .build-rotate a:nth-child(3) {
    background-position: 0 -20px;
}

.rotate .build-rotate a:nth-child(3):hover {
    background-position: 0 -140px;
}

.rotate .build-rotate a:nth-child(4) {
    background-position: -20px -20px;
}

.rotate .build-rotate a:nth-child(4):hover {
    background-position: -20px -100px;
}

.rotate .build-rotate img {
    position: absolute;
    top: 10px;
    left: 10px;
    height: 20px;
    width: 20px;
    margin-top: 0;
    margin-left: 0;
    -webkit-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
    z-index: 25;
}

.rotate .build-rotate .rotate-free, .rotate .build-rotate .rotate-free:hover, .rotate .build-rotate .rotate-free:active {
    display: block;
    width: 25px;
    height: 25px;
    position: absolute;
    top: 7px;
    left: 8px;
    border-radius: 13px;
    background: transparent;
}


a.zoomin, a.zoomout {
  width: 60px;
  height: 61px;
  background-color: #fff;
  border-radius: 4px;
  display: block;
  color: #555;
  font-size: 40px;
  border: none;
  text-align: center;
  background-position: center center;
  background-repeat: no-repeat;
  cursor: pointer;
  position: relative;
}

a.zoomin {
  border-bottom: 1px #f5f5f5 solid;
  border-radius: 3px 3px 0 0;
}

a.zoomout {
  border-top: 1px #f5f5f5 solid;
  border-radius: 0 0 3px 3px;
}

a.zoomin:hover, a.zoomout:hover {
  background-color: #f7f7f7;
}
<div class="scene">
</div>

<div class="perspective">

  <div class="rotate">
    <div class="build-rotate">
          <a data-rotate="315" href="#rotate315"></a>
          <a data-rotate="45" href="#rotate0"></a>
          <a data-rotate="225" href="#rotate225"></a>
          <a data-rotate="135" href="#rotate135"></a>
          <a class="rotate-free" href="#"></a>
          <img src="https://www.buildwithchrome.com/v2-2-1.376043847035368998/img/build/rotate-indicator.png" style="transform: rotate(77.3493023426611deg);">
    </div>
  </div>

    <a href="#" id="zoomIn" class="zoomin">+</a>

    <a href="#" id="zoomOut" class="zoomout">-</a>

  </div>

1 个答案:

答案 0 :(得分:0)

我想这就是你要找的东西。检查此示例:

http://mrdoob.github.io/three.js/examples/misc_controls_pointerlock.html

基本上,你添加

<script src="js/controls/PointerLockControls.js"></script>

然后这样的事情应该有效。

controls = new THREE.PointerLockControls( camera );
        scene.add( controls.getObject() );

        var onKeyDown = function ( event ) {

            switch ( event.keyCode ) {

                case 38: // up
                case 87: // w
                    moveForward = true;
                    break;

                case 37: // left
                case 65: // a
                    moveLeft = true; break;

                case 40: // down
                case 83: // s
                    moveBackward = true;
                    break;

                case 39: // right
                case 68: // d
                    moveRight = true;
                    break;

                case 32: // space
                    if ( canJump === true ) velocity.y += 350;
                    canJump = false;
                    break;

            }

        };

        var onKeyUp = function ( event ) {

            switch( event.keyCode ) {

                case 38: // up
                case 87: // w
                    moveForward = false;
                    break;

                case 37: // left
                case 65: // a
                    moveLeft = false;
                    break;

                case 40: // down
                case 83: // s
                    moveBackward = false;
                    break;

                case 39: // right
                case 68: // d
                    moveRight = false;
                    break;

            }

        };

通过整个代码的示例,它确实有帮助!