Functions are values too

On the previous page, we defined a method for rotation around the z-axis. When called with elapsed time delta, it increments this object’s angle of rotation based on its rotation rate rps:

function spinZ(delta) {
    this.rotation.z += rpsToRadians(this.rps, delta);
    this.rotation.z %= 2 * Math.PI;
}

We’ll need to spin around the other principal axes in coming pages. Rather than write separate spinX and spinY functions that differ only minimally, we define a function that can define and return any of these functions, depending on whether it’s called with 0 (spin around the x-axis), 1 (y-axis), or 2 (z-axis).

function makeSpin(indx, rps="rps") {
    return function (delta) {
        let vec = this.rotation.toVector3();
        let val = vec.getComponent(indx);
        val += rpsToRadians(this[rps], delta);
        val %= 2 * Math.PI;
        vec.setComponent(indx, val);
        this.rotation.setFromVector3(vec);
    }
}

let spinZ = makeSpin(2);

We cannot apply getComponent and setComponent to this.rotation directly since its value is an Euler object rather than a Vector3 which provides these getter and setter methods. But it is easy to translate between these two types.

Note we store an object’s rotational rate in its rps property by default, which can be changed by calling makeSpin with a different property name. This can be useful for spinning an object around multiple principal axes at different rates.