Search code examples
javascriptrotationthree.jskeypress

Three js keyboard rotation


can anyone help me in making a 3D object rotate on a y axis? with a press of keyboard button? (B)

I've been sitting on this issue for many days now, my code breaks every time i try to do something,

please please please

this is the 3D object that needs turning

https://www.dropbox.com/s/8yefhx3yc11zbik/b.obj?dl=0

and this is the code

var lesson6 = {
  scene: null,
  camera: null,
  renderer: null,
  container: null,
  controls: null,
  clock: null,
  stats: null,


  init: function() { // Initialization


this.scene = new THREE.Scene();

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


// prepare camera
var VIEW_ANGLE = 15, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 1, FAR = 0;
this.camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
this.scene.add(this.camera);
this.camera.position.set(10, 200, 0);
this.camera.lookAt(new THREE.Vector3(0,30,0));

// prepare renderer
this.renderer = new THREE.WebGLRenderer({ antialias:true });
this.renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);

this.renderer.shadowMapEnabled = true;
this.renderer.shadowMapSoft = true;


// prepare container
this.container = document.createElement('div');
document.body.appendChild(this.container);
this.container.appendChild(this.renderer.domElement);

// events
THREEx.WindowResize(this.renderer, this.camera);

// prepare controls (OrbitControls)
this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
this.controls.target = new THREE.Vector3(0, 0, 0);
this.controls.maxDistance = 2000;


//keyboard control





 // L I G H T S
  //bottom

var light = new THREE.DirectionalLight(0xffffff, 1);
    light.castShadow = true;
    light.shadowCameraVisible = true;
    light.shadowCameraNear = 100;
    light.shadowCameraFar = 200;
    light.shadowCameraLeft = -20; // CHANGED
    light.shadowCameraRight = 20; // CHANGED
    light.shadowCameraTop = 20; // CHANGED
    light.shadowCameraBottom = -20; // CHANGED
    light.position.set(180  ,20, 0); // CHANGED
    this.scene.add(light);
    this.scene.add( new THREE.DirectionalLightHelper(light, 0.2) );


//left



var dlight = new THREE.DirectionalLight(0xffffff, 1);
    dlight.castShadow = true;
    dlight.shadowCameraVisible = true;
    dlight.shadowCameraNear = 100;
    dlight.shadowCameraFar = 200;
    dlight.shadowCameraLeft = -20; // CHANGED
    dlight.shadowCameraRight = 20; // CHANGED
    dlight.shadowCameraTop = 20; // CHANGED
    dlight.shadowCameraBottom = -20; // CHANGED
    dlight.position.set(0, 20, 100); // CHANGED
    this.scene.add(dlight);
    this.scene.add( new THREE.DirectionalLightHelper(dlight, 0.2) );


// add simple ground

// load a model
this.loadModel();


},
  loadModel: function() {

// prepare loader and load the model
var oLoader = new THREE.OBJLoader();
oLoader.load('b.obj', function( geometry ) {

var material = new THREE.MeshLambertMaterial({ color: "red" });
var mesh = new THREE.Mesh (geometry, material);



geometry.traverse( function(child) {
    if (child instanceof THREE.Mesh) {

      // apply custom material
      child.material = material;
      child.castShadow = true;
      child.receiveShadow = true;
    }
  });

  geometry.rotation.y = -Math.PI / -1.7;
  geometry.position.x = 0;
  geometry.position.y = 0;
  geometry.position.z = 0;
  geometry.scale.set(1, 1, 1);
  lesson6.scene.add(geometry);
});
  }
};

// Animate the scene
function animate() {
  requestAnimationFrame(animate);
  render();
}


// Render the scene
function render() {
  if (lesson6.renderer) {
    lesson6.renderer.render(lesson6.scene, lesson6.camera);

    }
  }


// Initialize lesson on page load
function initializeLesson() {
  lesson6.init();
  animate();
}

if (window.addEventListener)
  window.addEventListener('load', initializeLesson, false);
else if (window.attachEvent)
  window.attachEvent('onload', initializeLesson);
else window.onload = initializeLesson;

Solution

  • When dealing with that sort of input, you want the button press to NOT modify any object. You want your keyup/keydown/other input events to do as little as possible: toggle a true/false variable or change a number.

    In this example:

    function handleKeyDown(event) {
      if (event.keyCode === 66) { //66 is "b"
        window.isBDown = true;
      }
    }
    
    function handleKeyUp(event) {
      if (event.keyCode === 66) {
        window.isBDown = false;
      }
    }
    
    window.addEventListener('keydown', handleKeyDown, false);
    window.addEventListener('keyup', handleKeyUp, false);
    

    From there, you can modify your animate() function to be:

    function animate() {
      requestAnimationFrame(animate);
      if (window.isBDown) {
        //Increment your object's Y rotation value a little bit.
        //Ideally, you would listen to animate()'s first argument,
        //which is a high resolution timestamp that says the current time
        //in milliseconds since the tab was opened.
      }
      render();
    }
    

    Note how all the work happens in animate(). Choose the correct speed, and the object will slowly rotate until you release the key. (Once comfortable with this concept, you can also add acceleration and momentum toanimate().)

    Gamepad joysticks work the same way, except that instead of true or false, you are given a decimal number. You can multiply this into whatever value you use for "speed". Usually 0 means the joystick is centered, 1 means the joystick is maxed out at that axis, and some number between means input is being delivered, but not all the way (or is being pulled diagonally).