NGL@1.0.0-beta.7 Home Manual Reference Source Gallery

src/controls/mouse-actions.js

  1. /**
  2. * @file Mouse Actions
  3. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  4. * @private
  5. */
  6.  
  7. import { almostIdentity } from '../math/math-utils.js'
  8.  
  9. /**
  10. * Mouse actions provided as static methods
  11. */
  12. class MouseActions {
  13. /**
  14. * Zoom scene based on scroll-delta
  15. * @param {Stage} stage - the stage
  16. * @param {Number} delta - amount to zoom
  17. * @return {undefined}
  18. */
  19. static zoomScroll (stage, delta) {
  20. stage.trackballControls.zoom(delta)
  21. }
  22.  
  23. /**
  24. * Move near clipping plane based on scroll-delta
  25. * @param {Stage} stage - the stage
  26. * @param {Number} delta - amount to move clipping plane
  27. * @return {undefined}
  28. */
  29. static clipNearScroll (stage, delta) {
  30. const sp = stage.getParameters()
  31. stage.setParameters({ clipNear: sp.clipNear + delta / 10 })
  32. }
  33.  
  34. /**
  35. * Move focus planes based on scroll-delta
  36. * @param {Stage} stage - the stage
  37. * @param {Number} delta - amount to move focus planes
  38. * @return {undefined}
  39. */
  40. static focusScroll (stage, delta) {
  41. const sp = stage.getParameters()
  42. const focus = sp.clipNear * 2
  43. const sign = Math.sign(delta)
  44. const step = sign * almostIdentity((100 - focus) / 10, 5, 0.2)
  45. stage.setFocus(focus + step)
  46. }
  47.  
  48. /**
  49. * Change isolevel of volume surfaces based on scroll-delta
  50. * @param {Stage} stage - the stage
  51. * @param {Number} delta - amount to change isolevel
  52. * @return {undefined}
  53. */
  54. static isolevelScroll (stage, delta) {
  55. const d = Math.sign(delta) / 5
  56. stage.eachRepresentation(function (reprComp) {
  57. if (reprComp.repr.type !== 'surface') return
  58. const l = reprComp.getParameters().isolevel
  59. reprComp.setParameters({ isolevel: l + d })
  60. }, 'volume')
  61. }
  62.  
  63. /**
  64. * Pan scene based on mouse coordinate changes
  65. * @param {Stage} stage - the stage
  66. * @param {Number} dx - amount to pan in x direction
  67. * @param {Number} dy - amount to pan in y direction
  68. * @return {undefined}
  69. */
  70. static panDrag (stage, dx, dy) {
  71. stage.trackballControls.pan(dx, dy)
  72. }
  73.  
  74. /**
  75. * Rotate scene based on mouse coordinate changes
  76. * @param {Stage} stage - the stage
  77. * @param {Number} dx - amount to rotate in x direction
  78. * @param {Number} dy - amount to rotate in y direction
  79. * @return {undefined}
  80. */
  81. static rotateDrag (stage, dx, dy) {
  82. stage.trackballControls.rotate(dx, dy)
  83. }
  84.  
  85. /**
  86. * Zoom scene based on mouse coordinate changes
  87. * @param {Stage} stage - the stage
  88. * @param {Number} dx - amount to zoom
  89. * @param {Number} dy - amount to zoom
  90. * @return {undefined}
  91. */
  92. static zoomDrag (stage, dx, dy) {
  93. stage.trackballControls.zoom((dx + dy) / -2)
  94. }
  95.  
  96. /**
  97. * Zoom scene based on mouse coordinate changes and
  98. * move focus planes based on camera position (zoom)
  99. * @param {Stage} stage - the stage
  100. * @param {Number} dx - amount to zoom
  101. * @param {Number} dy - amount to zoom
  102. * @return {undefined}
  103. */
  104. static zoomFocusDrag (stage, dx, dy) {
  105. stage.trackballControls.zoom((dx + dy) / -2)
  106. const z = stage.viewer.camera.position.z
  107. stage.setFocus(100 - Math.abs(z / 8))
  108. }
  109.  
  110. /**
  111. * Pan picked component based on mouse coordinate changes
  112. * @param {Stage} stage - the stage
  113. * @param {Number} dx - amount to pan in x direction
  114. * @param {Number} dy - amount to pan in y direction
  115. * @return {undefined}
  116. */
  117. static panComponentDrag (stage, dx, dy) {
  118. stage.trackballControls.panComponent(dx, dy)
  119. }
  120.  
  121. /**
  122. * Pan picked atom based on mouse coordinate changes
  123. * @param {Stage} stage - the stage
  124. * @param {Number} dx - amount to pan in x direction
  125. * @param {Number} dy - amount to pan in y direction
  126. * @return {undefined}
  127. */
  128. static panAtomDrag (stage, dx, dy) {
  129. stage.trackballControls.panAtom(dx, dy)
  130. }
  131.  
  132. /**
  133. * Rotate picked component based on mouse coordinate changes
  134. * @param {Stage} stage - the stage
  135. * @param {Number} dx - amount to rotate in x direction
  136. * @param {Number} dy - amount to rotate in y direction
  137. * @return {undefined}
  138. */
  139. static rotateComponentDrag (stage, dx, dy) {
  140. stage.trackballControls.rotateComponent(dx, dy)
  141. }
  142.  
  143. /**
  144. * Move picked element to the center of the screen
  145. * @param {Stage} stage - the stage
  146. * @param {PickingProxy} pickingProxy - the picking data object
  147. * @return {undefined}
  148. */
  149. static movePick (stage, pickingProxy) {
  150. if (pickingProxy) {
  151. stage.animationControls.move(pickingProxy.position.clone())
  152. }
  153. }
  154.  
  155. /**
  156. * Show tooltip with information of picked element
  157. * @param {Stage} stage - the stage
  158. * @param {PickingProxy} pickingProxy - the picking data object
  159. * @return {undefined}
  160. */
  161. static tooltipPick (stage, pickingProxy) {
  162. const tt = stage.tooltip
  163. const sp = stage.getParameters()
  164. if (sp.tooltip && pickingProxy) {
  165. const mp = pickingProxy.mouse.position
  166. tt.innerText = pickingProxy.getLabel()
  167. tt.style.bottom = (window.innerHeight - mp.y + 3) + 'px'
  168. tt.style.left = (mp.x + 3) + 'px'
  169. tt.style.display = 'block'
  170. } else {
  171. tt.style.display = 'none'
  172. }
  173. }
  174. }
  175.  
  176. const MouseActionPresets = {
  177. default: [
  178. [ 'scroll', MouseActions.zoomScroll ],
  179. [ 'scroll-ctrl', MouseActions.clipNearScroll ],
  180. [ 'scroll-shift', MouseActions.focusScroll ],
  181. [ 'scroll-alt', MouseActions.isolevelScroll ],
  182.  
  183. [ 'drag-right', MouseActions.panDrag ],
  184. [ 'drag-left', MouseActions.rotateDrag ],
  185. [ 'drag-middle', MouseActions.zoomDrag ],
  186. [ 'drag-shift-right', MouseActions.zoomDrag ],
  187. [ 'drag-left+right', MouseActions.zoomDrag ],
  188. [ 'drag-ctrl-right', MouseActions.panComponentDrag ],
  189. [ 'drag-ctrl-left', MouseActions.rotateComponentDrag ],
  190.  
  191. [ 'clickPick-middle', MouseActions.movePick ],
  192. [ 'clickPick-shift-left', MouseActions.movePick ],
  193. [ 'hoverPick', MouseActions.tooltipPick ]
  194. ],
  195. pymol: [
  196. [ 'drag-left', MouseActions.rotateDrag ],
  197. [ 'drag-middle', MouseActions.panDrag ],
  198. [ 'drag-right', MouseActions.zoomDrag ],
  199. [ 'drag-shift-right', MouseActions.focusScroll ],
  200.  
  201. [ 'clickPick-ctrl+shift-middle', MouseActions.movePick ],
  202. [ 'hoverPick', MouseActions.tooltipPick ]
  203. ],
  204. coot: [
  205. [ 'scroll', MouseActions.isolevelScroll ],
  206.  
  207. [ 'drag-left', MouseActions.rotateDrag ],
  208. [ 'drag-middle', MouseActions.panDrag ],
  209. [ 'drag-ctrl-left', MouseActions.panDrag ],
  210. [ 'drag-right', MouseActions.zoomFocusDrag ],
  211. [ 'drag-ctrl-right', MouseActions.focusScroll ],
  212.  
  213. [ 'clickPick-middle', MouseActions.movePick ],
  214. [ 'hoverPick', MouseActions.tooltipPick ]
  215. ]
  216. }
  217.  
  218. export default MouseActions
  219.  
  220. export {
  221. MouseActionPresets
  222. }