smooth-scrollbar
Version:
Customize scrollbar in modern browsers with smooth scrolling experience.
88 lines • 3.16 kB
JavaScript
import clamp from 'lodash.clamp';
import { eventScope, getPosition, } from '../utils/';
export function selectHandler(scrollbar) {
var addEvent = eventScope(scrollbar);
var containerEl = scrollbar.containerEl, contentEl = scrollbar.contentEl;
var isSelected = false;
var isContextMenuOpened = false; // flag to prevent selection when context menu is opened
var animationID;
function scroll(_a) {
var x = _a.x, y = _a.y;
if (!x && !y)
return;
var offset = scrollbar.offset, limit = scrollbar.limit;
// DISALLOW delta transformation
scrollbar.setMomentum(clamp(offset.x + x, 0, limit.x) - offset.x, clamp(offset.y + y, 0, limit.y) - offset.y);
animationID = requestAnimationFrame(function () {
scroll({ x: x, y: y });
});
}
addEvent(window, 'mousemove', function (evt) {
if (!isSelected)
return;
cancelAnimationFrame(animationID);
var dir = calcMomentum(scrollbar, evt);
scroll(dir);
});
// prevent scrolling when context menu is opened
// NOTE: `contextmenu` event may be fired
// 1. BEFORE `selectstart`: when user right-clicks on the text content -> prevent future scrolling,
// 2. AFTER `selectstart`: when user right-clicks on the blank area -> cancel current scrolling,
// so we need to both set the flag and cancel current scrolling
addEvent(contentEl, 'contextmenu', function () {
// set the flag to prevent future scrolling
isContextMenuOpened = true;
// stop current scrolling
cancelAnimationFrame(animationID);
isSelected = false;
});
// reset context menu flag on mouse down
// to ensure the scrolling is allowed in the next selection
addEvent(contentEl, 'mousedown', function () {
isContextMenuOpened = false;
});
addEvent(contentEl, 'selectstart', function () {
if (isContextMenuOpened) {
return;
}
cancelAnimationFrame(animationID);
isSelected = true;
});
addEvent(window, 'mouseup blur', function () {
cancelAnimationFrame(animationID);
isSelected = false;
isContextMenuOpened = false;
});
// patch for touch devices
addEvent(containerEl, 'scroll', function (evt) {
evt.preventDefault();
containerEl.scrollTop = containerEl.scrollLeft = 0;
});
}
function calcMomentum(scrollbar, evt) {
var _a = scrollbar.bounding, top = _a.top, right = _a.right, bottom = _a.bottom, left = _a.left;
var _b = getPosition(evt), x = _b.x, y = _b.y;
var res = {
x: 0,
y: 0,
};
var padding = 20;
if (x === 0 && y === 0)
return res;
if (x > right - padding) {
res.x = (x - right + padding);
}
else if (x < left + padding) {
res.x = (x - left - padding);
}
if (y > bottom - padding) {
res.y = (y - bottom + padding);
}
else if (y < top + padding) {
res.y = (y - top - padding);
}
res.x *= 2;
res.y *= 2;
return res;
}
//# sourceMappingURL=select.js.map