Keeping an object scaled based on the bounds of the canvas (really battling to explain this one)

is this similar to background-size: cover in css? if yes, you can calculate it like this:

  const v = ... // viewport
  const aspect = size.width / size.height 

  const adaptedHeight = height * (aspect > width / height ? v.width / width : v.height / height)
  const adaptedWidth = width * (aspect > width / height ? v.width / width : v.height / height)
  return [adaptedWidth * factor, adaptedHeight * factor, 1]

the viewport is calculated like so:

  const getCurrentViewport = (camera, target, size) => {
      const { width, height } = size
      const distance = camera.position.distanceTo(target)
      if (isOrthographicCamera(camera)) {
        return { width: width / camera.zoom, height: height / camera.zoom, factor: 1, distance }
      } else {
        const fov = (camera.fov * Math.PI) / 180 // convert vertical fov to radians
        const h = 2 * Math.tan(fov / 2) * distance // visible height
        const w = h * (width / height)
        return { width: w, height: h, factor: width / w, distance }
      }
    }

this is how it looks, it scales the object (a plane in this case) based on the canvas viewport: https://codesandbox.io/s/r3f-floating-diamonds-dwkjr

2 Likes