The source code is here.

I implemented typical RTS controls. Pan left/right/up/down, zoom in/out and also arcball rotation. Worth noting is that you should only move the camera for each requestAnimationFrame to make smoother animations, not on the keypress events themselves. The more interesting implementation was arcball rotation, which I think I got from here:

(defn arc-ball-rotation-left-right
  [state sign]
  (let
    [camera (:camera state)
     focus (scene/get-camera-focus camera 0 0)
     axis (-> camera .-position .clone)
     _ (-> axis (.sub focus))
     _ (-> axis .-y (set! 0))
     _ (-> axis .normalize)
     old (-> camera .-position .clone)
     config (:config state)
     rotate-speed (get-in config [:controls :rotate-speed])
     rotate-speed (* sign rotate-speed)
     rotate-speed (* rotate-speed (get-elapsed state))]

    (-> camera .-position (.applyAxisAngle axis rotate-speed))
    (-> camera .-position .-y (set! (-> old .-y)))
    (-> camera (.lookAt focus))))


(defn arc-ball-rotation-up-down
  [state sign]
  (let
    [camera (:camera state)
     focus (scene/get-camera-focus camera 0 0)
     axis (-> camera .-position .clone)
     _ (-> axis (.sub focus))
     offset axis
     config (:config state)
     rotate-speed (get-in config [:controls :rotate-speed])
     rotate-speed (* sign rotate-speed)
     rotate-speed (* rotate-speed (get-elapsed state))
     theta (atan2 (-> offset .-x) (-> offset .-z))
     xzlen (sqrt (+ (square (-> offset .-x)) (square (-> offset .-z))))
     min-polar-angle 0.1
     max-polar-angle (- (/ pi 2) (/ pi 16))
     phi (atan2 xzlen (-> offset .-y))
     phi (+ phi rotate-speed)
     phi (min max-polar-angle phi)
     phi (max min-polar-angle phi)
     radius (-> offset .length)
     x (* radius (sin phi) (sin theta))
     y (* radius (cos phi))
     z (* radius (sin phi) (cos theta))
     _ (-> offset (.set x y z))]

    (-> camera .-position (.copy focus))
    (-> camera .-position (.add offset))
    (-> camera (.lookAt focus))))