JSFiddle - React, Tailwind, and code Playground

by Simon060694

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/102/three.min.js"></script>
<button type="button">
  Center + Fit object
</button>

SCSS

html, body {
  margin: 0;
  padding: 0;
}

canvas {
  margin: 0;
  width: 100%;
  height: 100%;
}

button {
  position: absolute;
  top: 10px;
  left: 10px;
}

JavaScript

// SETUP
const camera = new THREE.PerspectiveCamera(
  70,
  window.innerWidth / window.innerHeight,
  1,
  1000
)

const scene = new THREE.Scene()

const renderer = new THREE.WebGLRenderer()
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)


const material = new THREE.MeshBasicMaterial({
  color: 0x3a9ceb
})

// generating a randomly rotated and positioned cube
const cube = new THREE.Mesh(new THREE.BoxGeometry(20, 20, 20), material)
cube.position.set(
  Math.random() * 200 - 100,
  Math.random() * 200 - 100,
  Math.random() * -400
)
cube.rotation.set(
  Math.random() * Math.PI * 2,
  Math.random() * Math.PI * 2,
  Math.random() * Math.PI * 2
)
scene.add(cube)

// fit object to camera fov
document.querySelector('button').addEventListener('click', () => {
  const boundingBox = new THREE.Box3()
  boundingBox.setFromObject(cube)

  const center = new THREE.Vector3()
  boundingBox.getCenter(center)

  camera.position.y = center.y
  camera.position.x = center.x
  camera.updateProjectionMatrix()

  const size = new THREE.Vector3()
  boundingBox.getSize(size)

  const fov = camera.fov * (Math.PI / 180)
  const maxDim = Math.max(size.x, size.y, size.z)
  let cameraZ = Math.abs((maxDim / 4) * Math.tan(fov * 2))

  camera.position.z = cameraZ
  camera.updateProjectionMatrix()

  camera.lookAt(center)
  console.log(camera.fov * (Math.PI / 180))
})


// animate the scene
const animate = (timestamp) => {
  window.requestAnimationFrame(animate)
  renderer.render(scene, camera)
}

animate()

// resize handler
window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()

  renderer.setSize(window.innerWidth, window.innerHeight)
}, false)