UNPKG

4.55 kBJavaScriptView Raw
1import { EventGroup } from './EventGroup';
2import { findScrollableParent } from './scroll';
3import { getRect } from './dom/getRect';
4var SCROLL_ITERATION_DELAY = 16;
5var SCROLL_GUTTER = 100;
6var MAX_SCROLL_VELOCITY = 15;
7/**
8 * AutoScroll simply hooks up mouse events given a parent element, and scrolls the container
9 * up/down depending on how close the mouse is to the top/bottom of the container.
10 *
11 * Once you don't want autoscroll any more, just dispose the helper and it will unhook events.
12 *
13 * @public
14 * {@docCategory AutoScroll}
15 */
16var AutoScroll = /** @class */ (function () {
17 function AutoScroll(element) {
18 this._events = new EventGroup(this);
19 this._scrollableParent = findScrollableParent(element);
20 this._incrementScroll = this._incrementScroll.bind(this);
21 this._scrollRect = getRect(this._scrollableParent);
22 // eslint-disable-next-line @typescript-eslint/no-explicit-any
23 if (this._scrollableParent === window) {
24 this._scrollableParent = document.body;
25 }
26 if (this._scrollableParent) {
27 this._events.on(window, 'mousemove', this._onMouseMove, true);
28 this._events.on(window, 'touchmove', this._onTouchMove, true);
29 }
30 }
31 AutoScroll.prototype.dispose = function () {
32 this._events.dispose();
33 this._stopScroll();
34 };
35 AutoScroll.prototype._onMouseMove = function (ev) {
36 this._computeScrollVelocity(ev);
37 };
38 AutoScroll.prototype._onTouchMove = function (ev) {
39 if (ev.touches.length > 0) {
40 this._computeScrollVelocity(ev);
41 }
42 };
43 AutoScroll.prototype._computeScrollVelocity = function (ev) {
44 if (!this._scrollRect) {
45 return;
46 }
47 var clientX;
48 var clientY;
49 if ('clientX' in ev) {
50 clientX = ev.clientX;
51 clientY = ev.clientY;
52 }
53 else {
54 clientX = ev.touches[0].clientX;
55 clientY = ev.touches[0].clientY;
56 }
57 var scrollRectTop = this._scrollRect.top;
58 var scrollRectLeft = this._scrollRect.left;
59 var scrollClientBottom = scrollRectTop + this._scrollRect.height - SCROLL_GUTTER;
60 var scrollClientRight = scrollRectLeft + this._scrollRect.width - SCROLL_GUTTER;
61 // variables to use for alternating scroll direction
62 var scrollRect;
63 var clientDirection;
64 var scrollClient;
65 // if either of these conditions are met we are scrolling vertically else horizontally
66 if (clientY < scrollRectTop + SCROLL_GUTTER || clientY > scrollClientBottom) {
67 clientDirection = clientY;
68 scrollRect = scrollRectTop;
69 scrollClient = scrollClientBottom;
70 this._isVerticalScroll = true;
71 }
72 else {
73 clientDirection = clientX;
74 scrollRect = scrollRectLeft;
75 scrollClient = scrollClientRight;
76 this._isVerticalScroll = false;
77 }
78 // calculate scroll velocity and direction
79 if (clientDirection < scrollRect + SCROLL_GUTTER) {
80 this._scrollVelocity = Math.max(-MAX_SCROLL_VELOCITY, -MAX_SCROLL_VELOCITY * ((SCROLL_GUTTER - (clientDirection - scrollRect)) / SCROLL_GUTTER));
81 }
82 else if (clientDirection > scrollClient) {
83 this._scrollVelocity = Math.min(MAX_SCROLL_VELOCITY, MAX_SCROLL_VELOCITY * ((clientDirection - scrollClient) / SCROLL_GUTTER));
84 }
85 else {
86 this._scrollVelocity = 0;
87 }
88 if (this._scrollVelocity) {
89 this._startScroll();
90 }
91 else {
92 this._stopScroll();
93 }
94 };
95 AutoScroll.prototype._startScroll = function () {
96 if (!this._timeoutId) {
97 this._incrementScroll();
98 }
99 };
100 AutoScroll.prototype._incrementScroll = function () {
101 if (this._scrollableParent) {
102 if (this._isVerticalScroll) {
103 this._scrollableParent.scrollTop += Math.round(this._scrollVelocity);
104 }
105 else {
106 this._scrollableParent.scrollLeft += Math.round(this._scrollVelocity);
107 }
108 }
109 this._timeoutId = setTimeout(this._incrementScroll, SCROLL_ITERATION_DELAY);
110 };
111 AutoScroll.prototype._stopScroll = function () {
112 if (this._timeoutId) {
113 clearTimeout(this._timeoutId);
114 delete this._timeoutId;
115 }
116 };
117 return AutoScroll;
118}());
119export { AutoScroll };
120//# sourceMappingURL=AutoScroll.js.map
\No newline at end of file