Add fit to selection camera function

This commit is contained in:
Nettika 2026-01-28 23:59:27 -08:00
parent e19eee5f74
commit fa7370da4f
No known key found for this signature in database
2 changed files with 25 additions and 1 deletions

View file

@ -43,7 +43,7 @@ A step-by-step checklist for porting MatterControl's design features to a Vue +
### Camera Controls ### Camera Controls
- [x] Install and configure OrbitControls (zoom, pan, orbit) - [x] Install and configure OrbitControls (zoom, pan, orbit)
- [ ] Add "fit to selection" camera function - [x] Add "fit to selection" camera function
- [ ] Add "reset view" function (home position) - [ ] Add "reset view" function (home position)
- [ ] Add view presets (front, back, top, bottom, left, right) - [ ] Add view presets (front, back, top, bottom, left, right)
- [ ] Add orthographic/perspective toggle - [ ] Add orthographic/perspective toggle

View file

@ -140,6 +140,26 @@ function animate() {
renderer.render(scene, camera) renderer.render(scene, camera)
} }
function fitToSelection(objects: THREE.Object3D[]) {
if (objects.length === 0) return
const box = new THREE.Box3()
for (const obj of objects) {
box.expandByObject(obj)
}
const center = box.getCenter(new THREE.Vector3())
const size = box.getSize(new THREE.Vector3())
const maxDim = Math.max(size.x, size.y, size.z)
const fov = camera.fov * (Math.PI / 180)
const distance = maxDim / (2 * Math.tan(fov / 2)) * 1.5
const direction = camera.position.clone().sub(controls.target).normalize()
camera.position.copy(center).add(direction.multiplyScalar(distance))
controls.target.copy(center)
controls.update()
}
function cleanup() { function cleanup() {
if (animationFrameId) { if (animationFrameId) {
cancelAnimationFrame(animationFrameId) cancelAnimationFrame(animationFrameId)
@ -166,6 +186,10 @@ onMounted(() => {
onBeforeUnmount(() => { onBeforeUnmount(() => {
cleanup() cleanup()
}) })
defineExpose({
fitToSelection,
})
</script> </script>
<template> <template>