diff --git a/assets/javascripts/lib/util.coffee b/assets/javascripts/lib/util.coffee index 836c3795..e5b177a6 100644 --- a/assets/javascripts/lib/util.coffee +++ b/assets/javascripts/lib/util.coffee @@ -223,6 +223,36 @@ $.lockScroll = (el, fn) -> fn() return +smoothScroll = smoothStart = smoothEnd = smoothDistance = smoothDuration = null + +$.smoothScroll = (el, end) -> + unless window.requestAnimationFrame + el.scrollTop = end + return + + smoothEnd = end + + if smoothScroll + newDistance = smoothEnd - smoothStart + smoothDuration += Math.min 400, Math.abs(smoothDistance - newDistance) + smoothDistance = newDistance + return + + smoothStart = el.scrollTop + smoothDistance = smoothEnd - smoothStart + smoothDuration = Math.min 400, Math.abs(smoothDistance) + startTime = Date.now() + + smoothScroll = -> + p = Math.min 1, (Date.now() - startTime) / smoothDuration + y = Math.max 0, Math.floor(smoothStart + smoothDistance * (if p < 0.5 then 2 * p * p else p * (4 - p * 2) - 1)) + el.scrollTop = y + if p is 1 + smoothScroll = null + else + requestAnimationFrame(smoothScroll) + requestAnimationFrame(smoothScroll) + # # Utilities # diff --git a/assets/javascripts/views/content/content.coffee b/assets/javascripts/views/content/content.coffee index a3a37c83..39285dbc 100644 --- a/assets/javascripts/views/content/content.coffee +++ b/assets/javascripts/views/content/content.coffee @@ -59,32 +59,36 @@ class app.views.Content extends app.View @scrollEl.scrollTop = value or 0 return + smoothScrollTo: (value) -> + $.smoothScroll @scrollEl, value or 0 + return + scrollBy: (n) -> - @scrollEl.scrollTop += n + @smoothScrollTo @scrollEl.scrollTop + n return scrollToTop: => - @scrollTo 0 + @smoothScrollTo 0 return scrollToBottom: => - @scrollTo @scrollEl.scrollHeight + @smoothScrollTo @scrollEl.scrollHeight return scrollStepUp: => - @scrollBy -50 + @scrollBy -80 return scrollStepDown: => - @scrollBy 50 + @scrollBy 80 return scrollPageUp: => - @scrollBy 80 - @scrollEl.clientHeight + @scrollBy 40 - @scrollEl.clientHeight return scrollPageDown: => - @scrollBy @scrollEl.clientHeight - 80 + @scrollBy @scrollEl.clientHeight - 40 return scrollToTarget: ->