@helpscout/hsds-react
Version:
React component library for Help Scout's Design System
99 lines (79 loc) • 2.92 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.smoothScrollTo = exports.easeInOutCubic = exports.linear = void 0;
var _node = require("./node");
var _lodash = _interopRequireDefault(require("lodash.isfunction"));
/* istanbul ignore file */
// Source:
// https://gist.github.com/gre/1650294
var linear = function linear(t) {
return t;
};
exports.linear = linear;
var easeInOutCubic = function easeInOutCubic(t) {
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
}; // Source
// https://jsfiddle.net/s61x7c4e/
//
// Testing:
// Note: This function cannot be tested in JSDOM. JSDOM lacks the
// necessary DOM node numbers (like scrollY or scrollTop) to test
// the calculations for this method. These numbers cannot be
// mocked/faked :(.
//
// To properly test this method, we'll need to leverage ACTUAL
// browser testing somehow (either in-browser or headless).
//
// For now, this method has been extensively tested manually
// within Storybook.
exports.easeInOutCubic = easeInOutCubic;
var smoothScrollTo = function smoothScrollTo(_ref) {
var node = _ref.node,
position = _ref.position,
duration = _ref.duration,
direction = _ref.direction,
callback = _ref.callback,
timingFunction = _ref.timingFunction;
var scrollNode = (0, _node.isNodeElement)(node) ? node : window;
var isWindow = scrollNode === window;
var scrollDuration = duration || 500;
var scrollDirection = direction || 'y';
var isHorizontalScroll = scrollDirection === 'x';
var scrollTimingFunction = timingFunction || easeInOutCubic;
var currentScrollPosition = isWindow ? window.scrollY : scrollNode.scrollTop;
if (isHorizontalScroll) {
currentScrollPosition = isWindow ? window.scrollX : scrollNode.scrollLeft;
}
var diff = currentScrollPosition - position;
var start;
if (!diff) return;
var step = function step(timestamp) {
if (!start) start = timestamp; // Elapsed miliseconds since start of scrolling.
var time = timestamp - start; // Get percent of completion in range [0, 1].
var percent = scrollTimingFunction(Math.min(time / scrollDuration, 1));
var scrollToPosition = currentScrollPosition - diff * percent;
if (node.scrollTo) {
if (isHorizontalScroll) {
node.scrollTo(scrollToPosition, 0);
} else {
node.scrollTo(0, scrollToPosition);
}
} else {
if (isHorizontalScroll) {
node.scrollLeft = scrollToPosition;
} else {
node.scrollTop = scrollToPosition;
}
} // Proceed with animation as long as we wanted it to.
if (time < scrollDuration) {
requestAnimationFrame(step);
} else {
if ((0, _lodash.default)(callback)) {
callback();
}
}
};
requestAnimationFrame(step);
};
exports.smoothScrollTo = smoothScrollTo;
;