diff --git a/TODO.md b/TODO.md index 7b946cd06..f474a6481 100644 --- a/TODO.md +++ b/TODO.md @@ -45,7 +45,7 @@ A step-by-step checklist for porting MatterControl's design features to a Vue + - [x] Install and configure OrbitControls (zoom, pan, orbit) - [x] Add "fit to selection" camera function - [x] Add "reset view" function (home position) -- [ ] Add view presets (front, back, top, bottom, left, right) +- [x] Add view presets (front, back, top, bottom, left, right) - [ ] Add orthographic/perspective toggle ### Scene State Management diff --git a/src/components/Viewport.vue b/src/components/Viewport.vue index d7059fdbb..568ca0ce8 100644 --- a/src/components/Viewport.vue +++ b/src/components/Viewport.vue @@ -27,6 +27,18 @@ let controls: OrbitControls const HOME_POSITION = new THREE.Vector3(5, 5, 5) const HOME_TARGET = new THREE.Vector3(0, 0, 0) +const VIEW_DISTANCE = 10 + +type ViewPreset = 'front' | 'back' | 'top' | 'bottom' | 'left' | 'right' + +const VIEW_POSITIONS: Record = { + front: new THREE.Vector3(0, 0, VIEW_DISTANCE), + back: new THREE.Vector3(0, 0, -VIEW_DISTANCE), + top: new THREE.Vector3(0, VIEW_DISTANCE, 0), + bottom: new THREE.Vector3(0, -VIEW_DISTANCE, 0), + left: new THREE.Vector3(-VIEW_DISTANCE, 0, 0), + right: new THREE.Vector3(VIEW_DISTANCE, 0, 0), +} function initScene() { if (!containerRef.value) return @@ -169,6 +181,16 @@ function resetView() { controls.update() } +function setViewPreset(preset: ViewPreset) { + const position = VIEW_POSITIONS[preset] + camera.position.copy(position) + controls.target.set(0, 0, 0) + camera.up.set(0, 1, 0) + if (preset === 'top') camera.up.set(0, 0, -1) + if (preset === 'bottom') camera.up.set(0, 0, 1) + controls.update() +} + function cleanup() { if (animationFrameId) { cancelAnimationFrame(animationFrameId) @@ -199,6 +221,7 @@ onBeforeUnmount(() => { defineExpose({ fitToSelection, resetView, + setViewPreset, })