babylon.arcRotateCameraKeyboardMoveInput.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. module BABYLON {
  2. /**
  3. * Manage the keyboard inputs to control the movment of an arc rotate camera.
  4. * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
  5. */
  6. export class ArcRotateCameraKeyboardMoveInput implements ICameraInput<ArcRotateCamera> {
  7. /**
  8. * Defines the camera the input is attached to.
  9. */
  10. public camera: ArcRotateCamera;
  11. /**
  12. * Defines the list of key codes associated with the up action (increase alpha)
  13. */
  14. @serialize()
  15. public keysUp = [38];
  16. /**
  17. * Defines the list of key codes associated with the down action (decrease alpha)
  18. */
  19. @serialize()
  20. public keysDown = [40];
  21. /**
  22. * Defines the list of key codes associated with the left action (increase beta)
  23. */
  24. @serialize()
  25. public keysLeft = [37];
  26. /**
  27. * Defines the list of key codes associated with the right action (decrease beta)
  28. */
  29. @serialize()
  30. public keysRight = [39];
  31. /**
  32. * Defines the list of key codes associated with the reset action.
  33. * Those keys reset the camera to its last stored state (with the method camera.storeState())
  34. */
  35. @serialize()
  36. public keysReset = [220];
  37. /**
  38. * Defines the panning sensibility of the inputs.
  39. * (How fast is the camera paning)
  40. */
  41. @serialize()
  42. public panningSensibility: number = 50.0;
  43. /**
  44. * Defines the zooming sensibility of the inputs.
  45. * (How fast is the camera zooming)
  46. */
  47. @serialize()
  48. public zoomingSensibility: number = 25.0;
  49. /**
  50. * Defines wether maintaining the alt key down switch the movment mode from
  51. * orientation to zoom.
  52. */
  53. @serialize()
  54. public useAltToZoom: boolean = true;
  55. private _keys = new Array<number>();
  56. private _ctrlPressed: boolean;
  57. private _altPressed: boolean;
  58. private _onCanvasBlurObserver: Nullable<Observer<Engine>>;
  59. private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;
  60. private _engine: Engine;
  61. private _scene: Scene;
  62. /**
  63. * Attach the input controls to a specific dom element to get the input from.
  64. * @param element Defines the element the controls should be listened from
  65. * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
  66. */
  67. public attachControl(element: HTMLElement, noPreventDefault?: boolean): void {
  68. if (this._onCanvasBlurObserver) {
  69. return;
  70. }
  71. this._scene = this.camera.getScene();
  72. this._engine = this._scene.getEngine();
  73. this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(()=>{
  74. this._keys = [];
  75. });
  76. this._onKeyboardObserver = this._scene.onKeyboardObservable.add(info => {
  77. let evt = info.event;
  78. if (info.type === KeyboardEventTypes.KEYDOWN) {
  79. this._ctrlPressed = evt.ctrlKey;
  80. this._altPressed = evt.altKey;
  81. if (this.keysUp.indexOf(evt.keyCode) !== -1 ||
  82. this.keysDown.indexOf(evt.keyCode) !== -1 ||
  83. this.keysLeft.indexOf(evt.keyCode) !== -1 ||
  84. this.keysRight.indexOf(evt.keyCode) !== -1 ||
  85. this.keysReset.indexOf(evt.keyCode) !== -1) {
  86. var index = this._keys.indexOf(evt.keyCode);
  87. if (index === -1) {
  88. this._keys.push(evt.keyCode);
  89. }
  90. if (evt.preventDefault) {
  91. if (!noPreventDefault) {
  92. evt.preventDefault();
  93. }
  94. }
  95. }
  96. }
  97. else {
  98. if (this.keysUp.indexOf(evt.keyCode) !== -1 ||
  99. this.keysDown.indexOf(evt.keyCode) !== -1 ||
  100. this.keysLeft.indexOf(evt.keyCode) !== -1 ||
  101. this.keysRight.indexOf(evt.keyCode) !== -1 ||
  102. this.keysReset.indexOf(evt.keyCode) !== -1) {
  103. var index = this._keys.indexOf(evt.keyCode);
  104. if (index >= 0) {
  105. this._keys.splice(index, 1);
  106. }
  107. if (evt.preventDefault) {
  108. if (!noPreventDefault) {
  109. evt.preventDefault();
  110. }
  111. }
  112. }
  113. }
  114. });
  115. }
  116. /**
  117. * Detach the current controls from the specified dom element.
  118. * @param element Defines the element to stop listening the inputs from
  119. */
  120. public detachControl(element: Nullable<HTMLElement>) {
  121. if (this._scene) {
  122. if (this._onKeyboardObserver) {
  123. this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);
  124. }
  125. if (this._onCanvasBlurObserver) {
  126. this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);
  127. }
  128. this._onKeyboardObserver = null;
  129. this._onCanvasBlurObserver = null;
  130. }
  131. this._keys = [];
  132. }
  133. /**
  134. * Update the current camera state depending on the inputs that have been used this frame.
  135. * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
  136. */
  137. public checkInputs(): void {
  138. if (this._onKeyboardObserver){
  139. var camera = this.camera;
  140. for (var index = 0; index < this._keys.length; index++) {
  141. var keyCode = this._keys[index];
  142. if (this.keysLeft.indexOf(keyCode) !== -1) {
  143. if (this._ctrlPressed && this.camera._useCtrlForPanning) {
  144. camera.inertialPanningX -= 1 / this.panningSensibility;
  145. } else {
  146. camera.inertialAlphaOffset -= 0.01;
  147. }
  148. } else if (this.keysUp.indexOf(keyCode) !== -1) {
  149. if (this._ctrlPressed && this.camera._useCtrlForPanning) {
  150. camera.inertialPanningY += 1 / this.panningSensibility;
  151. }
  152. else if (this._altPressed && this.useAltToZoom) {
  153. camera.inertialRadiusOffset += 1 / this.zoomingSensibility;
  154. }
  155. else {
  156. camera.inertialBetaOffset -= 0.01;
  157. }
  158. } else if (this.keysRight.indexOf(keyCode) !== -1) {
  159. if (this._ctrlPressed && this.camera._useCtrlForPanning) {
  160. camera.inertialPanningX += 1 / this.panningSensibility;
  161. } else {
  162. camera.inertialAlphaOffset += 0.01;
  163. }
  164. } else if (this.keysDown.indexOf(keyCode) !== -1) {
  165. if (this._ctrlPressed && this.camera._useCtrlForPanning) {
  166. camera.inertialPanningY -= 1 / this.panningSensibility;
  167. }
  168. else if (this._altPressed && this.useAltToZoom) {
  169. camera.inertialRadiusOffset -= 1 / this.zoomingSensibility;
  170. }
  171. else {
  172. camera.inertialBetaOffset += 0.01;
  173. }
  174. } else if (this.keysReset.indexOf(keyCode) !== -1) {
  175. camera.restoreState();
  176. }
  177. }
  178. }
  179. }
  180. /**
  181. * Gets the class name of the current intput.
  182. * @returns the class name
  183. */
  184. public getClassName(): string {
  185. return "ArcRotateCameraKeyboardMoveInput";
  186. }
  187. /**
  188. * Get the friendly name associated with the input class.
  189. * @returns the input friendly name
  190. */
  191. public getSimpleName(): string{
  192. return "keyboard";
  193. }
  194. }
  195. (<any>CameraInputTypes)["ArcRotateCameraKeyboardMoveInput"] = ArcRotateCameraKeyboardMoveInput;
  196. }