Manually set scene orientation

How can you orient the scene in a camera direction and then frame all?

For example, view the scene where the camera is normalized in the direction 1,0,0 (x,y,z) so that you are looking at the scene in one direction. Another angles would be -1,0,0 where you would be looking at the scene in the opposite direction from the first. Left, Right, Top, Bottom, Front, Back.

Similar to a view cube, but you set the directions manually.

Check out this live demo. It shows how to set the camera Xfo from a matrix that is computed from a direction and an up-vector.

The code to set the camera matrix is covered here.

const camera = renderer.getViewport().getCamera()
const setCameraXfo = (dir, up) => {
  const sw =  up.cross(dir).normalize()
  const mat3 = new Mat3(up, sw, dir.negate())
  const xfo = new Xfo()
  xfo.ori.setFromMat3(mat3)
  const target = camera.getTargetPosition()
  const dist = camera.getFocalDistance()
  xfo.tr = target.subtract(dir.scale(dist))
  camera.getParameter('GlobalXfo').setValue(xfo)
}

document.getElementById("camera-button-top").addEventListener("click", function (event) {
  setCameraXfo(new Vec3(0, 0, -1), new Vec3(-1, 0, 0))
});
document.getElementById("camera-button-bottom").addEventListener("click", function (event) {
  setCameraXfo(new Vec3(0, 0, 1), new Vec3(-1, 0, 0))
});
document.getElementById("camera-button-left").addEventListener("click", function (event) {
  setCameraXfo(new Vec3(0, -1, 0), new Vec3(-1, 0, 0))
});
document.getElementById("camera-button-right").addEventListener("click", function (event) {
  setCameraXfo(new Vec3(0, 1, 0), new Vec3(1, 0, 0))
});

https://camera-directions.glitch.me

When changing the camera position and target, is it possible to animate the transformation from the current camera to the new camera?

yes it is. (sorry I missed your follow-up question).

Note: there was a slight bug in the original code I posted above, so here is the updated code. (I also updated the Glitch demo)

const setCameraXfo = (camera, dir, up) => {
  const sw = dir.cross(up).normalize()
  const upNormalized = sw.cross(dir).normalize()
  const mat3 = new Mat3(sw, upNormalized, dir.negate())
  const xfo = new Xfo()
  xfo.ori.setFromMat3(mat3)
  const target = camera.getTargetPosition()
  const dist = camera.getFocalDistance()
  xfo.tr = target.subtract(dir.scale(dist))
  camera.getParameter('GlobalXfo').setValue(xfo)
  
  // Frame all after changing the camera Xfo 
  renderer.frameAll()
}

You also asked about framing after moving the camera, so I added that as well.
For completeness, here is the place in the Svelte template you can go to modify to add your own changes.

And now, to answer your question about animation…

The right way to do it, is to calculate the new orientation of the camera using the direction and up vector values, then lerp towards it, and then calculate the position of the camera by subtracting the distance off the target.

Here is the code I added to the sample.

const setCameraXfo = (camera, dir, up, duration = 400) => {

  const startTarget = camera.getTargetPosition()
  const startDist = camera.getFocalDistance()
  
  const startXfo = camera.getParameter('GlobalXfo').getValue()
  
  // Calculate the target orientation of the camera.
  const sw = dir.cross(up).normalize()
  const upNormalized = sw.cross(dir).normalize()
  const mat3 = new Mat3(sw, upNormalized, dir.negate())
  const endOri = new Quat()
  endOri.setFromMat3(mat3)
  endOri.alignWith(startXfo.ori)
  
  const xfo = new Xfo()
  xfo.ori = endOri
  camera.getParameter('GlobalXfo').setValue(xfo)
  // Now to calculate where the camera will end up at the end
  // after framing, we set the camera Xfo, call frameAll, 
  // extract the target, and then put back the old value so we can
  // start interpolating.
  renderer.frameAll()
  const endTarget = camera.getTargetPosition()
  const endDist = camera.getFocalDistance()
  camera.getParameter('GlobalXfo').setValue(startXfo)
  
  const count = Math.round(duration / 20) // each step is 20ms
  let id
  let i = 0
  const applyMovement = () => {
    const lerpValue = i / count
    
    // interpolate the orientation between the start and the end ones.
    const xfo = new Xfo()
    xfo.ori = startXfo.ori.lerp(endOri, lerpValue).normalize()
    
    // interpolate the target and distance between the start and the end ones.
    const target = startTarget.lerp(endTarget, lerpValue)
    const dist = MathFunctions.lerp(startDist, endDist, lerpValue)
    
    // Move the camera back away from the new target using the orientation.
    const newDir = xfo.ori.getZaxis().negate()
    xfo.tr = target.subtract(newDir.scale(dist))
    
    camera.getParameter('GlobalXfo').setValue(xfo)
    i++
    if (i <= count) {
      id = setTimeout(applyMovement, 20)
    } else {
      //renderer.frameAll()
      // Thie event tells the viewport to re-rendeer the picking buffer.
      camera.emit('movementFinished')
    }
  }
  applyMovement()
}

Some of this math could be included in the camera so you can just set a position, target, and upvector and it would just move, but most of the complexity here is in how to interpolate from the inital Xfo to the target Xfo in an elegant way.

you can checkout the live demo here, and test out the camera interpolation yourself.