# (Three.js) How to slowly rotate a mesh until it reaches a specific value

I’ve just gotten into Three.JS, and I’ve ran into an issue. I’m trying to make a car, that is drivable using the Arrow Keys. So far, I’ve gotten it to move forwards, and backwards, and the wheels turn when you press Up (Forwards) and Down (Backwards). So, logically, the next step would be turning. However, that’s where I run I to my issue.

I can’t figure out how to make it so that when I press the left or right arrow keys, it will slowly, gradually increase the rotation of the wheels, until they reach a certain value, say, 45 for left, and -45 for right.

I have a cube, stretched out to the shape of a mostly flat rectangle, called chassis. I have four wheels, Wheel_FL, FR, RL, and RR. F meaning Front, First R meaning rear, L meaning Left, Second R meaning right. Both Wheel_FL and Wheel_FR have a group as their parent, which I will use to rotate them left or right, they act as a pivot. I cannot figure out how to do this, I’ve tried looking for an answer everywhere for the past couple of days, to no avail. If anyone has any ideas, please, let me know! And if anyone needs any more information, please, let me know!

I’m also looking for a way to, then, once this steering issue is fixed, to rotate the chassis itself in a way that is realistic to how a car would turn.

Thanks!

If anyone needs an example, I have one here.

Let’s name the variables: `Wheel_FL, Wheel_FR, Group_FL, Group_FR;`. Each wheel is nested inside its respective group with `Group_FL.add(Wheel_FL);`

So to spin the wheels, you’d probably do `Wheel_FL.rotation.x += spinAngle;` or maybe `rotation.z` based on the orientation of your asset. Now to steer left/right, you’d want to rotate the container `Group` so it doesn’t interfere with the spinning angle: `Group_FL.rotation.y = steerAngle;`

To animate, or tween this steering angle, you could use the `MathUtils.lerp()` function (lerp stands for Linear-interpolation), which takes a variable and eases it towards its target.

```var Wheel_FL, Wheel_FR;
var Group_FL = new THREE.Group();
var Group_FR = new THREE.Group();
var spinAngle = 0;
var steerAngle = 0;
var steerAngleTarget = 0;
function update() {
// Update wheel spin
Wheel_FL.rotation.x += spinAngle;
Wheel_FR.rotation.x += spinAngle;
// Tween steering angle towards target
steerAngle = MathUtils.lerp(steerAngle, steerAngleTarget, 0.1);
// Rotate parent group around y-axis
Group_FL.rotation.y = steerAngle;
Group_FR.rotation.y = steerAngle;
}
function steerLeft() {
steerAngleTarget = Math.PI / 4; // 45 deg in radians
}
function steerRight() {
steerAngleTarget = - Math.PI / 4; // -45 deg in radians
}
```

I’ve created a working demo for you below. Use w-a-s-d keys to steer, accelerate, and decelerate:

```var camera, scene, renderer, clock, container;
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 1, 100 );
camera.position.y = 10;
camera.position.z = 5;
camera.lookAt(0, 0, 0);
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xeeeeee );
scene.fog = new THREE.Fog( 0xcccccc, 100, 1500 );
clock = new THREE.Clock();
var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x222222, 1.5 );
hemiLight.position.set( 1, 1, 1 );
var floor = new THREE.Mesh(new THREE.PlaneBufferGeometry(10, 10), new THREE.MeshBasicMaterial({color: 0x999999}));
floor.rotation.x = -Math.PI/2;
renderer = new THREE.WebGLRenderer();
renderer.setSize( container.offsetWidth, container.offsetHeight );
container.appendChild( renderer.domElement );
// Create wheels
var Wheel_FL = new THREE.Mesh(
new THREE.CylinderBufferGeometry(1, 1, 1, 8),
new THREE.MeshBasicMaterial({color: 0xffff00, wireframe: true})
);
var Wheel_FR = new THREE.Mesh(
new THREE.CylinderBufferGeometry(1, 1, 1, 8),
new THREE.MeshBasicMaterial({color: 0xffff00, wireframe: true})
);
var Group_FL = new THREE.Group();
var Group_FR = new THREE.Group();
// Set initial positions and rotations
Wheel_FL.position.y = 1;
Wheel_FR.position.y = 1;
Wheel_FL.rotation.z = Math.PI / 2;
Wheel_FR.rotation.z = Math.PI / 2;
// Add wheels to group, and position groups
Group_FL.position.x = -2;
Group_FR.position.x = 2;
var spinAngle = 0;
var steerAngle = 0;
var steerAngleTarget = 0;
// WASD to turn, accelerate, and decelerate
function onKeyPress(evt) {
switch(evt.key) {
case 'a':
steerAngleTarget = Math.PI / 6; // 45 deg in radians
break;
case 'd':
steerAngleTarget = - Math.PI / 6; // -45 deg in radians
break;
case 'w':
spinAngle += 0.01; // accelerate
break;
case 's':
spinAngle -= 0.01; // decelerate
break;
}
}
// Returns wheels to center
function onKeyRelease() {
steerAngleTarget = 0;
}
function onWindowResize() {
camera.aspect = container.offsetWidth / container.offsetHeight;
camera.updateProjectionMatrix();
renderer.setSize( container.offsetWidth, container.offsetHeight );
}
function update() {
// Update wheel spin
Wheel_FL.rotation.x -= spinAngle;
Wheel_FR.rotation.x -= spinAngle;
// Tween steering angle towards target
steerAngle = THREE.MathUtils.lerp(steerAngle, steerAngleTarget, 0.1);
// Rotate parent group around y-axis
Group_FL.rotation.y = steerAngle;
Group_FR.rotation.y = steerAngle;
requestAnimationFrame( update );
renderer.render(scene, camera);
}
update();```
```body, html {
background-color: #fff;
color: #222;
width: 100%;
height: 100%;
margin: 0;
```<script src="https://cdn.rawgit.com/mrdoob/three.js/dev/build/three.js"></script>