1 | const raf = require('./utils/raf');
|
2 | const getWindow = require('./utils/window').getWindow;
|
3 | const is = require('./utils/is');
|
4 | const domUtils = require('./utils/domUtils');
|
5 | const Interaction = require('./Interaction');
|
6 | const defaultOptions = require('./defaultOptions');
|
7 |
|
8 | const autoScroll = {
|
9 | defaults: {
|
10 | enabled : false,
|
11 | container: null,
|
12 | margin : 60,
|
13 | speed : 300,
|
14 | },
|
15 |
|
16 | interaction: null,
|
17 | i: null,
|
18 | x: 0, y: 0,
|
19 |
|
20 | isScrolling: false,
|
21 | prevTime: 0,
|
22 |
|
23 | start: function (interaction) {
|
24 | autoScroll.isScrolling = true;
|
25 | raf.cancel(autoScroll.i);
|
26 |
|
27 | autoScroll.interaction = interaction;
|
28 | autoScroll.prevTime = new Date().getTime();
|
29 | autoScroll.i = raf.request(autoScroll.scroll);
|
30 | },
|
31 |
|
32 | stop: function () {
|
33 | autoScroll.isScrolling = false;
|
34 | raf.cancel(autoScroll.i);
|
35 | },
|
36 |
|
37 |
|
38 | scroll: function () {
|
39 | const options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll;
|
40 | const container = options.container || getWindow(autoScroll.interaction.element);
|
41 | const now = new Date().getTime();
|
42 |
|
43 | const dt = (now - autoScroll.prevTime) / 1000;
|
44 |
|
45 | const s = options.speed * dt;
|
46 |
|
47 | if (s >= 1) {
|
48 | if (is.window(container)) {
|
49 | container.scrollBy(autoScroll.x * s, autoScroll.y * s);
|
50 | }
|
51 | else if (container) {
|
52 | container.scrollLeft += autoScroll.x * s;
|
53 | container.scrollTop += autoScroll.y * s;
|
54 | }
|
55 |
|
56 | autoScroll.prevTime = now;
|
57 | }
|
58 |
|
59 | if (autoScroll.isScrolling) {
|
60 | raf.cancel(autoScroll.i);
|
61 | autoScroll.i = raf.request(autoScroll.scroll);
|
62 | }
|
63 | },
|
64 | check: function (interactable, actionName) {
|
65 | const options = interactable.options;
|
66 |
|
67 | return options[actionName].autoScroll && options[actionName].autoScroll.enabled;
|
68 | },
|
69 | onInteractionMove: function ({ interaction, pointer }) {
|
70 | if (!(interaction.interacting()
|
71 | && autoScroll.check(interaction.target, interaction.prepared.name))) {
|
72 | return;
|
73 | }
|
74 |
|
75 | if (interaction.simulation) {
|
76 | autoScroll.x = autoScroll.y = 0;
|
77 | return;
|
78 | }
|
79 |
|
80 | let top;
|
81 | let right;
|
82 | let bottom;
|
83 | let left;
|
84 |
|
85 | const options = interaction.target.options[interaction.prepared.name].autoScroll;
|
86 | const container = options.container || getWindow(interaction.element);
|
87 |
|
88 | if (is.window(container)) {
|
89 | left = pointer.clientX < autoScroll.margin;
|
90 | top = pointer.clientY < autoScroll.margin;
|
91 | right = pointer.clientX > container.innerWidth - autoScroll.margin;
|
92 | bottom = pointer.clientY > container.innerHeight - autoScroll.margin;
|
93 | }
|
94 | else {
|
95 | const rect = domUtils.getElementClientRect(container);
|
96 |
|
97 | left = pointer.clientX < rect.left + autoScroll.margin;
|
98 | top = pointer.clientY < rect.top + autoScroll.margin;
|
99 | right = pointer.clientX > rect.right - autoScroll.margin;
|
100 | bottom = pointer.clientY > rect.bottom - autoScroll.margin;
|
101 | }
|
102 |
|
103 | autoScroll.x = (right ? 1: left? -1: 0);
|
104 | autoScroll.y = (bottom? 1: top? -1: 0);
|
105 |
|
106 | if (!autoScroll.isScrolling) {
|
107 |
|
108 | autoScroll.margin = options.margin;
|
109 | autoScroll.speed = options.speed;
|
110 |
|
111 | autoScroll.start(interaction);
|
112 | }
|
113 | },
|
114 | };
|
115 |
|
116 | Interaction.signals.on('stop-active', function () {
|
117 | autoScroll.stop();
|
118 | });
|
119 |
|
120 | Interaction.signals.on('action-move', autoScroll.onInteractionMove);
|
121 |
|
122 | defaultOptions.perAction.autoScroll = autoScroll.defaults;
|
123 |
|
124 | module.exports = autoScroll;
|