@@ -33,6 +33,7 @@ export class CameraController {
3333 private readonly camera : THREE . PerspectiveCamera ;
3434 private rotation : CameraRotation = { theta : 0 , phi : 0.5 } ;
3535 private distance : number = 10 ;
36+ private targetDistance : number = 10 ;
3637 private anchored : boolean = false ;
3738 private focusPoint : THREE . Vector3 | null = null ;
3839
@@ -41,6 +42,8 @@ export class CameraController {
4142 private readonly maxDistance : number = 50 ;
4243 private readonly rotationSpeed : number = 0.02 ;
4344 private readonly freeMoveSpeed : number = 0.5 ;
45+ private readonly zoomSpeed : number = 0.0025 ;
46+ private readonly zoomLerp : number = 0.18 ;
4447
4548 constructor ( aspectRatio : number ) {
4649 this . camera = new THREE . PerspectiveCamera ( 75 , aspectRatio , 0.1 , 10000 ) ;
@@ -75,8 +78,11 @@ export class CameraController {
7578 }
7679
7780 public adjustZoom ( delta : number ) : void {
78- this . distance += delta ;
79- this . distance = Math . max ( this . minDistance , Math . min ( this . maxDistance , this . distance ) ) ;
81+ // Use exponential scaling for consistent feel across small/large wheel deltas:
82+ // delta > 0 => zoom out (increase distance), delta < 0 => zoom in.
83+ const factor = Math . exp ( delta * this . zoomSpeed ) ;
84+ this . targetDistance *= factor ;
85+ this . targetDistance = Math . max ( this . minDistance , Math . min ( this . maxDistance , this . targetDistance ) ) ;
8086 }
8187
8288 public adjustRotation ( deltaTheta : number , deltaPhi : number ) : void {
@@ -90,6 +96,9 @@ export class CameraController {
9096 public update ( player : Player | null , input : InputManager ) : void {
9197 if ( ! player ) return ;
9298
99+ // Smoothly approach the zoom target each frame.
100+ this . distance = THREE . MathUtils . lerp ( this . distance , this . targetDistance , this . zoomLerp ) ;
101+
93102 // Handle arrow keys and Q/E for horizontal camera rotation
94103 if ( input . isKeyPressed ( 'arrowleft' ) || input . isKeyPressed ( 'q' ) ) {
95104 this . rotation . theta += this . rotationSpeed ;
@@ -159,5 +168,8 @@ export class CameraController {
159168 public setInitialPosition ( player : Player ) : void {
160169 const pos = player . mesh . position ;
161170 this . camera . position . set ( pos . x , pos . y + 5 , pos . z + 10 ) ;
171+ // Keep zoom state consistent with initial placement.
172+ this . distance = this . camera . position . distanceTo ( new THREE . Vector3 ( pos . x , pos . y , pos . z ) ) ;
173+ this . targetDistance = this . distance ;
162174 }
163175}
0 commit comments