         width (.-clientWidth element)
         height (.-clientHeight element)
         svg (setup-svg! selector width height)
-        current-state (atom (initial-state svg width height))]
+        current-state (atom (initial-state svg width height))
+        gesture-manager (hammer-manager svg)]
     (sync-graph! @current-state)
     (load-nodes "miserables.json" (fn [nodes]
                                     (swap-state! current-state assoc :nodes nodes)))
     (move-camera-on-arrow-keys! current-state)
-    (move-camera-on-pan! current-state)))
+    (move-camera-on-pan! gesture-manager current-state)
+    (move-camera-on-swipe! gesture-manager current-state)))

                         {:dx (- (.-x e1-center) (.-x e2-center))
                          :dy (- (.-y e1-center) (.-y e2-center))}))))))

(defn move-camera-on-pan! [current-state]
  (.subscribe
    (pan-deltas-observable (:svg @current-state))
    (fn [d] (let [{:keys [dx dy]} d] (move-camera! current-state dx dy)))))

;; Exported function to do magic


  (-> arrow-keys-observable
      (.flatMapLatest (fn [arrows] (if (empty? arrows)
                                     (.empty rx-observable)
                                     (-> tick-observable (.map (constantly arrows))))))
      (.subscribe
        (fn [arrows]
          (let [dx (+ (if (arrows :left) -10 0) (if (arrows :right) 10 0))
