1- // Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.
2-
31import { GeometryNode , ICameraController , Point , ShapeType } from "chili-core" ;
42import { Box3 , Matrix4 , OrthographicCamera , PerspectiveCamera , Sphere , Vector3 } from "three" ;
53import { ThreeGeometry } from "./threeGeometry" ;
64import { ThreeHelper } from "./threeHelper" ;
75import { ThreeView } from "./threeView" ;
8- import { ThreeVisualContext } from "./threeVisualContext" ;
6+ import { ThreeVisualContext from "./threeVisualContext" ;
97
108const DegRad = Math . PI / 180.0 ;
119
@@ -18,6 +16,9 @@ export class CameraController implements ICameraController {
1816 private _fov : number = 50 ;
1917 private _rotateCenter : Vector3 | undefined ;
2018 private _camera : PerspectiveCamera | OrthographicCamera ;
19+ private isPanning : boolean = false ;
20+ private isRotating : boolean = false ;
21+ private lastMousePosition : { x : number ; y : number } = { x : 0 , y : 0 } ;
2122
2223 private _cameraType : "perspective" | "orthographic" = "orthographic" ;
2324 get cameraType ( ) : "perspective" | "orthographic" {
@@ -45,6 +46,7 @@ export class CameraController implements ICameraController {
4546
4647 constructor ( readonly view : ThreeView ) {
4748 this . _camera = this . newCamera ( ) ;
49+ this . addEventListeners ( ) ;
4850 }
4951
5052 private newCamera ( ) {
@@ -53,6 +55,50 @@ export class CameraController implements ICameraController {
5355 : new OrthographicCamera ( - 0.5 , 0.5 , 0.5 , - 0.5 , 0.1 , 1e4 ) ;
5456 }
5557
58+ private addEventListeners ( ) {
59+ this . view . element . addEventListener ( 'mousedown' , this . onMouseDown . bind ( this ) ) ;
60+ this . view . element . addEventListener ( 'mouseup' , this . onMouseUp . bind ( this ) ) ;
61+ this . view . element . addEventListener ( 'mousemove' , this . onMouseMove . bind ( this ) ) ;
62+ this . view . element . addEventListener ( 'wheel' , this . onMouseWheel . bind ( this ) ) ;
63+ }
64+
65+ private onMouseDown ( event : MouseEvent ) {
66+ if ( event . button === 1 ) { // Middle mouse button
67+ if ( event . shiftKey ) {
68+ this . isRotating = true ;
69+ this . startRotate ( event . clientX , event . clientY ) ;
70+ } else {
71+ this . isPanning = true ;
72+ }
73+ this . lastMousePosition = { x : event . clientX , y : event . clientY } ;
74+ }
75+ }
76+
77+ private onMouseUp ( event : MouseEvent ) {
78+ if ( event . button === 1 ) { // Middle mouse button
79+ this . isPanning = false ;
80+ this . isRotating = false ;
81+ }
82+ }
83+
84+ private onMouseMove ( event : MouseEvent ) {
85+ if ( this . isPanning ) {
86+ let dx = event . clientX - this . lastMousePosition . x ;
87+ let dy = event . clientY - this . lastMousePosition . y ;
88+ this . pan ( dx , dy ) ;
89+ this . lastMousePosition = { x : event . clientX , y : event . clientY } ;
90+ } else if ( this . isRotating ) {
91+ let dx = event . clientX - this . lastMousePosition . x ;
92+ let dy = event . clientY - this . lastMousePosition . y ;
93+ this . rotate ( dx , dy ) ;
94+ this . lastMousePosition = { x : event . clientX , y : event . clientY } ;
95+ }
96+ }
97+
98+ private onMouseWheel ( event : WheelEvent ) {
99+ this . zoom ( event . clientX , event . clientY , event . deltaY ) ;
100+ }
101+
56102 pan ( dx : number , dy : number ) : void {
57103 let ratio = 0.0015 * this . _target . distanceTo ( this . _position ) ;
58104 let direction = this . _target . clone ( ) . sub ( this . _position ) . normalize ( ) ;
0 commit comments