baseframe-js
Version:
A suite of useful Javascript plugins and functions to help with Front-end Development on websites
65 lines (64 loc) • 2.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = smoothScroll;
var _cashDom = _interopRequireDefault(require("cash-dom"));
var _helpers = require("../util/helpers");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
// We need to throttle the checking of the previous scroll for a bug in IOS
// that says the previous pixel is the same as the current pixel.
// Q: Why do we need to check if the current pixel is the same as the previous?
// A: Because it could indicate that the element cannot be completely scrolled to
// and as a result we need to break this JS scroll
var checkIterationAmt = 3;
var activeScroll = false;
function smoothScroll(elemYPos) {
var _speed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100;
var afterScroll = arguments.length > 2 ? arguments[2] : undefined;
var afterScrollArgs = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
// If an active scroll is going exit until it's done
if (activeScroll) return;
var speed = _speed / 1000;
activeScroll = true;
var prevScroll = null,
animation = null,
userBreakScroll = false,
pxToCheckIteration = 0;
var targetIsAbove = elemYPos < (0, _helpers.docTop)();
(0, _cashDom["default"])(window).on('wheel.smoothScroll', function () {
userBreakScroll = true;
});
document.body.style.scrollBehavior = 'auto';
var scrollDone = function scrollDone() {
if (typeof afterScroll === 'function') {
afterScroll.apply(null, afterScrollArgs);
}
window.cancelAnimationFrame(animation);
activeScroll = false;
(0, _cashDom["default"])(window).off('wheel.smoothScroll');
document.body.style.scrollBehavior = null;
};
(function smoothScrollInner() {
var currentScroll = (0, _helpers.docTop)();
if (prevScroll === currentScroll || userBreakScroll) {
scrollDone();
return;
}
if (pxToCheckIteration === checkIterationAmt) {
prevScroll = currentScroll;
pxToCheckIteration = 0;
} else {
pxToCheckIteration++;
}
var isAtTarget = Math.floor(currentScroll - elemYPos) === 0;
var isPastTarget = targetIsAbove ? prevScroll < currentScroll : prevScroll > currentScroll;
if (!isAtTarget || !isPastTarget) {
animation = window.requestAnimationFrame(smoothScrollInner);
window.scroll(0, currentScroll + (elemYPos - currentScroll) * speed);
} else {
scrollDone();
return;
}
})();
}