scroll-snap
Version:
Snap page when user stops scrolling, with a customizable configuration and a consistent cross browser behaviour
656 lines (639 loc) • 28.2 kB
JavaScript
/******/ // The require scope
/******/ var __webpack_require__ = {};
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
A: () => (/* binding */ createScrollSnap)
});
;// ./src/constants.ts
var TIMEOUT_MIN = 50;
var TIMEOUT_DEFAULT = 100;
var DURATION_DEFAULT = 300;
var THRESHOLD_DEFAULT = 0.2;
var SNAPSTOP_DEFAULT = false;
var SHOW_ARROWS_DEFAULT = false;
var ENABLE_KEYBOARD_DEFAULT = true;
var NOOP = function () { };
function easeInOutQuad(t) {
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
}
;// ./src/utils.ts
function parseSnapCoordinatesValue(x, y) {
var regex = /([+-]?(?=\.\d|\d)(?:\d+)?(?:\.?\d*)(?:[eE][+-]?\d+)?)(px|%|vw|vh)/;
var parsed = {
y: { value: 0, unit: 'px' },
x: { value: 0, unit: 'px' },
};
if (typeof y === 'number') {
parsed.y.value = y;
}
else {
var resultY = regex.exec(y);
if (resultY !== null) {
parsed.y = { value: Number(resultY[1]), unit: resultY[2] };
}
}
if (typeof x === 'number') {
parsed.x.value = x;
}
else {
var resultX = regex.exec(x);
if (resultX !== null) {
parsed.x = { value: Number(resultX[1]), unit: resultX[2] };
}
}
return parsed;
}
function getYSnapLength(obj, declaration) {
if (declaration.unit === 'vh') {
return ((Math.max(document.documentElement.clientHeight, window.innerHeight || 1) / 100) *
declaration.value);
}
else if (declaration.unit === '%') {
return (obj.clientHeight / 100) * declaration.value;
}
return declaration.value;
}
function getXSnapLength(obj, declaration) {
if (declaration.unit === 'vw') {
return ((Math.max(document.documentElement.clientWidth, window.innerWidth || 1) / 100) *
declaration.value);
}
else if (declaration.unit === '%') {
return (obj.clientWidth / 100) * declaration.value;
}
return declaration.value;
}
function stayInBounds(min, max, destined) {
return Math.max(Math.min(destined, max), min);
}
function roundToNearestSnapPoint(value, snapLength) {
var multiplier = 1000;
return Math.round((value * multiplier) / (snapLength * multiplier)) * snapLength;
}
;// ./src/arrows.ts
var __read = (undefined && undefined.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var ARROW_SVG = {
right: function (color) {
return "data:image/svg+xml;base64,".concat(btoa("<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"".concat(color, "\" d=\"M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\"/></svg>")));
},
left: function (color) {
return "data:image/svg+xml;base64,".concat(btoa("<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"".concat(color, "\" d=\"M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z\"/></svg>")));
},
up: function (color) {
return "data:image/svg+xml;base64,".concat(btoa("<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"".concat(color, "\" d=\"M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6 1.41-1.41z\"/></svg>")));
},
down: function (color) {
return "data:image/svg+xml;base64,".concat(btoa("<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"".concat(color, "\" d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\"/></svg>")));
},
};
function getBackgroundBrightness(element) {
var _a;
var bgColor = window.getComputedStyle(element).backgroundColor;
var rgb = ((_a = bgColor.match(/\d+/g)) === null || _a === void 0 ? void 0 : _a.map(Number)) || [255, 255, 255];
var brightness = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;
return brightness > 128 ? 'light' : 'dark';
}
var hoveredArrow = null;
function createArrowElements(target) {
var arrows = {
up: document.createElement('div'),
down: document.createElement('div'),
left: document.createElement('div'),
right: document.createElement('div'),
};
Object.entries(arrows).forEach(function (_a) {
var _b = __read(_a, 2), direction = _b[0], element = _b[1];
var theme = getBackgroundBrightness(target);
var iconColor = theme === 'light' ? '#1a1a1a' : '#ffffff';
var bgColor = theme === 'light' ? 'rgba(255, 255, 255, 0.8)' : 'rgba(0, 0, 0, 0.8)';
element.className = "scroll-snap-arrow scroll-snap-arrow-".concat(direction);
element.style.cssText = "\n position: fixed;\n width: 40px;\n height: 40px;\n background-size: 24px;\n background-position: center;\n background-repeat: no-repeat;\n opacity: 0;\n transition: opacity 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;\n cursor: pointer;\n z-index: 1000;\n background-image: url(".concat(ARROW_SVG[direction](iconColor), ");\n background-color: ").concat(bgColor, ";\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n border-radius: 50%;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n display: none;\n align-items: center;\n justify-content: center;\n pointer-events: auto;\n user-select: none;\n ");
element.addEventListener('mouseenter', function () {
if (element.style.display !== 'none') {
hoveredArrow = element;
element.style.opacity = '0.95';
element.style.transform = 'scale(1.05)';
element.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.2)';
}
});
element.addEventListener('mouseleave', function () {
if (element.style.display !== 'none') {
hoveredArrow = null;
element.style.opacity = '0.6';
element.style.transform = 'scale(1)';
element.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.15)';
}
});
});
return arrows;
}
function updateArrowsPosition(element, arrows, arrowContainer) {
if (!arrowContainer || !Object.keys(arrows).length)
return;
var rect = element.getBoundingClientRect();
var padding = 16;
var halfArrowSize = 20;
arrows.up.style.top = "".concat(rect.top + padding, "px");
arrows.up.style.left = "".concat(rect.left + rect.width / 2 - halfArrowSize, "px");
arrows.down.style.bottom = "".concat(window.innerHeight - rect.bottom + padding, "px");
arrows.down.style.left = "".concat(rect.left + rect.width / 2 - halfArrowSize, "px");
arrows.left.style.left = "".concat(rect.left + padding, "px");
arrows.left.style.top = "".concat(rect.top + rect.height / 2 - halfArrowSize, "px");
arrows.right.style.right = "".concat(window.innerWidth - rect.right + padding, "px");
arrows.right.style.top = "".concat(rect.top + rect.height / 2 - halfArrowSize, "px");
Object.values(arrows).forEach(function (arrow) {
var shouldDisplay = getArrowVisibility(element, arrow.className);
arrow.style.display = shouldDisplay ? 'flex' : 'none';
if (shouldDisplay) {
arrow.style.opacity = element.matches(':hover') || arrow === hoveredArrow ? '0.6' : '0';
}
});
}
function getArrowVisibility(element, className) {
if (className.includes('up')) {
return element.scrollTop > 0;
}
if (className.includes('down')) {
return element.scrollTop < element.scrollHeight - element.clientHeight;
}
if (className.includes('left')) {
return element.scrollLeft > 0;
}
if (className.includes('right')) {
return element.scrollLeft < element.scrollWidth - element.clientWidth;
}
return false;
}
;// ./src/animations.ts
function smoothScrollAxis(obj, end, axis, easing, duration, animationFrame, callback) {
var prop = axis === 'x' ? 'scrollLeft' : 'scrollTop';
if (animationFrame[axis]) {
cancelAnimationFrame(animationFrame[axis]);
}
var start = obj[prop];
var targetEnd = end[axis];
if (Math.abs(start - targetEnd) < 1 || isNaN(targetEnd)) {
callback();
return;
}
var startTime;
var lastPosition = start;
function step(timestamp) {
if (!startTime)
startTime = timestamp;
var elapsed = timestamp - startTime;
if (elapsed < duration) {
var nextPos = start + (targetEnd - start) * easing(elapsed / duration);
if (Math.abs(targetEnd - nextPos) < Math.abs(targetEnd - lastPosition)) {
obj[prop] = nextPos;
lastPosition = nextPos;
}
animationFrame[axis] = requestAnimationFrame(step);
}
else {
obj[prop] = targetEnd;
animationFrame[axis] = 0;
callback();
}
}
animationFrame[axis] = requestAnimationFrame(step);
}
function smoothScroll(obj, end, easing, duration, animationFrame, callback) {
var remaining = 2;
var onComplete = function () {
remaining--;
if (remaining === 0)
callback();
};
if (!isNaN(end.x)) {
smoothScrollAxis(obj, end, 'x', easing, duration, animationFrame, onComplete);
}
else {
remaining--;
}
if (!isNaN(end.y)) {
smoothScrollAxis(obj, end, 'y', easing, duration, animationFrame, onComplete);
}
else {
remaining--;
}
}
;// ./src/handlers.ts
function addEventHandler(element, event, handler, activeHandlers) {
element.addEventListener(event, handler);
activeHandlers.push({ element: element, event: event, handler: handler });
}
function cleanupEventHandlers(activeHandlers) {
activeHandlers.forEach(function (_a) {
var element = _a.element, event = _a.event, handler = _a.handler;
element.removeEventListener(event, handler);
});
activeHandlers.splice(0, activeHandlers.length);
}
function handleKeydown(e, target, enableKeyboard, scrollToDirection) {
var keyEvent = e;
if (!enableKeyboard || !target.contains(keyEvent.target))
return;
switch (keyEvent.key) {
case 'ArrowUp':
e.preventDefault();
scrollToDirection('up');
break;
case 'ArrowDown':
e.preventDefault();
scrollToDirection('down');
break;
case 'ArrowLeft':
e.preventDefault();
scrollToDirection('left');
break;
case 'ArrowRight':
e.preventDefault();
scrollToDirection('right');
break;
}
}
;// ./src/validation.ts
function validateSettings(settings) {
var snapDestinationX = settings.snapDestinationX, snapDestinationY = settings.snapDestinationY, timeout = settings.timeout, duration = settings.duration, threshold = settings.threshold, easing = settings.easing, snapStop = settings.snapStop, showArrows = settings.showArrows, enableKeyboard = settings.enableKeyboard;
if (snapDestinationX &&
typeof snapDestinationX !== 'string' &&
typeof snapDestinationX !== 'number') {
throw new Error("Settings property 'snapDestinationX' is not valid, expected STRING or NUMBER but found ".concat((typeof snapDestinationX).toUpperCase()));
}
if (snapDestinationY &&
typeof snapDestinationY !== 'string' &&
typeof snapDestinationY !== 'number') {
throw new Error("Settings property 'snapDestinationY' is not valid, expected STRING or NUMBER but found ".concat((typeof snapDestinationY).toUpperCase()));
}
if (timeout && (isNaN(timeout) || typeof timeout === 'boolean')) {
throw new Error("Optional settings property 'timeout' is not valid, expected NUMBER but found ".concat((typeof timeout).toUpperCase()));
}
if (timeout && timeout < TIMEOUT_MIN) {
console.warn("Timeout value less than ".concat(TIMEOUT_MIN, "ms may cause issues with momentum scrolling"));
}
if (duration && (isNaN(duration) || typeof duration === 'boolean')) {
throw new Error("Optional settings property 'duration' is not valid, expected NUMBER but found ".concat((typeof duration).toUpperCase()));
}
if (threshold && (isNaN(threshold) || typeof threshold === 'boolean')) {
throw new Error("Optional settings property 'threshold' is not valid, expected NUMBER but found ".concat((typeof threshold).toUpperCase()));
}
if (easing && typeof easing !== 'function') {
throw new Error("Optional settings property 'easing' is not valid, expected FUNCTION but found ".concat((typeof easing).toUpperCase()));
}
if (snapStop && typeof snapStop !== 'boolean') {
throw new Error("Optional settings property 'snapStop' is not valid, expected BOOLEAN but found ".concat((typeof snapStop).toUpperCase()));
}
if (showArrows && typeof showArrows !== 'boolean') {
throw new Error("Optional settings property 'showArrows' is not valid, expected BOOLEAN but found ".concat((typeof snapStop).toUpperCase()));
}
if (enableKeyboard && typeof enableKeyboard !== 'boolean') {
throw new Error("Optional settings property 'enableKeyboard' is not valid, expected BOOLEAN but found ".concat((typeof snapStop).toUpperCase()));
}
}
;// ./src/index.ts
var src_read = (undefined && undefined.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
function createScrollSnap(element, settings, callback) {
if (settings === void 0) { settings = {}; }
var onAnimationEnd = typeof callback === 'function' ? callback : NOOP;
var listenerElement;
var target;
var arrowContainer = null;
var scrollHandlerTimer;
var scrollSpeedTimer;
var scrollStart;
var speedDeltaX;
var speedDeltaY;
var snapLengthUnit;
var lastScrollValue = { x: 0, y: 0 };
var isControlledScroll = false;
var arrows = {};
var lastWindowWidth = window.innerWidth;
var lastWindowHeight = window.innerHeight;
var animating = { x: false, y: false };
var animationFrame = { x: 0, y: 0 };
var activeHandlers = [];
var activeDirections = { x: 0, y: 0 };
var lastValidSnapPoints = { x: 0, y: 0 };
validateSettings(settings);
var _a = settings.timeout, timeout = _a === void 0 ? TIMEOUT_DEFAULT : _a, _b = settings.duration, duration = _b === void 0 ? DURATION_DEFAULT : _b, _c = settings.threshold, threshold = _c === void 0 ? THRESHOLD_DEFAULT : _c, _d = settings.snapStop, snapStop = _d === void 0 ? SNAPSTOP_DEFAULT : _d, _e = settings.showArrows, showArrows = _e === void 0 ? SHOW_ARROWS_DEFAULT : _e, _f = settings.enableKeyboard, enableKeyboard = _f === void 0 ? ENABLE_KEYBOARD_DEFAULT : _f, _g = settings.easing, easing = _g === void 0 ? easeInOutQuad : _g;
function getLastValidSnapPoint(axis) {
return lastValidSnapPoints[axis];
}
function setLastValidSnapPoint(axis, value) {
lastValidSnapPoints[axis] = value;
}
function checkScrollSpeed(value, axis) {
var clear = function () {
lastScrollValue[axis] = null;
};
var newValue = value;
var delta = lastScrollValue[axis] !== null ? newValue - lastScrollValue[axis] : 0;
lastScrollValue[axis] = newValue;
scrollSpeedTimer && clearTimeout(scrollSpeedTimer);
scrollSpeedTimer = window.setTimeout(clear, 100);
return delta;
}
function bindElement(element) {
target = element;
listenerElement = element === document.documentElement ? window : element;
addEventHandler(listenerElement, 'scroll', startAnimation, activeHandlers);
snapLengthUnit = parseSnapCoordinatesValue(settings.snapDestinationX, settings.snapDestinationY);
lastValidSnapPoints = {
x: roundToNearestSnapPoint(element.scrollLeft, Math.round(getXSnapLength(element, snapLengthUnit.x))),
y: roundToNearestSnapPoint(element.scrollTop, Math.round(getYSnapLength(element, snapLengthUnit.y))),
};
}
function startAnimation() {
speedDeltaX = checkScrollSpeed(target.scrollLeft, 'x');
speedDeltaY = checkScrollSpeed(target.scrollTop, 'y');
if (speedDeltaX !== 0 && !animating.x) {
activeDirections.x = Math.sign(speedDeltaX);
}
if (speedDeltaY !== 0 && !animating.y) {
activeDirections.y = Math.sign(speedDeltaY);
}
if ((animating.x && animating.y) || (speedDeltaX === 0 && speedDeltaY === 0)) {
return;
}
handler(target);
}
function handler(target) {
if (animationFrame.x)
clearTimeout(animationFrame.x);
if (animationFrame.y)
clearTimeout(animationFrame.y);
if (scrollHandlerTimer) {
clearTimeout(scrollHandlerTimer);
}
else {
scrollStart = {
y: target.scrollTop,
x: target.scrollLeft,
};
}
scrollHandlerTimer = window.setTimeout(animationHandler, timeout);
}
function shouldMove(direction, currentPoint) {
if (isControlledScroll)
return true;
var fractionalPart = currentPoint % 1;
var normalizedFraction = fractionalPart >= 0 ? fractionalPart : 1 + fractionalPart;
return direction > 0 ? normalizedFraction > threshold : 1 - normalizedFraction > threshold;
}
function calculateAxisSnapPoint(axis, direction, snapLength) {
var prop = axis === 'x' ? 'scrollLeft' : 'scrollTop';
var size = axis === 'x' ? 'scrollWidth' : 'scrollHeight';
var clientSize = axis === 'x' ? 'clientWidth' : 'clientHeight';
var currentScroll = target[prop];
var lastValidPoint = getLastValidSnapPoint(axis);
if (Math.abs(currentScroll - lastValidPoint) < 1) {
currentScroll = lastValidPoint;
}
var currentPoint = currentScroll / snapLength;
if (isControlledScroll) {
var nextPoint_1 = Math.round(currentPoint) + direction;
return stayInBounds(0, target[size] - target[clientSize], nextPoint_1 * snapLength);
}
if (!shouldMove(direction, currentPoint)) {
return roundToNearestSnapPoint(currentScroll, snapLength);
}
var nextPoint;
if (snapStop) {
var currentRoundedPoint = Math.round(lastValidPoint / snapLength);
nextPoint = currentRoundedPoint + (direction > 0 ? 1 : -1);
}
else {
nextPoint = direction > 0 ? Math.ceil(currentPoint) : Math.floor(currentPoint);
}
return stayInBounds(0, target[size] - target[clientSize], nextPoint * snapLength);
}
function animationHandler() {
// If the scroll position has changed during the timeout, restart the timer
if (scrollStart.y === target.scrollTop && scrollStart.x === target.scrollLeft) {
return;
}
var direction = {
y: activeDirections.y,
x: activeDirections.x,
};
var snapPoints = {
x: calculateAxisSnapPoint('x', direction.x, Math.round(getXSnapLength(target, snapLengthUnit.x))),
y: calculateAxisSnapPoint('y', direction.y, Math.round(getYSnapLength(target, snapLengthUnit.y))),
};
if (activeDirections.x !== 0 && !animating.x) {
listenerElement.removeEventListener('scroll', startAnimation);
animating.x = true;
smoothScrollAxis(target, { x: snapPoints.x }, 'x', easing, duration, animationFrame, function () {
animating.x = false;
activeDirections.x = 0;
listenerElement.addEventListener('scroll', startAnimation);
setLastValidSnapPoint('x', snapPoints.x);
if (!animating.y)
onAnimationEnd();
});
}
if (activeDirections.y !== 0 && !animating.y) {
listenerElement.removeEventListener('scroll', startAnimation);
animating.y = true;
smoothScrollAxis(target, { y: snapPoints.y }, 'y', easing, duration, animationFrame, function () {
animating.y = false;
activeDirections.y = 0;
listenerElement.addEventListener('scroll', startAnimation);
setLastValidSnapPoint('y', snapPoints.y);
if (!animating.x)
onAnimationEnd();
});
}
}
function setupArrows() {
if (!showArrows)
return;
arrows = createArrowElements(target);
if (!arrowContainer) {
arrowContainer = document.createElement('div');
arrowContainer.style.cssText = "\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n z-index: 999;\n ";
document.body.appendChild(arrowContainer);
}
Object.entries(arrows).forEach(function (_a) {
var _b = src_read(_a, 2), direction = _b[0], arrow = _b[1];
arrow.onclick = function (e) {
e.stopPropagation();
scrollToDirection(direction);
};
arrowContainer.appendChild(arrow);
});
addEventHandler(element, 'mouseenter', function () { return updateArrowsPosition(element, arrows, arrowContainer); }, activeHandlers);
addEventHandler(element, 'mouseleave', function () {
Object.values(arrows).forEach(function (arrow) {
arrow.style.opacity = '0';
});
}, activeHandlers);
addEventHandler(element, 'scroll', function () { return updateArrowsPosition(element, arrows, arrowContainer); }, activeHandlers);
addEventHandler(window, 'scroll', function () { return updateArrowsPosition(element, arrows, arrowContainer); }, activeHandlers);
updateArrowsPosition(element, arrows, arrowContainer);
}
function scrollToDirection(direction) {
var axis = direction === 'up' || direction === 'down' ? 'y' : 'x';
if (animating[axis])
return;
var directionMap = {
up: { x: 0, y: -1 },
down: { x: 0, y: 1 },
left: { x: -1, y: 0 },
right: { x: 1, y: 0 },
};
isControlledScroll = true;
var snapLength = {
y: Math.round(getYSnapLength(target, snapLengthUnit.y)),
x: Math.round(getXSnapLength(target, snapLengthUnit.x)),
};
var delta = directionMap[direction];
var nextPoint = {
y: delta.y
? roundToNearestSnapPoint(target.scrollTop + delta.y * snapLength.y, snapLength.y)
: roundToNearestSnapPoint(target.scrollTop, snapLength.y),
x: delta.x
? roundToNearestSnapPoint(target.scrollLeft + delta.x * snapLength.x, snapLength.x)
: roundToNearestSnapPoint(target.scrollLeft, snapLength.x),
};
activeDirections[axis] = directionMap[direction][axis];
animating[axis] = true;
smoothScrollAxis(target, nextPoint, axis, easing, duration, animationFrame, function () {
animating[axis] = false;
activeDirections[axis] = 0;
isControlledScroll = false;
setLastValidSnapPoint(axis, nextPoint[axis]);
onAnimationEnd();
});
}
function handleResize() {
var oldSnapLength = {
y: Math.round(getYSnapLength(target, snapLengthUnit.y)),
x: Math.round(getXSnapLength(target, snapLengthUnit.x)),
};
var currentPoint = {
y: Math.round(target.scrollTop / oldSnapLength.y),
x: Math.round(target.scrollLeft / oldSnapLength.x),
};
requestAnimationFrame(function () {
var newSnapLength = {
y: Math.round(getYSnapLength(target, snapLengthUnit.y)),
x: Math.round(getXSnapLength(target, snapLengthUnit.x)),
};
var scrollTo = {
y: currentPoint.y * newSnapLength.y,
x: currentPoint.x * newSnapLength.x,
};
if (window.innerWidth !== lastWindowWidth || window.innerHeight !== lastWindowHeight) {
isControlledScroll = true;
smoothScrollAxis(target, scrollTo, 'x', easing, duration, animationFrame, function () {
smoothScrollAxis(target, scrollTo, 'y', easing, duration, animationFrame, function () {
isControlledScroll = false;
if (showArrows) {
updateArrowsPosition(element, arrows, arrowContainer);
}
});
});
lastWindowWidth = window.innerWidth;
lastWindowHeight = window.innerHeight;
}
});
}
function bind() {
bindElement(element);
if (enableKeyboard) {
if (!element.getAttribute('tabindex')) {
element.setAttribute('tabindex', '0');
}
addEventHandler(element, 'keydown', function (e) { return handleKeydown(e, target, enableKeyboard, scrollToDirection); }, activeHandlers);
}
addEventHandler(window, 'resize', handleResize, activeHandlers);
setupArrows();
}
function unbind() {
cleanupEventHandlers(activeHandlers);
activeHandlers = [];
if (showArrows) {
Object.values(arrows).forEach(function (arrow) {
arrow.onclick = null;
});
if (arrowContainer === null || arrowContainer === void 0 ? void 0 : arrowContainer.parentNode) {
arrowContainer.parentNode.removeChild(arrowContainer);
arrowContainer = null;
}
arrows = {};
}
if (animationFrame.x) {
cancelAnimationFrame(animationFrame.x);
animationFrame.x = 0;
}
if (animationFrame.y) {
cancelAnimationFrame(animationFrame.y);
animationFrame.y = 0;
}
animating = { x: false, y: false };
activeDirections = { x: 0, y: 0 };
listenerElement = null;
target = null;
}
bind();
return {
bind: bind,
unbind: unbind,
};
}
var __webpack_exports__default = __webpack_exports__.A;
export { __webpack_exports__default as default };
//# sourceMappingURL=scroll-snap.esm.js.map