How to make custom autorotation smooth when FPS changes

I am trying to implement a custom autorotation, but I am failing to make it smooth as my fps can change dynamically and the rotation is lagging when it changes.

The current implementation looks following:

startAutorotation() {
    autorotationInterval = setInterval(() => this.autoRotate(1), 10); // Rotate every 10 ms
  }

  stopAutorotation() {
    if (autorotationInterval) {
      clearInterval(autorotationInterval);
    }
  }

// This part taken from ArcballControlls
  rotate(axis: Vector3, angle: number) {
    const point = this._gizmos.position; //rotation center
    this._translationMatrix.makeTranslation(-point.x, -point.y, -point.z);
    this._rotationMatrix.makeRotationAxis(axis, -angle);

    //rotate camera
    this._m4_1.makeTranslation(point.x, point.y, point.z);
    this._m4_1.multiply(this._rotationMatrix);
    this._m4_1.multiply(this._translationMatrix);

    this.setTransformationMatrices(this._m4_1);

    return _transformation;
  }

 applyTransformMatrix(transformation: TransformationType) {
    if (transformation.camera != null && this.camera) {
      this._m4_1
        .copy(this._cameraMatrixState)
        .premultiply(transformation.camera);
      this._m4_1.decompose(
        this.camera.position,
        this.camera.quaternion,
        this.camera.scale
      );
      this.camera.updateMatrix();

      //update camera up vector
        this.camera.up
          .copy(this._upState)
          .applyQuaternion(this.camera.quaternion);
    }
   ...
}

autoRotate = (speed = 1) => {
    this.applyTransformMatrix(
      this.rotate(new Vector3(0, speed, 0), Math.PI / 3000) // Rotate around Y axis.
    );

    this.camera.lookAt(this.target);
  };

Is there a way to make it smooth? I believe I need to use Clock.getDelta() to calculate rotation angle, but I am not sure how.

Also, there is a bonus question. I want it to always rotate around vertical axis, but when I update camera.up camera sees “vertical” differently. How can I calculate the vector to rotate camera around, so the rotation is aways around viewer perceived Y axis?

I believe these questions are quite basic, but for some reason, I’m stuck on them.

don’t use setInterval. don’t use more than one single requestAnimationFrame-loop — in that you call your classes update() method. in there you run something that has easing, i would suggest GitHub - pmndrs/maath: 🪶 Math helpers for the rest of us which is what unity uses. just feed it your clocks delta and it will ease towards the goal value. it supports all threejs classes: vec2, 3, 4, euler, matrix, quat, colors, etc.

1 Like

Thank you! I ended up using Tween.JS.