title: 3D Rotation where the z-axis remains vertical
body: <p><a href="https://codepen.io/SitePoint/pen/VeEyvm?editors=0010" rel="nofollow noreferrer">This codepen</a> has a small rotation function that accepts theta and phi values. The formula of the rotation can be found anywhere on the internet and is fairly simple:</p>
  <pre class="lang-js prettyprint-override"><code>function rotate(P, C, theta, phi) {
      let ct = Math.cos(theta);
      let st = Math.sin(theta);
      let cp = Math.cos(phi);
      let sp = Math.sin(phi);
  
      let x = P.x - C.x;
      let y = P.y - C.y;
      let z = P.z - C.z;
  
      P.x = ct * x - st * cp * y + st * sp * z + C.x;
      P.y = st * x + ct * cp * y - ct * sp * z + C.y;
      P.z = sp * y + cp * z + C.z;
  }
  </code></pre>
  <p>This rotation works as a demonstration, but It's easy to loose track of which face of the cube is the initially bottom face.</p>
  <p><a href="https://github.com/openscad/openscad" rel="nofollow noreferrer">openSCAD</a> on the other hand has a very nice rotation where the z-axis of the object always appears as a vertical line:</p>
  <p><a href="https://i.stack.imgur.com/tcDnx.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/tcDnx.gif" alt="Cube rotated around the z axis" /></a></p>
  <p>The above function would behave the same, if you'd only change the <code>theta</code> value. As soon as you change <code>phi</code> value the cube stars to fall over.</p>
  <p>How would I write such a rotation in JavaScript?</p>