scroll-into-view-rtl-support
Version:
ScrollIntoView with duration speed support
114 lines (113 loc) • 4.53 kB
JavaScript
;
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var compute_scroll_into_view_1 = require("./compute-scroll-into-view");
var scroll_into_view_if_needed_1 = __importDefault(require("./scroll-into-view-if-needed"));
// Memoize so we're much more friendly to non-dom envs
var memoizedNow;
var now = function () {
if (!memoizedNow) {
memoizedNow = 'performance' in window ? performance.now.bind(performance) : Date.now;
}
return memoizedNow();
};
function step(context) {
var time = now();
var elapsed = Math.min((time - context.startTime) / context.duration, 1);
// apply easing to elapsed time
var value = context.ease(elapsed);
var currentX = context.startX + (context.x - context.startX) * value;
var currentY = context.startY + (context.y - context.startY) * value;
context.method(currentX, currentY);
// scroll more if we have not reached our destination
if (currentX !== context.x || currentY !== context.y) {
requestAnimationFrame(function () { return step(context); });
}
else {
// If nothing left to scroll lets fire the callback
context.cb();
}
}
function smoothScroll(el, x, y, duration, ease, cb) {
if (duration === void 0) { duration = 600; }
if (ease === void 0) { ease = function (t) { return 1 + --t * t * t * t * t; }; }
var scrollable;
var startX;
var startY;
var method;
// define scroll context
scrollable = el;
startX = (0, compute_scroll_into_view_1.getScrollLeft)(el);
startY = el.scrollTop;
method = function (xValue, yValue) {
// use ceil to include the fractional part of the number for the scrolling
(0, compute_scroll_into_view_1.setScrollLeft)(el, Math.ceil(xValue));
el.scrollTop = Math.ceil(yValue);
};
// scroll looping over a frame if needed
step({
scrollable: scrollable,
method: method,
startTime: now(),
startX: startX,
startY: startY,
x: x,
y: y,
duration: duration,
ease: ease,
cb: cb,
});
}
var shouldSmoothScroll = function (options) {
return (options && !options.behavior) || options.behavior === 'smooth';
};
function scroll(target, options) {
var overrides = options || {};
if (shouldSmoothScroll(overrides)) {
return (0, scroll_into_view_if_needed_1.default)(target, {
block: overrides.block,
inline: overrides.inline,
scrollMode: overrides.scrollMode,
boundary: overrides.boundary,
behavior: function (actions) {
return Promise.all(actions.reduce(function (results, _a) {
var el = _a.el, left = _a.left, top = _a.top;
var startLeft = (0, compute_scroll_into_view_1.getScrollLeft)(el);
var startTop = el.scrollTop;
if (startLeft === left && startTop === top) {
return results;
}
if (el.tagName === 'HTML') {
return results;
}
return __spreadArray(__spreadArray([], results, true), [
new Promise(function (resolve) {
return smoothScroll(el, left, top, overrides.duration, overrides.ease, function () {
return resolve({
el: el,
left: [startLeft, el.scrollWidth - left],
top: [startTop, top],
});
});
}),
], false);
}, []));
},
});
}
return Promise.resolve((0, scroll_into_view_if_needed_1.default)(target, options));
}
// re-assign here makes the flowtype generation work
var smoothScrollIntoView = scroll;
exports.default = smoothScrollIntoView;