|
| 1 | +import warning from 'fbjs/lib/warning'; |
| 2 | +import { setTimeout } from 'requestanimationframe-timer'; |
| 3 | + |
| 4 | +export function animateScroll (id, animate) { |
| 5 | + const element = id ? document.getElementById(id) : document.body; |
| 6 | + warning(element, `Cannot find element: #${id}`); |
| 7 | + |
| 8 | + if (!element) { |
| 9 | + return null; |
| 10 | + } |
| 11 | + |
| 12 | + const { offset, duration, easing } = animate; |
| 13 | + const start = getScrollTop(); |
| 14 | + const to = getOffsetTop(element) + offset; |
| 15 | + const change = to - start; |
| 16 | + |
| 17 | + function animateFn (elapsedTime = 0) { |
| 18 | + const increment = 20; |
| 19 | + const elapsed = elapsedTime + increment; |
| 20 | + const position = easing(null, elapsed, start, change, duration); |
| 21 | + setScrollTop(position); |
| 22 | + elapsed < duration && |
| 23 | + setTimeout(function () { |
| 24 | + animateFn(elapsed); |
| 25 | + }, increment); |
| 26 | + } |
| 27 | + |
| 28 | + animateFn(); |
| 29 | + return id; |
| 30 | +} |
| 31 | + |
| 32 | +export function updateHistory (id) { |
| 33 | + window.location.hash = id; |
| 34 | +} |
| 35 | + |
| 36 | +function getScrollTop () { |
| 37 | + // like jQuery -> $('html, body').scrollTop |
| 38 | + return document.documentElement.scrollTop || document.body.scrollTop; |
| 39 | +} |
| 40 | + |
| 41 | +function setScrollTop (position) { |
| 42 | + document.documentElement.scrollTop = document.body.scrollTop = position; |
| 43 | +} |
| 44 | + |
| 45 | +function getOffsetTop (element) { |
| 46 | + const { top } = element.getBoundingClientRect(); |
| 47 | + return top + getScrollTop(); |
| 48 | +} |
0 commit comments