import * as THREE from "three";
import { CameraControls } from "./controls/CameraControls.js";
class Controls {
/**
* Create Camera Controls.
* @param {string} type - Type of controls: "orbit", "trackball".
* @param {THREE.Camera} camera - The camera object.
* @param {THREE.Vector3} target - The lookAt target for the camera.
* @param {canvas} domElement - The dom element of the rendering canvas.
* @param {number} [rotateSpeed=1.0] - Speed for rotating.
* @param {number} [zoomSpeed=1.0] - Speed for zooming.
* @param {number} [panSpeed=1.0] - Speed for panning.
*/
constructor(
type,
camera,
target,
domElement,
rotateSpeed = 1.0,
zoomSpeed = 1.0,
panSpeed = 1.0,
) {
this.type = type;
this.camera = camera;
this.target = target;
this.target0 = target.slice();
this.domElement = domElement;
this.rotateSpeed = rotateSpeed;
this.zoomSpeed = zoomSpeed;
this.panSpeed = panSpeed;
switch (type) {
case "orbit":
this.initOrbitControls();
break;
case "trackball":
this.initTrackballControls();
break;
}
this.controls.target = new THREE.Vector3(...this.target);
this.controls.rotateSpeed = this.rotateSpeed;
this.controls.zoomSpeed = this.zoomSpeed;
this.controls.panSpeed = this.panSpeed;
this.currentUpdateCallback = null;
// save default view for reset
this.saveState();
this.update();
}
/**
* Remove assets and event handlers.
*/
dispose() {
this.controls.dispose();
this.controls = null;
}
/**
* Save state for reset.
*/
saveState() {
this.controls.saveState();
}
/**
* Initialize Trackball Controls.
* @param {boolean} [holroyd=true] - enable holroyd (non tumbling) mode.
**/
initTrackballControls(holroyd = true) {
this.controls = new CameraControls(this.camera, this.domElement);
this.controls.trackball = true;
this.setHolroydTrackball(holroyd);
}
/**
* Initialize Orbit Controls.
**/
initOrbitControls() {
this.controls = new CameraControls(this.camera, this.domElement);
}
/**
* Add an event listener callback for the "change" event.
* @param {callback} domEventCallback - the callback function.
**/
addChangeListener(callback) {
if (this.currentUpdateCallback == null) {
this.currentUpdateCallback = callback;
this.controls.addEventListener("change", callback);
}
}
/**
* Remove the event listener callback for the "change" event.
**/
removeChangeListener() {
if (this.currentUpdateCallback != null) {
this.controls.removeEventListener("change", this.currentUpdateCallback);
this.currentUpdateCallback = null;
}
}
/**
* Update controls after camera position, zoom or quaternion changes.
**/
update() {
this.controls.update();
}
/**
* Reset camera to initial (automatically saved) state of position, up, quaternion and zoom.
**/
reset() {
this.controls.reset();
}
/**
* Set the camera to be controlled.
* @param {THREE.Camera} camera - a threejs Camera object.
**/
setCamera(camera) {
this.controls.object = camera;
}
/**
* Change the trackball holroyd (non tumbling) flag.
* @param {boolean} flag - a threejs Camera object.
**/
setHolroydTrackball(flag) {
this.controls.holroyd = flag;
}
/**
* Get the lookAt target of the camera.
* @returns {THREE.Vector3} The lookAt target
**/
getTarget() {
return this.controls.target;
}
/**
* Get the initial zoom value of the camera.
**/
getZoom0() {
return this.controls.zoom0;
}
/**
* Get the lookAt target of the camera.
* @param {number[]} target - camera target as THREE.Vector3.
**/
setTarget(target) {
this.controls.target.copy(target);
}
/**
* Set the zoom speed.
* @param {number} val - the speed value.
**/
setZoomSpeed(val) {
this.controls.zoomSpeed = val;
}
/**
* Set the pan speed.
* @param {number} val - the speed value.
**/
setPanSpeed(val) {
this.controls.panSpeed = val;
}
/**
* Set the rotate speed.
* @param {number} val - the speed value.
**/
setRotateSpeed(val) {
this.controls.rotateSpeed = val;
}
/**
* Get reset location value.
* @function
* @returns {object} - target, position, quaternion, zoom as object.
*/
getResetLocation = () => {
return {
target0: this.controls.target0.clone(),
position0: this.controls.position0.clone(),
quaternion0: this.controls.quaternion0.clone(),
zoom0: this.controls.zoom0,
};
};
/**
* Set reset location value.
* @function
* @param {number[]} target - camera target as THREE.Vector3.
* @param {number[]} position - camera position as THREE.Vector3.
* @returns {number[]} camera rotation as THREE.Quaternion.
* @param {boolean} [notify=true] - whether to send notification or not.
*/
setResetLocation = (target, position, quaternion, zoom) => {
this.controls.target0.copy(target);
this.controls.position0.copy(position);
this.controls.quaternion0.copy(quaternion);
this.controls.zoom0 = zoom;
};
// Rotations for OrbitControls
/**
* Rotate camera up (OrbitControls only)
* @param {number} angle - the angle to rotate.
**/
rotateUp(angle) {
this.controls.rotateUp((-angle / 180) * Math.PI);
this.update();
}
/**
* Rotate camera left (OrbitControls only)
* @param {number} angle - the angle to rotate.
**/
rotateLeft(angle) {
this.controls.rotateLeft((angle / 180) * Math.PI);
this.update();
}
// Rotations for TrackballControls
/**
* Rotate camera around x-axis (TrackballControls only)
* @param {number} angle - the angle to rotate.
**/
rotateX(angle) {
this.controls.rotateX((angle / 180) * Math.PI);
this.update();
}
/**
* Rotate camera around y-axis (TrackballControls only)
* @param {number} angle - the angle to rotate.
**/
rotateY(angle) {
this.controls.rotateY((angle / 180) * Math.PI);
this.update();
}
/**
* Rotate camera around z-axis (TrackballControls only)
* @param {number} angle - the angle to rotate.
**/
rotateZ(angle) {
this.controls.rotateZ((angle / 180) * Math.PI);
this.update();
}
}
export { Controls };