Skip to content

Instantly share code, notes, and snippets.

@minikomi
Last active March 22, 2018 06:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save minikomi/3874a87c221e88cca79374637becdcbf to your computer and use it in GitHub Desktop.
Save minikomi/3874a87c221e88cca79374637becdcbf to your computer and use it in GitHub Desktop.
;; smooth scroll
(def SCROLL_DURATION 550)
(def HEADER_HEIGHT 85)
(defn quad-out [p] (- (* p (- p 2))))
(defonce SMOOTH_SCROLL_ACTIVE (atom false))
(defn cancel-scroll-animation []
(reset! SMOOTH_SCROLL_ACTIVE false)
(goog.events/unlisten js/window event-type/WHEEL cancel-scroll-animation)
(goog.events/unlisten js/window event-type/TOUCHMOVE cancel-scroll-animation)
(goog.events/unlisten js/window event-type/MOUSEDOWN cancel-scroll-animation))
(defn add-scroll-cancel []
(goog.events/listen js/window event-type/WHEEL cancel-scroll-animation)
(goog.events/listen js/window event-type/TOUCHMOVE cancel-scroll-animation)
(goog.events/listen js/window event-type/MOUSEDOWN cancel-scroll-animation))
(defn scroll-to [id]
(when-let [element (and (not @SMOOTH_SCROLL_ACTIVE)
(gdom/getElement id))]
(let [scroll-started (js/Date.)
original-scroll (.-y (gdom/getDocumentScroll))
Δscroll (- (.-top (.getBoundingClientRect element)) HEADER_HEIGHT)]
(when (< 0 Δscroll)
(reset! SMOOTH_SCROLL_ACTIVE true)
(letfn [(scroll-updater []
(when @SMOOTH_SCROLL_ACTIVE
(let [elapsed (- (js/Date.) scroll-started)
p (->> (/ elapsed SCROLL_DURATION)
(min 1.0)
(quad-out))
new-scroll (+ original-scroll (* p Δscroll))]
(.scrollTo js/window 0 new-scroll)
(if (<= 1.0 p)
(cancel-scroll-animation)
(js/requestAnimationFrame scroll-updater)))))]
(add-scroll-cancel)
(js/requestAnimationFrame scroll-updater))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment