import { clampTo } from '../cameraUtils' ; export default function createKeyboardController ( inputTarget , camera ) { let frameHandle = 0 ; let vx = 0 , vy = 0 , vz = 0 ; let dx = 0 , dy = 0 , dz = 0 ; let dPhi = 0 , vPhi = 0 ; let dRadius = 0 , vRadius = 0 ; let dIncline = 0 , vIncline = 0 ; listenToEvents ( ) ; return { dispose } ; function listenToEvents ( ) { if ( ! inputTarget . getAttribute ( 'tabindex' ) ) { inputTarget . setAttribute ( 'tabindex' , '0' ) ; } inputTarget . addEventListener ( 'keydown' , handleKeyDown ) ; inputTarget . addEventListener ( 'keyup' , handleKeyUp ) ; } function dispose ( ) { inputTarget . removeEventListener ( 'keydown' , handleKeyDown ) ; inputTarget . removeEventListener ( 'keyup' , handleKeyUp ) ; cancelAnimationFrame ( frameHandle ) ; } function frame ( ) { frameHandle = 0 ; let dampFactor = 0.9 ; let needRedraw = false ; dx = clampTo ( dx * dampFactor + vx , 0.5 , 0 ) ; dy = clampTo ( dy * dampFactor + vy , 0.5 , 0 ) ; dz = clampTo ( dz * dampFactor + vz , 0.5 , 0 ) ; if ( dx || dy ) { camera . panByAbsoluteOffset ( dx , dy ) ; needRedraw = true ; } if ( dz ) { camera . slideCenterUpDown ( dz ) ; needRedraw = true ; } dPhi = clampTo ( ( dPhi * dampFactor + vPhi / 2 ) , Math . PI / 360 , 0 ) ; dIncline = clampTo ( ( dIncline * dampFactor + vIncline / 6 ) , Math . PI / 360 , 0 ) ; if ( dPhi || dIncline ) { camera . rotateByAbsoluteOffset ( dPhi , dIncline ) ; needRedraw = true ; } dRadius = clampTo ( ( dRadius * 0.7 + vRadius ) , 0.5 , 0 ) ; if ( dRadius ) { let scaleFactor = Math . sign ( dRadius ) * 0.025 ; camera . zoomCenterByScaleFactor ( scaleFactor , 0 , 0 ) ; needRedraw = true ; } if ( needRedraw ) { camera . redraw ( ) ; processNextInput ( ) ; } } function processNextInput ( ) { if ( frameHandle ) return ; frameHandle = requestAnimationFrame ( frame ) ; } function handleKeyDown ( e ) { onKey ( e , 1 ) ; } function handleKeyUp ( e ) { onKey ( e , 0 ) ; } function onKey ( e , isDown ) { if ( isModifierKey ( e ) ) return ; switch ( e . which ) { case 81 : vPhi = - isDown ; break ; case 69 : vPhi = isDown ; break ; case 187 : vRadius = isDown ; break ; case 189 : vRadius = - isDown ; break ; case 82 : vIncline = isDown ; break ; case 70 : vIncline = - isDown ; break ; case 37 : case 65 : vx = isDown ; break ; case 39 : case 68 : vx = - isDown ; break ; case 38 : case 87 : vy = isDown ; break ; case 40 : case 83 : vy = - isDown ; break ; case 71 : vz = - isDown ; break ; case 84 : vz = isDown ; break ; } processNextInput ( ) ; } } function isModifierKey ( e ) { return e . altKey || e . ctrlKey || e . metaKey ; }