@fastkit/scroller 0.16.0 → 0.17.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/scroller.d.mts +829 -0
- package/dist/scroller.mjs +1323 -1338
- package/dist/scroller.mjs.map +1 -1
- package/package.json +8 -8
- package/dist/scroller.d.ts +0 -820
package/dist/scroller.mjs
CHANGED
|
@@ -1,1416 +1,1401 @@
|
|
|
1
|
-
import { EV } from
|
|
2
|
-
import { visibilityManager } from
|
|
3
|
-
import { IN_WINDOW, removeUndef } from
|
|
4
|
-
import { TinyLogger } from
|
|
1
|
+
import { EV } from "@fastkit/ev";
|
|
2
|
+
import { visibilityManager } from "@fastkit/visibility";
|
|
3
|
+
import { IN_WINDOW, removeUndef } from "@fastkit/helpers";
|
|
4
|
+
import { TinyLogger } from "@fastkit/tiny-logger";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
//#region src/util.ts
|
|
7
7
|
function isDocumentElement(el) {
|
|
8
|
-
|
|
8
|
+
return el.constructor === HTMLHtmlElement;
|
|
9
9
|
}
|
|
10
|
-
function isBodyElement(el) {
|
|
11
|
-
|
|
10
|
+
function isBodyElement$1(el) {
|
|
11
|
+
return el.constructor === HTMLBodyElement;
|
|
12
12
|
}
|
|
13
|
-
var logger = new TinyLogger("scroller");
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/logger.ts
|
|
16
|
+
const logger = new TinyLogger("scroller");
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/prevent-scroll.ts
|
|
20
|
+
const SCROLLABLE_KEY_CODES = [
|
|
21
|
+
32,
|
|
22
|
+
33,
|
|
23
|
+
34,
|
|
24
|
+
35,
|
|
25
|
+
36,
|
|
26
|
+
37,
|
|
27
|
+
38,
|
|
28
|
+
39,
|
|
29
|
+
40
|
|
30
|
+
];
|
|
31
|
+
const eventListenerOptions = { passive: false };
|
|
32
|
+
const handleWheel = (e) => {
|
|
33
|
+
e.preventDefault();
|
|
22
34
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
el.scrollTo(el.__ps_ctx__.lockPosition.x, el.__ps_ctx__.lockPosition.y);
|
|
27
|
-
}
|
|
35
|
+
const handleScroll = (e) => {
|
|
36
|
+
const el = e.target;
|
|
37
|
+
if (el && el.__ps_ctx__) el.scrollTo(el.__ps_ctx__.lockPosition.x, el.__ps_ctx__.lockPosition.y);
|
|
28
38
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
if (SCROLLABLE_KEY_CODES.includes(e.which)) {
|
|
34
|
-
e.preventDefault();
|
|
35
|
-
}
|
|
39
|
+
const handleKeydown = (e) => {
|
|
40
|
+
if (e.target && ["INPUT", "TEXTAREA"].includes(e.target.tagName)) return;
|
|
41
|
+
if (SCROLLABLE_KEY_CODES.includes(e.which)) e.preventDefault();
|
|
36
42
|
};
|
|
37
43
|
function enableScroll(el) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
delete _el.__ps_ctx__;
|
|
44
|
+
const _el = el;
|
|
45
|
+
if (!_el.__ps_ctx__) return;
|
|
46
|
+
const { options } = _el.__ps_ctx__;
|
|
47
|
+
_el.removeEventListener("wheel", handleWheel, eventListenerOptions);
|
|
48
|
+
_el.removeEventListener("scroll", handleScroll, eventListenerOptions);
|
|
49
|
+
_el.removeEventListener("keydown", handleKeydown);
|
|
50
|
+
if (options.hideScrollbar) _el.style.overflow = _el.__ps_ctx__.overflowOrigin;
|
|
51
|
+
delete _el.__ps_ctx__;
|
|
48
52
|
}
|
|
49
53
|
function disableScroll(el, opts = {}) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
_el.addEventListener("wheel", handleWheel, eventListenerOptions);
|
|
69
|
-
_el.addEventListener("scroll", handleScroll, eventListenerOptions);
|
|
70
|
-
_el.addEventListener("keydown", handleKeydown);
|
|
54
|
+
const { hideScrollbar = false } = opts;
|
|
55
|
+
const _el = el;
|
|
56
|
+
if (_el.__ps_ctx__) return;
|
|
57
|
+
const options = { hideScrollbar };
|
|
58
|
+
_el.__ps_ctx__ = {
|
|
59
|
+
options,
|
|
60
|
+
el: _el,
|
|
61
|
+
overflowOrigin: _el.style.overflow,
|
|
62
|
+
lockPosition: {
|
|
63
|
+
x: _el.scrollLeft || _el.scrollX,
|
|
64
|
+
y: _el.scrollTop || _el.scrollY
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
if (options.hideScrollbar) _el.style.overflow = "hidden";
|
|
68
|
+
_el.addEventListener("wheel", handleWheel, eventListenerOptions);
|
|
69
|
+
_el.addEventListener("scroll", handleScroll, eventListenerOptions);
|
|
70
|
+
_el.addEventListener("keydown", handleKeydown);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/scroll/schemes.ts
|
|
75
|
+
const defaultBaseSettings = {
|
|
76
|
+
duration: 500,
|
|
77
|
+
easing: "ease",
|
|
78
|
+
cancelable: true
|
|
78
79
|
};
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
const defaultSettings = {
|
|
81
|
+
get container() {
|
|
82
|
+
return document.scrollingElement;
|
|
83
|
+
},
|
|
84
|
+
...defaultBaseSettings
|
|
84
85
|
};
|
|
85
86
|
|
|
86
|
-
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/bezier-easing.ts
|
|
87
89
|
function LinearEasing(x) {
|
|
88
|
-
|
|
90
|
+
return x;
|
|
89
91
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
} else {
|
|
106
|
-
\u03C6 = (q > 0 ? 0 : \u03C0) + angle;
|
|
107
|
-
}
|
|
108
|
-
return 2 * l * Math.cos(\u03C6 / 3) - d;
|
|
92
|
+
const { cbrt, sqrt, PI: π } = Math;
|
|
93
|
+
const x2t = (x, a, b, c, d) => {
|
|
94
|
+
const q = a + b * x;
|
|
95
|
+
const s = q ** 2 + c;
|
|
96
|
+
if (s > 0) {
|
|
97
|
+
const root = sqrt(s);
|
|
98
|
+
return cbrt(q + root) + cbrt(q - root) - d;
|
|
99
|
+
}
|
|
100
|
+
const l = cbrt(sqrt(q * q - s));
|
|
101
|
+
const angle = q ? Math.atan(sqrt(-s) / q) : -π / 2;
|
|
102
|
+
let φ;
|
|
103
|
+
if (b < 0) φ = (q > 0 ? 2 * π : π) - angle;
|
|
104
|
+
else if (d < 0) φ = (q > 0 ? 2 * π : -3 * π) + angle;
|
|
105
|
+
else φ = (q > 0 ? 0 : π) + angle;
|
|
106
|
+
return 2 * l * Math.cos(φ / 3) - d;
|
|
109
107
|
};
|
|
110
|
-
|
|
108
|
+
const Y = (t, ay, by, cy) => ((ay * t + 3 * by) * t + cy) * t;
|
|
111
109
|
function bezier(mX1, mY1, mX2, mY2) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return function BezierEasing(x) {
|
|
133
|
-
if (x === 0 || x === 1) {
|
|
134
|
-
return x;
|
|
135
|
-
}
|
|
136
|
-
return Y(X2T(x, e, o, w, d), ay, by, cy);
|
|
137
|
-
};
|
|
110
|
+
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) throw new Error("bezier x values must be in [0, 1] range");
|
|
111
|
+
if (mX1 === mY1 && mX2 === mY2) return LinearEasing;
|
|
112
|
+
const a = 6 * (3 * mX1 - 3 * mX2 + 1);
|
|
113
|
+
const b = 6 * (mX2 - 2 * mX1);
|
|
114
|
+
const c = 3 * mX1;
|
|
115
|
+
const a2 = a * a;
|
|
116
|
+
const b2 = b * b;
|
|
117
|
+
const d = b / a;
|
|
118
|
+
const e = 3 * b * c / a2 - b2 * b / (a2 * a);
|
|
119
|
+
const w1 = 2 * c / a - b2 / a2;
|
|
120
|
+
const w = w1 * w1 * w1;
|
|
121
|
+
const o = 3 / a;
|
|
122
|
+
const ay = 3 * mY1 - 3 * mY2 + 1;
|
|
123
|
+
const by = mY2 - 2 * mY1;
|
|
124
|
+
const cy = 3 * mY1;
|
|
125
|
+
const X2T = a ? x2t : LinearEasing;
|
|
126
|
+
return function BezierEasing(x) {
|
|
127
|
+
if (x === 0 || x === 1) return x;
|
|
128
|
+
return Y(X2T(x, e, o, w, d), ay, by, cy);
|
|
129
|
+
};
|
|
138
130
|
}
|
|
139
131
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/scroll/easings.ts
|
|
134
|
+
const easings = {
|
|
135
|
+
ease: [
|
|
136
|
+
.25,
|
|
137
|
+
.1,
|
|
138
|
+
.25,
|
|
139
|
+
1
|
|
140
|
+
],
|
|
141
|
+
linear: [
|
|
142
|
+
0,
|
|
143
|
+
0,
|
|
144
|
+
1,
|
|
145
|
+
1
|
|
146
|
+
],
|
|
147
|
+
"ease-in": [
|
|
148
|
+
.42,
|
|
149
|
+
0,
|
|
150
|
+
1,
|
|
151
|
+
1
|
|
152
|
+
],
|
|
153
|
+
"ease-out": [
|
|
154
|
+
0,
|
|
155
|
+
0,
|
|
156
|
+
.58,
|
|
157
|
+
1
|
|
158
|
+
],
|
|
159
|
+
"ease-in-out": [
|
|
160
|
+
.42,
|
|
161
|
+
0,
|
|
162
|
+
.58,
|
|
163
|
+
1
|
|
164
|
+
]
|
|
147
165
|
};
|
|
148
166
|
var easings_default = easings;
|
|
149
167
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region src/scroll/util.ts
|
|
170
|
+
function isBodyElement(el) {
|
|
171
|
+
return el.tagName.toLowerCase() === "body";
|
|
153
172
|
}
|
|
154
173
|
function getContainerDimension(el) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
height: el.clientHeight
|
|
167
|
-
};
|
|
174
|
+
if (isBodyElement(el)) {
|
|
175
|
+
const documentElement = document.documentElement;
|
|
176
|
+
return {
|
|
177
|
+
width: documentElement.clientWidth,
|
|
178
|
+
height: documentElement.clientWidth
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
width: el.clientWidth,
|
|
183
|
+
height: el.clientHeight
|
|
184
|
+
};
|
|
168
185
|
}
|
|
169
186
|
function $(selectorOrElement) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return document.querySelector(selectorOrElement);
|
|
187
|
+
if (typeof selectorOrElement !== "string") return selectorOrElement;
|
|
188
|
+
return document.querySelector(selectorOrElement);
|
|
173
189
|
}
|
|
174
190
|
function cumulativeOffset(element) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
191
|
+
let top = 0;
|
|
192
|
+
let left = 0;
|
|
193
|
+
let el = element;
|
|
194
|
+
while (el) {
|
|
195
|
+
top += el.offsetTop || 0;
|
|
196
|
+
left += el.offsetLeft || 0;
|
|
197
|
+
el = el.offsetParent;
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
top,
|
|
201
|
+
left
|
|
202
|
+
};
|
|
187
203
|
}
|
|
188
204
|
function on(element, events, handler, opts = { passive: false }) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
element.addEventListener(events[i], handler, opts);
|
|
192
|
-
}
|
|
205
|
+
if (!Array.isArray(events)) events = [events];
|
|
206
|
+
for (let i = 0; i < events.length; i++) element.addEventListener(events[i], handler, opts);
|
|
193
207
|
}
|
|
194
208
|
function off(element, events, handler) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
element.removeEventListener(events[i], handler);
|
|
198
|
-
}
|
|
209
|
+
if (!Array.isArray(events)) events = [events];
|
|
210
|
+
for (let i = 0; i < events.length; i++) element.removeEventListener(events[i], handler);
|
|
199
211
|
}
|
|
200
212
|
function error(message) {
|
|
201
|
-
|
|
213
|
+
return /* @__PURE__ */ new Error(`[scroll] ${message}`);
|
|
202
214
|
}
|
|
203
215
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
216
|
+
//#endregion
|
|
217
|
+
//#region src/scroll/scroll-by-internal.ts
|
|
218
|
+
const abortEvents = [
|
|
219
|
+
"mousedown",
|
|
220
|
+
"wheel",
|
|
221
|
+
"DOMMouseScroll",
|
|
222
|
+
"mousewheel",
|
|
223
|
+
"keyup",
|
|
224
|
+
"touchmove"
|
|
212
225
|
];
|
|
213
226
|
function scroll(diffX, diffY, options = {}, _computedValues) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
function topLeft(top, left) {
|
|
323
|
-
if (y) $container.scrollTop = top;
|
|
324
|
-
if (x) $container.scrollLeft = left;
|
|
325
|
-
}
|
|
326
|
-
function done() {
|
|
327
|
-
if (!callbackValues.aborted) topLeft(targetY, targetX);
|
|
328
|
-
timeStart = 0;
|
|
329
|
-
off($container, abortEvents, abortFn);
|
|
330
|
-
callbackValues.progress = 1;
|
|
331
|
-
doneResolve();
|
|
332
|
-
if (!callbackValues.aborted && onDone) onDone(callbackValues);
|
|
333
|
-
}
|
|
227
|
+
let $container;
|
|
228
|
+
let initialX;
|
|
229
|
+
let initialY;
|
|
230
|
+
let targetX;
|
|
231
|
+
let targetY;
|
|
232
|
+
const _options = {
|
|
233
|
+
...defaultSettings,
|
|
234
|
+
...removeUndef(options)
|
|
235
|
+
};
|
|
236
|
+
const { container, duration, easing, cancelable, onProgress, onCancel, onDone } = _options;
|
|
237
|
+
const x = diffX !== 0;
|
|
238
|
+
const y = diffY !== 0;
|
|
239
|
+
if (_computedValues) {
|
|
240
|
+
$container = _computedValues.$container;
|
|
241
|
+
initialX = _computedValues.initialX;
|
|
242
|
+
initialY = _computedValues.initialY;
|
|
243
|
+
targetX = _computedValues.targetX;
|
|
244
|
+
targetY = _computedValues.targetY;
|
|
245
|
+
} else {
|
|
246
|
+
$container = $(container);
|
|
247
|
+
if (!$container) throw error(`missing container ${container}`);
|
|
248
|
+
initialX = $container.scrollLeft;
|
|
249
|
+
initialY = $container.scrollTop;
|
|
250
|
+
targetX = initialX + diffX;
|
|
251
|
+
targetY = initialY + diffY;
|
|
252
|
+
}
|
|
253
|
+
const { scrollWidth, scrollHeight } = $container;
|
|
254
|
+
const { width, height } = getContainerDimension($container);
|
|
255
|
+
const overflowX = targetX + width - scrollWidth;
|
|
256
|
+
const overflowY = targetY + height - scrollHeight;
|
|
257
|
+
if (overflowX > 0) {
|
|
258
|
+
diffX -= overflowX;
|
|
259
|
+
targetX -= overflowX;
|
|
260
|
+
}
|
|
261
|
+
if (overflowY > 0) {
|
|
262
|
+
diffY -= overflowY;
|
|
263
|
+
targetY -= overflowY;
|
|
264
|
+
}
|
|
265
|
+
let doneResolver;
|
|
266
|
+
let timeStart = 0;
|
|
267
|
+
let timeElapsed;
|
|
268
|
+
const callbackValues = {
|
|
269
|
+
container: $container,
|
|
270
|
+
progress: 0,
|
|
271
|
+
aborted: false,
|
|
272
|
+
abortEventSource: null
|
|
273
|
+
};
|
|
274
|
+
const result = {
|
|
275
|
+
cancel: canceller,
|
|
276
|
+
promise: new Promise((resolve) => {
|
|
277
|
+
doneResolver = resolve;
|
|
278
|
+
}),
|
|
279
|
+
plans: {
|
|
280
|
+
x: diffX,
|
|
281
|
+
y: diffY
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
if (diffY === 0 && diffX === 0 || !!$container.__ps_ctx__) return initialAbort();
|
|
285
|
+
let easingValues;
|
|
286
|
+
if (!easing) easingValues = easings_default.ease;
|
|
287
|
+
else if (typeof easing === "string") easingValues = easings_default[_options.easing];
|
|
288
|
+
else easingValues = easing;
|
|
289
|
+
const easingFn = bezier.apply(bezier, easingValues);
|
|
290
|
+
on($container, abortEvents, abortFn, { passive: true });
|
|
291
|
+
window.requestAnimationFrame(step);
|
|
292
|
+
return result;
|
|
293
|
+
function doneResolve() {
|
|
294
|
+
doneResolver();
|
|
295
|
+
}
|
|
296
|
+
function canceller(e = null, checkCancelable = false) {
|
|
297
|
+
if (checkCancelable && !cancelable) return;
|
|
298
|
+
off($container, abortEvents, abortFn);
|
|
299
|
+
callbackValues.abortEventSource = e;
|
|
300
|
+
callbackValues.aborted = true;
|
|
301
|
+
onCancel && onCancel(callbackValues);
|
|
302
|
+
}
|
|
303
|
+
function abortFn(e) {
|
|
304
|
+
canceller(e, true);
|
|
305
|
+
}
|
|
306
|
+
function initialAbort(e = null) {
|
|
307
|
+
canceller(e);
|
|
308
|
+
doneResolve();
|
|
309
|
+
return result;
|
|
310
|
+
}
|
|
311
|
+
function step(timestamp) {
|
|
312
|
+
if (callbackValues.aborted) return done();
|
|
313
|
+
if (!timeStart) timeStart = timestamp;
|
|
314
|
+
timeElapsed = timestamp - timeStart;
|
|
315
|
+
let progress = Math.min(timeElapsed / duration, 1);
|
|
316
|
+
progress = easingFn(progress);
|
|
317
|
+
callbackValues.progress = progress;
|
|
318
|
+
topLeft(initialY + diffY * progress, initialX + diffX * progress);
|
|
319
|
+
onProgress && onProgress(callbackValues);
|
|
320
|
+
timeElapsed < duration ? window.requestAnimationFrame(step) : done();
|
|
321
|
+
}
|
|
322
|
+
function topLeft(top, left) {
|
|
323
|
+
if (y) $container.scrollTop = top;
|
|
324
|
+
if (x) $container.scrollLeft = left;
|
|
325
|
+
}
|
|
326
|
+
function done() {
|
|
327
|
+
if (!callbackValues.aborted) topLeft(targetY, targetX);
|
|
328
|
+
timeStart = 0;
|
|
329
|
+
off($container, abortEvents, abortFn);
|
|
330
|
+
callbackValues.progress = 1;
|
|
331
|
+
doneResolve();
|
|
332
|
+
if (!callbackValues.aborted && onDone) onDone(callbackValues);
|
|
333
|
+
}
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
-
|
|
336
|
+
//#endregion
|
|
337
|
+
//#region src/scroll/scroll-by.ts
|
|
338
|
+
/**
|
|
339
|
+
* 指定の差分だけコンテナをスクロールします。
|
|
340
|
+
* @param diffX - 横軸の移動量(px)です。デフォルトは0です。
|
|
341
|
+
* @param diffY - 縦軸の移動量(px)です。デフォルトは0です。
|
|
342
|
+
* @param options - スクロールオプション
|
|
343
|
+
*/
|
|
337
344
|
function scrollBy(diffX, diffY, options) {
|
|
338
|
-
|
|
345
|
+
return scroll(diffX, diffY, options);
|
|
339
346
|
}
|
|
340
347
|
|
|
341
|
-
|
|
348
|
+
//#endregion
|
|
349
|
+
//#region src/scroll/scroll-to.ts
|
|
350
|
+
/**
|
|
351
|
+
* 任意の位置(px)へコンテナをスクロールします。
|
|
352
|
+
* @param scrollPosition - スクロール先を指定します。x, y 共にオプショナルなるです。未指定の軸は現在のスクロール値のまま保持されます。
|
|
353
|
+
* @param options - スクロールオプション
|
|
354
|
+
*/
|
|
342
355
|
function scrollTo(scrollPosition, options = {}) {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
targetY: y
|
|
359
|
-
});
|
|
356
|
+
let { x, y } = scrollPosition;
|
|
357
|
+
const container = options.container || defaultSettings.container;
|
|
358
|
+
const $container = $(container);
|
|
359
|
+
if (!$container) throw error(`missing container ${container}`);
|
|
360
|
+
const initialY = $container.scrollTop;
|
|
361
|
+
const initialX = $container.scrollLeft;
|
|
362
|
+
if (x === void 0) x = initialX;
|
|
363
|
+
if (y === void 0) y = initialY;
|
|
364
|
+
return scroll(x - initialX, y - initialY, options, {
|
|
365
|
+
$container,
|
|
366
|
+
initialX,
|
|
367
|
+
initialY,
|
|
368
|
+
targetX: x,
|
|
369
|
+
targetY: y
|
|
370
|
+
});
|
|
360
371
|
}
|
|
361
372
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
373
|
+
//#endregion
|
|
374
|
+
//#region src/scroll/scroll-to-element.ts
|
|
375
|
+
/**
|
|
376
|
+
* 要素スクロール利用事のデフォルト設定です。
|
|
377
|
+
* {@link ScrollToElementSettings}
|
|
378
|
+
*/
|
|
379
|
+
const scrollToElementSettingsDefaults = {
|
|
380
|
+
offset: 0,
|
|
381
|
+
x: false,
|
|
382
|
+
y: true
|
|
367
383
|
};
|
|
384
|
+
/**
|
|
385
|
+
* 任意の要素の位置へスクロールします。
|
|
386
|
+
* @param target - スクロール先の要素
|
|
387
|
+
* @param options - スクロールオプション
|
|
388
|
+
*/
|
|
368
389
|
function scrollToElement(target, options = {}) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
390
|
+
const _options = {
|
|
391
|
+
...scrollToElementSettingsDefaults,
|
|
392
|
+
...options
|
|
393
|
+
};
|
|
394
|
+
const { x, y } = _options;
|
|
395
|
+
const offsetSource = _options.offset;
|
|
396
|
+
const offset = typeof offsetSource === "number" ? {
|
|
397
|
+
x: offsetSource,
|
|
398
|
+
y: offsetSource
|
|
399
|
+
} : offsetSource;
|
|
400
|
+
const $target = $(target);
|
|
401
|
+
if (!$target) throw error(`missing element ${target}`);
|
|
402
|
+
const container = _options.container || defaultSettings.container;
|
|
403
|
+
const $container = $(container);
|
|
404
|
+
if (!$container) throw error(`missing container ${container}`);
|
|
405
|
+
const cumulativeOffsetContainer = cumulativeOffset($container);
|
|
406
|
+
const cumulativeOffsetTarget = cumulativeOffset($target);
|
|
407
|
+
const initialY = $container.scrollTop;
|
|
408
|
+
const initialX = $container.scrollLeft;
|
|
409
|
+
const targetY = cumulativeOffsetTarget.top - cumulativeOffsetContainer.top + (offset.y || 0);
|
|
410
|
+
const targetX = cumulativeOffsetTarget.left - cumulativeOffsetContainer.left + (offset.x || 0);
|
|
411
|
+
return scroll(x ? targetX - initialX : 0, y ? targetY - initialY : 0, _options, {
|
|
412
|
+
$container,
|
|
413
|
+
initialX,
|
|
414
|
+
initialY,
|
|
415
|
+
targetX,
|
|
416
|
+
targetY
|
|
417
|
+
});
|
|
393
418
|
}
|
|
394
419
|
|
|
395
|
-
|
|
420
|
+
//#endregion
|
|
421
|
+
//#region src/scroll/scroll-to-side.ts
|
|
422
|
+
/**
|
|
423
|
+
* コンテナをいずれかの辺までスクロールします。
|
|
424
|
+
* @param targets - 辺を指定します。シングルの文字列、及び配列に対応しています。
|
|
425
|
+
* @param options - スクロールオプション
|
|
426
|
+
*/
|
|
396
427
|
function scrollToSide(targets, options) {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
if (hasRight) position.x = $container.scrollWidth;
|
|
412
|
-
if (hasBottom) position.y = $container.scrollHeight;
|
|
413
|
-
}
|
|
414
|
-
return scrollTo(position, options);
|
|
428
|
+
const sides = typeof targets === "string" ? [targets] : targets;
|
|
429
|
+
const position = {};
|
|
430
|
+
const hasRight = sides.includes("right");
|
|
431
|
+
const hasBottom = sides.includes("bottom");
|
|
432
|
+
if (sides.includes("top")) position.y = 0;
|
|
433
|
+
if (sides.includes("left")) position.x = 0;
|
|
434
|
+
if (hasRight || hasBottom) {
|
|
435
|
+
const container = options && options.container || defaultSettings.container;
|
|
436
|
+
const $container = $(container);
|
|
437
|
+
if (!$container) throw error(`missing container ${container}`);
|
|
438
|
+
if (hasRight) position.x = $container.scrollWidth;
|
|
439
|
+
if (hasBottom) position.y = $container.scrollHeight;
|
|
440
|
+
}
|
|
441
|
+
return scrollTo(position, options);
|
|
415
442
|
}
|
|
443
|
+
/**
|
|
444
|
+
* コンテナを上辺までスクロールします。
|
|
445
|
+
* @param options - スクロールオプション
|
|
446
|
+
*/
|
|
416
447
|
function scrollToTop(options) {
|
|
417
|
-
|
|
448
|
+
return scrollToSide("top", options);
|
|
418
449
|
}
|
|
450
|
+
/**
|
|
451
|
+
* コンテナを右辺までスクロールします。
|
|
452
|
+
* @param options - スクロールオプション
|
|
453
|
+
*/
|
|
419
454
|
function scrollToRight(options) {
|
|
420
|
-
|
|
455
|
+
return scrollToSide("right", options);
|
|
421
456
|
}
|
|
457
|
+
/**
|
|
458
|
+
* コンテナを下辺までスクロールします。
|
|
459
|
+
* @param options - スクロールオプション
|
|
460
|
+
*/
|
|
422
461
|
function scrollToBottom(options) {
|
|
423
|
-
|
|
462
|
+
return scrollToSide("bottom", options);
|
|
424
463
|
}
|
|
464
|
+
/**
|
|
465
|
+
* コンテナを左辺までスクロールします。
|
|
466
|
+
* @param options - スクロールオプション
|
|
467
|
+
*/
|
|
425
468
|
function scrollToLeft(options) {
|
|
426
|
-
|
|
469
|
+
return scrollToSide("left", options);
|
|
427
470
|
}
|
|
471
|
+
/**
|
|
472
|
+
* コンテナを左上コーナーまでスクロールします。
|
|
473
|
+
* @param options - スクロールオプション
|
|
474
|
+
*/
|
|
428
475
|
function scrollToLeftTop(options) {
|
|
429
|
-
|
|
476
|
+
return scrollToSide(["left", "top"], options);
|
|
430
477
|
}
|
|
478
|
+
/**
|
|
479
|
+
* コンテナを左下コーナーまでスクロールします。
|
|
480
|
+
* @param options - スクロールオプション
|
|
481
|
+
*/
|
|
431
482
|
function scrollToLeftBottom(options) {
|
|
432
|
-
|
|
483
|
+
return scrollToSide(["left", "bottom"], options);
|
|
433
484
|
}
|
|
485
|
+
/**
|
|
486
|
+
* コンテナを右上コーナーまでスクロールします。
|
|
487
|
+
* @param options - スクロールオプション
|
|
488
|
+
*/
|
|
434
489
|
function scrollToRightTop(options) {
|
|
435
|
-
|
|
490
|
+
return scrollToSide(["right", "top"], options);
|
|
436
491
|
}
|
|
492
|
+
/**
|
|
493
|
+
* コンテナを右下コーナーまでスクロールします。
|
|
494
|
+
* @param options - スクロールオプション
|
|
495
|
+
*/
|
|
437
496
|
function scrollToRightBottom(options) {
|
|
438
|
-
|
|
497
|
+
return scrollToSide(["right", "bottom"], options);
|
|
439
498
|
}
|
|
440
499
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
500
|
+
//#endregion
|
|
501
|
+
//#region src/scroller.ts
|
|
502
|
+
/**
|
|
503
|
+
* Scrollerの状態を示します。
|
|
504
|
+
*/
|
|
505
|
+
let ScrollerState = /* @__PURE__ */ function(ScrollerState) {
|
|
506
|
+
/**
|
|
507
|
+
* Scrollerが初期化されていない(Elementが設定されていない)状態を示します。
|
|
508
|
+
*/
|
|
509
|
+
ScrollerState["Pending"] = "pending";
|
|
510
|
+
/**
|
|
511
|
+
* Scrollerが初期化されているが、[[Scroller.el]]のリサイズやスクロールのイベント監視が動作していない状態を示します。
|
|
512
|
+
*/
|
|
513
|
+
ScrollerState["Ready"] = "ready";
|
|
514
|
+
/**
|
|
515
|
+
* Scrollerが初期化されていて、[[Scroller.el]]のリサイズやスクロールのイベント監視が動作している状態を示します。
|
|
516
|
+
*/
|
|
517
|
+
ScrollerState["Running"] = "running";
|
|
518
|
+
/**
|
|
519
|
+
* [[Scroller.destroy]]が実行され、Scrollerが利用不可である状態を示します。
|
|
520
|
+
*/
|
|
521
|
+
ScrollerState["Destroyed"] = "destroyed";
|
|
522
|
+
return ScrollerState;
|
|
523
|
+
}({});
|
|
524
|
+
const scrollerObservableKeys = [
|
|
525
|
+
"state",
|
|
526
|
+
"isPending",
|
|
527
|
+
"isReady",
|
|
528
|
+
"isRunning",
|
|
529
|
+
"isDestroyed",
|
|
530
|
+
"scrollEnabled",
|
|
531
|
+
"containerWidth",
|
|
532
|
+
"containerHeight",
|
|
533
|
+
"scrollWidth",
|
|
534
|
+
"scrollHeight",
|
|
535
|
+
"scrollableX",
|
|
536
|
+
"scrollableY",
|
|
537
|
+
"scrollTop",
|
|
538
|
+
"scrollLeft",
|
|
539
|
+
"scrollRight",
|
|
540
|
+
"scrollBottom",
|
|
541
|
+
"lastAxis",
|
|
542
|
+
"lastDirection",
|
|
543
|
+
"lastYDirection",
|
|
544
|
+
"lastXDirection",
|
|
545
|
+
"nowScrolling"
|
|
471
546
|
];
|
|
547
|
+
/**
|
|
548
|
+
* 任意のElement(or HTML Document)のスクロールやサイズ変更を監視し、その情報を通知するクラスです。<br>
|
|
549
|
+
* <a href="https://dadajam4.github.io/dadajam4/ev/classes/_ev_.ev.html" target="_blank">EV</a>を継承しており、イベントの購読[[Scroller.on]]等のインターフェースを利用するか、
|
|
550
|
+
* [[Scroller.observe]]メソッドを利用します。<br>
|
|
551
|
+
* [[Scroller.on]]、[[Scroller.once]]で購読可能なイベントについては[[ScrollerEventMap]]を参照してください。
|
|
552
|
+
*/
|
|
472
553
|
var Scroller = class extends EV {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
this._clearScrollingJudgeTimer();
|
|
1317
|
-
this._scrollingJudgeTimerId = window.setTimeout(() => {
|
|
1318
|
-
this._triggerScrollTick("scrollEnd");
|
|
1319
|
-
}, this.scrollingJudgeInterval);
|
|
1320
|
-
}
|
|
1321
|
-
_syncToObserver(observer, keys = scrollerObservableKeys) {
|
|
1322
|
-
for (const key of keys) {
|
|
1323
|
-
observer[key] = this[key];
|
|
1324
|
-
}
|
|
1325
|
-
}
|
|
1326
|
-
_syncToObservers(keys) {
|
|
1327
|
-
if (this._observers.length === 0) return;
|
|
1328
|
-
keys = typeof keys === "string" ? [keys] : keys;
|
|
1329
|
-
for (const observer of this._observers) {
|
|
1330
|
-
this._syncToObserver(observer, keys);
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
_checkElement() {
|
|
1334
|
-
const { _el } = this;
|
|
1335
|
-
if (!_el) {
|
|
1336
|
-
const message = "missing element";
|
|
1337
|
-
logger.error(message);
|
|
1338
|
-
throw new Error(message);
|
|
1339
|
-
}
|
|
1340
|
-
return _el;
|
|
1341
|
-
}
|
|
1342
|
-
_createMergedScrollOptions(source) {
|
|
1343
|
-
const el = this._checkElement();
|
|
1344
|
-
const merged = {
|
|
1345
|
-
container: el,
|
|
1346
|
-
...this.scrollSettingsDefaults,
|
|
1347
|
-
...source
|
|
1348
|
-
};
|
|
1349
|
-
return merged;
|
|
1350
|
-
}
|
|
1351
|
-
_createMergedScrollToElementOptions(source) {
|
|
1352
|
-
const el = this._checkElement();
|
|
1353
|
-
const merged = {
|
|
1354
|
-
container: el,
|
|
1355
|
-
...this.scrollToElementSettingsDefaults,
|
|
1356
|
-
...source
|
|
1357
|
-
};
|
|
1358
|
-
let { _scrollToElementAdditionalOffset: additionalOffset } = this;
|
|
1359
|
-
if (!additionalOffset) return merged;
|
|
1360
|
-
if (typeof additionalOffset === "function") {
|
|
1361
|
-
additionalOffset = additionalOffset(this);
|
|
1362
|
-
}
|
|
1363
|
-
if (!additionalOffset) return merged;
|
|
1364
|
-
if (typeof additionalOffset === "number") {
|
|
1365
|
-
additionalOffset = {
|
|
1366
|
-
x: additionalOffset,
|
|
1367
|
-
y: additionalOffset
|
|
1368
|
-
};
|
|
1369
|
-
}
|
|
1370
|
-
let { offset } = merged;
|
|
1371
|
-
if (!offset) {
|
|
1372
|
-
merged.offset = additionalOffset;
|
|
1373
|
-
return merged;
|
|
1374
|
-
}
|
|
1375
|
-
if (typeof offset === "number") {
|
|
1376
|
-
offset = {
|
|
1377
|
-
x: offset,
|
|
1378
|
-
y: offset
|
|
1379
|
-
};
|
|
1380
|
-
}
|
|
1381
|
-
offset.x = (offset.x || 0) + (additionalOffset.x || 0);
|
|
1382
|
-
offset.y = (offset.y || 0) + (additionalOffset.y || 0);
|
|
1383
|
-
merged.offset = offset;
|
|
1384
|
-
return merged;
|
|
1385
|
-
}
|
|
1386
|
-
_clearScrollToResult() {
|
|
1387
|
-
if (!this._scrollToResult) return;
|
|
1388
|
-
this._scrollToResult = null;
|
|
1389
|
-
}
|
|
1390
|
-
_setScrollToResult(result) {
|
|
1391
|
-
this._scrollToResult = result;
|
|
1392
|
-
result.promise.then(() => {
|
|
1393
|
-
this._clearScrollToResult();
|
|
1394
|
-
});
|
|
1395
|
-
return result;
|
|
1396
|
-
}
|
|
1397
|
-
_updateScrollable() {
|
|
1398
|
-
if (this.scrollEnabled) {
|
|
1399
|
-
this._scrollEnable();
|
|
1400
|
-
} else {
|
|
1401
|
-
this._scrollDisable();
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
_scrollEnable() {
|
|
1405
|
-
enableScroll(this._checkElement());
|
|
1406
|
-
}
|
|
1407
|
-
_scrollDisable() {
|
|
1408
|
-
const el = this._checkElement();
|
|
1409
|
-
this.cancel();
|
|
1410
|
-
disableScroll(el);
|
|
1411
|
-
}
|
|
554
|
+
/**
|
|
555
|
+
* Scrollerクラスの状態を監視&同期するオブジェクトが
|
|
556
|
+
* 保有すべきプロパティ一のキーの配列です。
|
|
557
|
+
*/
|
|
558
|
+
static scrollerObservableKeys = scrollerObservableKeys;
|
|
559
|
+
/**
|
|
560
|
+
* Scrollerの状態を示すenum値です。
|
|
561
|
+
* {@link ScrollerState}
|
|
562
|
+
*/
|
|
563
|
+
static States = ScrollerState;
|
|
564
|
+
/**
|
|
565
|
+
* スクロールを検知してから、移動がなくなった際に、何ms後にスクロール終了と判定するかのインターバル値を示します。
|
|
566
|
+
* デフォルトは500です。
|
|
567
|
+
*/
|
|
568
|
+
scrollingJudgeInterval = 500;
|
|
569
|
+
/**
|
|
570
|
+
* 縦、横のどちらのスクロールを基準とするかを示します。
|
|
571
|
+
* デフォルトはyです。<br>
|
|
572
|
+
* この設定は[[Scroller.toElement]]のデフォルト値にも影響します。
|
|
573
|
+
*/
|
|
574
|
+
baseAxis = "y";
|
|
575
|
+
/**
|
|
576
|
+
* スクロール系メソッド[[Scroller.to]]等を利用する際のデフォルトの設定を示します。
|
|
577
|
+
*/
|
|
578
|
+
scrollSettingsDefaults = { ...defaultBaseSettings };
|
|
579
|
+
/**
|
|
580
|
+
* [[Scroller.toElement]]のデフォルトオプションの設定を示します。
|
|
581
|
+
*/
|
|
582
|
+
scrollToElementSettingsDefaults = { ...scrollToElementSettingsDefaults };
|
|
583
|
+
scrollSizeObserver;
|
|
584
|
+
/**
|
|
585
|
+
* 設定されたElement要素です。
|
|
586
|
+
* 初期化が完了していない時には本getterはundefinedを返却する事に注意してください。
|
|
587
|
+
*/
|
|
588
|
+
get el() {
|
|
589
|
+
return this._el;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* 現在の状態です。<br>
|
|
593
|
+
* {@link ScrollerState}
|
|
594
|
+
*/
|
|
595
|
+
get state() {
|
|
596
|
+
return this._state;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* 未初期化である場合trueを示します。
|
|
600
|
+
*/
|
|
601
|
+
get isPending() {
|
|
602
|
+
return this._state === ScrollerState.Pending;
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* 初期化済み&停止状態である場合trueを示します。
|
|
606
|
+
*/
|
|
607
|
+
get isReady() {
|
|
608
|
+
return this._state === ScrollerState.Ready;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* 初期化済み&動作中である場合trueを示します。
|
|
612
|
+
*/
|
|
613
|
+
get isRunning() {
|
|
614
|
+
return this._state === ScrollerState.Running;
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* インスタンスが破棄済みである場合trueを示します。
|
|
618
|
+
*/
|
|
619
|
+
get isDestroyed() {
|
|
620
|
+
return this._state === ScrollerState.Destroyed;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* スクロールの有効状態を取得します
|
|
624
|
+
*/
|
|
625
|
+
get scrollEnabled() {
|
|
626
|
+
return this._scrollStoppers.length === 0;
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* スクロール要素の幅を示します。
|
|
630
|
+
*/
|
|
631
|
+
get containerWidth() {
|
|
632
|
+
return this._containerWidth;
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* スクロール要素の高さを示します。
|
|
636
|
+
*/
|
|
637
|
+
get containerHeight() {
|
|
638
|
+
return this._containerHeight;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* スクロール要素内のコンテンツの幅を示します。
|
|
642
|
+
*/
|
|
643
|
+
get scrollWidth() {
|
|
644
|
+
return this._scrollWidth;
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* スクロール要素内のコンテンツの高さを示します。
|
|
648
|
+
*/
|
|
649
|
+
get scrollHeight() {
|
|
650
|
+
return this._scrollHeight;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* x軸にスクロール可能な場合trueを示します
|
|
654
|
+
*/
|
|
655
|
+
get scrollableX() {
|
|
656
|
+
return this._scrollWidth > this._containerWidth;
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* y軸にスクロール可能な場合trueを示します
|
|
660
|
+
*/
|
|
661
|
+
get scrollableY() {
|
|
662
|
+
return this._scrollHeight > this._containerHeight;
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* 現在の上辺からのスクロール量を示します。
|
|
666
|
+
*/
|
|
667
|
+
get scrollTop() {
|
|
668
|
+
return this._scrollTop;
|
|
669
|
+
}
|
|
670
|
+
set scrollTop(scrollTop) {
|
|
671
|
+
if (!this.el) return;
|
|
672
|
+
this.el.scrollTop = scrollTop;
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* 現在の右辺からのスクロール量を示します。
|
|
676
|
+
*/
|
|
677
|
+
get scrollRight() {
|
|
678
|
+
return this._scrollRight;
|
|
679
|
+
}
|
|
680
|
+
set scrollRight(scrollRight) {
|
|
681
|
+
if (!this.el) return;
|
|
682
|
+
this.el.scrollLeft = this._scrollWidth - this._containerWidth - scrollRight;
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* 現在の下辺からのスクロール量を示します。
|
|
686
|
+
*/
|
|
687
|
+
get scrollBottom() {
|
|
688
|
+
return this._scrollBottom;
|
|
689
|
+
}
|
|
690
|
+
set scrollBottom(scrollBottom) {
|
|
691
|
+
if (!this.el) return;
|
|
692
|
+
this.el.scrollTop = this._scrollHeight - this._containerHeight - scrollBottom;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* 現在の左辺からのスクロール量を示します。
|
|
696
|
+
*/
|
|
697
|
+
get scrollLeft() {
|
|
698
|
+
return this._scrollLeft;
|
|
699
|
+
}
|
|
700
|
+
set scrollLeft(scrollLeft) {
|
|
701
|
+
if (!this.el) return;
|
|
702
|
+
this.el.scrollLeft = scrollLeft;
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* 現在スクロール中である場合trueを示します。
|
|
706
|
+
*/
|
|
707
|
+
get nowScrolling() {
|
|
708
|
+
return this._nowScrolling;
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* 最後に検知したスクロールの軸を示します。
|
|
712
|
+
*/
|
|
713
|
+
get lastAxis() {
|
|
714
|
+
return this._lastAxis;
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* 最後に検知したスクロールの方向を示します。
|
|
718
|
+
*/
|
|
719
|
+
get lastDirection() {
|
|
720
|
+
return this._lastDirection;
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* 最後に検知したスクロールの垂直方向を示します。
|
|
724
|
+
*/
|
|
725
|
+
get lastYDirection() {
|
|
726
|
+
return this._lastYDirection;
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* 最後に検知したスクロールの水平方向を示します。
|
|
730
|
+
*/
|
|
731
|
+
get lastXDirection() {
|
|
732
|
+
return this._lastXDirection;
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* 最後に検知したスクロールにより通知した情報を示します。
|
|
736
|
+
*/
|
|
737
|
+
get lastPayload() {
|
|
738
|
+
return {
|
|
739
|
+
top: this._scrollTop,
|
|
740
|
+
left: this._scrollLeft,
|
|
741
|
+
bottom: this._scrollBottom,
|
|
742
|
+
right: this._scrollRight,
|
|
743
|
+
axis: this._lastAxis,
|
|
744
|
+
direction: this._lastDirection,
|
|
745
|
+
directionX: this._lastXDirection,
|
|
746
|
+
directionY: this._lastYDirection,
|
|
747
|
+
tickedX: this._tickedX,
|
|
748
|
+
tickedY: this._tickedY,
|
|
749
|
+
totalX: this._lastTotalX,
|
|
750
|
+
totalY: this._lastTotalY
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
_el;
|
|
754
|
+
_eventTarget;
|
|
755
|
+
_isDocumentElement = false;
|
|
756
|
+
_isBodyElement = false;
|
|
757
|
+
_isRootElement = false;
|
|
758
|
+
_state = ScrollerState.Pending;
|
|
759
|
+
_containerWidth = 0;
|
|
760
|
+
_containerHeight = 0;
|
|
761
|
+
_scrollWidth = 0;
|
|
762
|
+
_scrollHeight = 0;
|
|
763
|
+
_scrollTop = 0;
|
|
764
|
+
_scrollRight = 0;
|
|
765
|
+
_scrollBottom = 0;
|
|
766
|
+
_scrollLeft = 0;
|
|
767
|
+
_lastAxis;
|
|
768
|
+
_lastDirection;
|
|
769
|
+
_lastYDirection = "top";
|
|
770
|
+
_lastXDirection = "left";
|
|
771
|
+
_nowScrolling = false;
|
|
772
|
+
_readyResolvers = [];
|
|
773
|
+
_scrollingJudgeTimerId = null;
|
|
774
|
+
_startX = 0;
|
|
775
|
+
_startY = 0;
|
|
776
|
+
_tickedX = 0;
|
|
777
|
+
_tickedY = 0;
|
|
778
|
+
_lastTotalX = 0;
|
|
779
|
+
_lastTotalY = 0;
|
|
780
|
+
_scrollListener;
|
|
781
|
+
_resizeListener;
|
|
782
|
+
_resizeObserver;
|
|
783
|
+
_scrollToResult = null;
|
|
784
|
+
_observers = [];
|
|
785
|
+
_scrollStoppers = [];
|
|
786
|
+
_scrollSizeObserverPollingId = null;
|
|
787
|
+
_scrollSizeObserverSuspended = false;
|
|
788
|
+
_visibilityListener;
|
|
789
|
+
/**
|
|
790
|
+
* Scrollerインスタンスを作成します。
|
|
791
|
+
* コンテキストとなるElementをこの時点で指定するか否かは任意です。
|
|
792
|
+
*
|
|
793
|
+
* @param settingOrElementOrQueryString - 任意です。{@link ScrollerSetting}か Element(or cssクエリセレクタ文字列)を直接指定します。この時点でElementを指定しない場合は、[[setElement]]を実行するまでインスタンスは動作しません。
|
|
794
|
+
*/
|
|
795
|
+
constructor(settingOrElementOrQueryString = {}) {
|
|
796
|
+
super();
|
|
797
|
+
const convertedSetting = typeof settingOrElementOrQueryString === "string" || settingOrElementOrQueryString === null || IN_WINDOW && settingOrElementOrQueryString instanceof Element ? settingOrElementOrQueryString = { el: settingOrElementOrQueryString } : settingOrElementOrQueryString;
|
|
798
|
+
if (convertedSetting.scrollingJudgeInterval !== void 0) this.scrollingJudgeInterval = convertedSetting.scrollingJudgeInterval;
|
|
799
|
+
if (convertedSetting.baseAxis) this.baseAxis = convertedSetting.baseAxis;
|
|
800
|
+
this._lastAxis = this.baseAxis;
|
|
801
|
+
const { scrollSizeObserver } = convertedSetting;
|
|
802
|
+
if (scrollSizeObserver) this.scrollSizeObserver = {
|
|
803
|
+
interval: 500,
|
|
804
|
+
width: true,
|
|
805
|
+
height: true,
|
|
806
|
+
...scrollSizeObserver
|
|
807
|
+
};
|
|
808
|
+
this._visibilityListener = () => {
|
|
809
|
+
if (visibilityManager.isVisible) {
|
|
810
|
+
this.update();
|
|
811
|
+
if (this._scrollSizeObserverSuspended) {
|
|
812
|
+
this._scrollSizeObserverSuspended = false;
|
|
813
|
+
this._startScrollSizeObserver();
|
|
814
|
+
}
|
|
815
|
+
} else {
|
|
816
|
+
this._scrollSizeObserverSuspended = this._scrollSizeObserverPollingId !== null;
|
|
817
|
+
this._stopScrollSizeObserver();
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
this._lastDirection = this._lastAxis === "y" ? "top" : "left";
|
|
821
|
+
if (!IN_WINDOW) return;
|
|
822
|
+
visibilityManager.change(this._visibilityListener);
|
|
823
|
+
this.setElement(convertedSetting.el);
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* インスタンスにElementを設定します。特別な理由(SSRの利用等)によりコンストラクタでElementを指定できない場合、
|
|
827
|
+
* 本メソッドを利用しブラウザコンテキスト配下で本メソッドを実行してください。
|
|
828
|
+
* @param el - Element、もしくはCSSクエリセレクタ文字列を指定します。
|
|
829
|
+
*/
|
|
830
|
+
setElement(el) {
|
|
831
|
+
if (el === null) return;
|
|
832
|
+
if (!IN_WINDOW) logger.error("Element can be set only when it is under DOM context.");
|
|
833
|
+
this.stop();
|
|
834
|
+
let _el;
|
|
835
|
+
if (typeof el === "string") _el = document.querySelector(el);
|
|
836
|
+
else _el = el || document.scrollingElement;
|
|
837
|
+
if (!_el) {
|
|
838
|
+
const message = "missing scrolling element";
|
|
839
|
+
logger.error(message, el);
|
|
840
|
+
throw new Error(message);
|
|
841
|
+
}
|
|
842
|
+
this._el = _el;
|
|
843
|
+
this._isDocumentElement = isDocumentElement(_el);
|
|
844
|
+
this._isBodyElement = isBodyElement$1(_el);
|
|
845
|
+
this._isRootElement = this._isDocumentElement || this._isBodyElement;
|
|
846
|
+
this._eventTarget = this._isDocumentElement || this._isBodyElement ? window : this._el;
|
|
847
|
+
this._setup();
|
|
848
|
+
}
|
|
849
|
+
_scrollToElementAdditionalOffset;
|
|
850
|
+
setScrollToElementAdditionalOffset(offset) {
|
|
851
|
+
this._scrollToElementAdditionalOffset = offset;
|
|
852
|
+
}
|
|
853
|
+
deleteScrollToElementAdditionalOffset() {
|
|
854
|
+
delete this._scrollToElementAdditionalOffset;
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* インスタンスが実行可能になった際にresolveされるPromiseインスタンスを返却します。
|
|
858
|
+
*/
|
|
859
|
+
ready() {
|
|
860
|
+
this._checkDestroyed();
|
|
861
|
+
if (!this.isPending) return Promise.resolve();
|
|
862
|
+
return new Promise((resolve) => this._readyResolvers.push(resolve));
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* インスタンスの動作を開始します。本インスタンスはElementが設定され初期化された際に自動で動作を開始しますが、
|
|
866
|
+
* [[Scroller.stop]]メソッドを利用し動作を停止した後に再開する場合に本メソッドを利用します。
|
|
867
|
+
*/
|
|
868
|
+
async start() {
|
|
869
|
+
this._checkDestroyed();
|
|
870
|
+
if (this.isRunning) return;
|
|
871
|
+
await this.ready();
|
|
872
|
+
this._startListeners();
|
|
873
|
+
this._setState(ScrollerState.Running);
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* インスタンスの動作(スクロール、リサイズイベントの検知等)を停止します。
|
|
877
|
+
* 何らかの理由で動作を停止させたい場合に利用してください。
|
|
878
|
+
* 本メソッドを実行後もインスタンス内の状態は保持されたままです。
|
|
879
|
+
* 完全にインスタンスを破棄するためには[[Scroller.destroy]]を利用してください。
|
|
880
|
+
*/
|
|
881
|
+
stop() {
|
|
882
|
+
this._checkDestroyed();
|
|
883
|
+
if (!this.isRunning) return;
|
|
884
|
+
this._stopListeners();
|
|
885
|
+
this._setState(ScrollerState.Ready);
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* インスタンスの動作を停止し、内部情報を完全に破棄します。
|
|
889
|
+
* これに伴い、スクロール中であった場合にはキャンセルされ、以後イベント通知は完全に行われません。
|
|
890
|
+
* また[[Scroller.start]]メソッドでの再利用も不可となります。
|
|
891
|
+
* 本インスタンスの利用を完全に停止する場合に必ず実行し、利用側のオブジェクト等において本インスタンスへの参照を完全に削除してください。
|
|
892
|
+
* 本メソッドはSPA等でのサービスにおいては意識的に実行する事を強く推奨します。
|
|
893
|
+
*/
|
|
894
|
+
destroy() {
|
|
895
|
+
if (this.isDestroyed) return;
|
|
896
|
+
this.stop();
|
|
897
|
+
this.cancel();
|
|
898
|
+
this._readyResolvers = [];
|
|
899
|
+
this._scrollStoppers = [];
|
|
900
|
+
this._scrollEnable();
|
|
901
|
+
this._observers = [];
|
|
902
|
+
visibilityManager.remove(this._visibilityListener);
|
|
903
|
+
delete this._el;
|
|
904
|
+
delete this._eventTarget;
|
|
905
|
+
delete this._scrollListener;
|
|
906
|
+
delete this._resizeListener;
|
|
907
|
+
delete this._resizeObserver;
|
|
908
|
+
delete this._scrollToResult;
|
|
909
|
+
delete this._visibilityListener;
|
|
910
|
+
this.deleteScrollToElementAdditionalOffset();
|
|
911
|
+
this._setState(ScrollerState.Destroyed);
|
|
912
|
+
this.offAll();
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* インスタンス内部のスクロール量や、Elementのサイズを強制的に更新します。
|
|
916
|
+
* 基本的に利用が必要なケースはありませんが、何らかの理由で更新をトリガーしたい場合に利用します。
|
|
917
|
+
*/
|
|
918
|
+
update() {
|
|
919
|
+
this._update();
|
|
920
|
+
}
|
|
921
|
+
/**
|
|
922
|
+
* インスタンス内の情報をjsonオブジェクトとして返却します。
|
|
923
|
+
* 情報の詳細は[[ScrollerObserver]]を参照してください。
|
|
924
|
+
*/
|
|
925
|
+
toJSON() {
|
|
926
|
+
const json = {};
|
|
927
|
+
for (const key of scrollerObservableKeys) json[key] = this[key];
|
|
928
|
+
return json;
|
|
929
|
+
}
|
|
930
|
+
/**
|
|
931
|
+
* [[Scroller.toJSON]]の情報を文字列として返却します。
|
|
932
|
+
*/
|
|
933
|
+
toString() {
|
|
934
|
+
return JSON.stringify(this.toJSON());
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* 本インスタンスの情報を購読するためのオブジェクトを設定する事で、
|
|
938
|
+
* インスタンスの内部情報が変更される度にパラメータが同期されます。
|
|
939
|
+
* 設定するオブジェクトは[[ScrollerObserver]]のインターフェースを満たしていれば内容は問いません。
|
|
940
|
+
* 本機能により同期される方法は単純にオブジェクトプロパティへの変数代入です。
|
|
941
|
+
* 従って対象となるプロパティをgetterとして実装(Ex: Vue computed等、、)しておく事により、
|
|
942
|
+
* 同期を受け取るオブジェクト側でパラメータ変更後の動作をリアクティブに実装可能です。
|
|
943
|
+
* @param observer - 同期させたいオブジェクト
|
|
944
|
+
* @returns 同期を停止するためのメソッド
|
|
945
|
+
*/
|
|
946
|
+
observe(observer) {
|
|
947
|
+
if (!this._observers.includes(observer)) this._observers.push(observer);
|
|
948
|
+
this._syncToObserver(observer);
|
|
949
|
+
const unobserve = () => {
|
|
950
|
+
this.unobserve(observer);
|
|
951
|
+
};
|
|
952
|
+
return unobserve;
|
|
953
|
+
}
|
|
954
|
+
/**
|
|
955
|
+
* [[Scroller.observe]]でパラメータ同期中のオブジェクトを停止します。
|
|
956
|
+
* [[Scroller.destroy]]実行時にも、同期中のオブジェクトは全停止されますが、destroy前に任意のタイミングで停止したい場合
|
|
957
|
+
* 本メソッドを利用します。
|
|
958
|
+
* @param observer - 同期中のオブジェクト
|
|
959
|
+
*/
|
|
960
|
+
unobserve(observer) {
|
|
961
|
+
const index = this._observers.indexOf(observer);
|
|
962
|
+
if (index !== -1) this._observers.splice(index, 1);
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* スクロール中であった場合、スクロールをキャンセルします。
|
|
966
|
+
*/
|
|
967
|
+
cancel() {
|
|
968
|
+
if (!this._scrollToResult) return;
|
|
969
|
+
this._scrollToResult.cancel();
|
|
970
|
+
this._clearScrollToResult();
|
|
971
|
+
}
|
|
972
|
+
/**
|
|
973
|
+
* x, yの差分pxを指定しスクロールします。
|
|
974
|
+
* メソッド、パラメータの詳細は[[scrollBy]]を参照してください。
|
|
975
|
+
* @param diffX - 横移動量
|
|
976
|
+
* @param diffY - 縦移動量
|
|
977
|
+
* @param options - スクロールオプション
|
|
978
|
+
*/
|
|
979
|
+
by(diffX, diffY, options) {
|
|
980
|
+
return this._setScrollToResult(scrollBy(diffX, diffY, this._createMergedScrollOptions(options)));
|
|
981
|
+
}
|
|
982
|
+
/**
|
|
983
|
+
* 指定の座標へスクロールします。
|
|
984
|
+
* メソッド、パラメータの詳細は[[scrollTo]]を参照してください。
|
|
985
|
+
* @param scrollPosition - 座標
|
|
986
|
+
* @param options - スクロールオプション
|
|
987
|
+
*/
|
|
988
|
+
to(scrollPosition, options) {
|
|
989
|
+
return this._setScrollToResult(scrollTo(scrollPosition, this._createMergedScrollOptions(options)));
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* 指定の要素の位置へスクロールします。
|
|
993
|
+
* メソッド、パラメータの詳細は[[scrollToElement]]を参照してください。
|
|
994
|
+
* オプションのx, yが未設定であった場合、[[Scroller.baseAxis]]により自動設定されます。
|
|
995
|
+
* @param target - スクロール先の要素
|
|
996
|
+
* @param options - スクロールオプション
|
|
997
|
+
*/
|
|
998
|
+
toElement(target, options) {
|
|
999
|
+
const merged = this._createMergedScrollToElementOptions(options);
|
|
1000
|
+
if (merged.x === void 0) merged.x = this.baseAxis === "x";
|
|
1001
|
+
if (merged.y === void 0) merged.y = this.baseAxis === "y";
|
|
1002
|
+
return this._setScrollToResult(scrollToElement(target, merged));
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* 指定の辺へスクロールします。
|
|
1006
|
+
* メソッド、パラメータの詳細は[[scrollToSide]]を参照してください。
|
|
1007
|
+
* @param targets - スクロール先
|
|
1008
|
+
* @param options - スクロールオプション
|
|
1009
|
+
*/
|
|
1010
|
+
toSide(targets, options) {
|
|
1011
|
+
return this._setScrollToResult(scrollToSide(targets, this._createMergedScrollOptions(options)));
|
|
1012
|
+
}
|
|
1013
|
+
/**
|
|
1014
|
+
* 上辺へスクロールします。
|
|
1015
|
+
* メソッド、パラメータの詳細は[[scrollToTop]]を参照してください。
|
|
1016
|
+
* @param options - スクロールオプション
|
|
1017
|
+
*/
|
|
1018
|
+
toTop(options) {
|
|
1019
|
+
return this._setScrollToResult(scrollToTop(this._createMergedScrollOptions(options)));
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* 右辺へスクロールします。
|
|
1023
|
+
* メソッド、パラメータの詳細は[[scrollToRight]]を参照してください。
|
|
1024
|
+
* @param options - スクロールオプション
|
|
1025
|
+
*/
|
|
1026
|
+
toRight(options) {
|
|
1027
|
+
return this._setScrollToResult(scrollToRight(this._createMergedScrollOptions(options)));
|
|
1028
|
+
}
|
|
1029
|
+
/**
|
|
1030
|
+
* 下辺へスクロールします。
|
|
1031
|
+
* メソッド、パラメータの詳細は[[scrollToBottom]]を参照してください。
|
|
1032
|
+
* @param options - スクロールオプション
|
|
1033
|
+
*/
|
|
1034
|
+
toBottom(options) {
|
|
1035
|
+
return this._setScrollToResult(scrollToBottom(this._createMergedScrollOptions(options)));
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* 左辺へスクロールします。
|
|
1039
|
+
* メソッド、パラメータの詳細は[[scrollToLeft]]を参照してください。
|
|
1040
|
+
* @param options - スクロールオプション
|
|
1041
|
+
*/
|
|
1042
|
+
toLeft(options) {
|
|
1043
|
+
return this._setScrollToResult(scrollToLeft(this._createMergedScrollOptions(options)));
|
|
1044
|
+
}
|
|
1045
|
+
/**
|
|
1046
|
+
* 左上コーナーへスクロールします。
|
|
1047
|
+
* メソッド、パラメータの詳細は[[scrollToLeftTop]]を参照してください。
|
|
1048
|
+
* @param options - スクロールオプション
|
|
1049
|
+
*/
|
|
1050
|
+
toLeftTop(options) {
|
|
1051
|
+
return this._setScrollToResult(scrollToLeftTop(this._createMergedScrollOptions(options)));
|
|
1052
|
+
}
|
|
1053
|
+
/**
|
|
1054
|
+
* 左下コーナーへスクロールします。
|
|
1055
|
+
* メソッド、パラメータの詳細は[[scrollToLeftBottom]]を参照してください。
|
|
1056
|
+
* @param options - スクロールオプション
|
|
1057
|
+
*/
|
|
1058
|
+
toLeftBottom(options) {
|
|
1059
|
+
return this._setScrollToResult(scrollToLeftBottom(this._createMergedScrollOptions(options)));
|
|
1060
|
+
}
|
|
1061
|
+
/**
|
|
1062
|
+
* 右上コーナーへスクロールします。
|
|
1063
|
+
* メソッド、パラメータの詳細は[[scrollToRightTop]]を参照してください。
|
|
1064
|
+
* @param options - スクロールオプション
|
|
1065
|
+
*/
|
|
1066
|
+
toRightTop(options) {
|
|
1067
|
+
return this._setScrollToResult(scrollToRightTop(this._createMergedScrollOptions(options)));
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* 右下コーナーへスクロールします。
|
|
1071
|
+
* メソッド、パラメータの詳細は[[scrollToRightBottom]]を参照してください。
|
|
1072
|
+
* @param options - スクロールオプション
|
|
1073
|
+
*/
|
|
1074
|
+
toRightBottom(options) {
|
|
1075
|
+
return this._setScrollToResult(scrollToRightBottom(this._createMergedScrollOptions(options)));
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* スクロールの停止を要求します。
|
|
1079
|
+
* @param stopper - 停止要求ソース
|
|
1080
|
+
*/
|
|
1081
|
+
pushScrollStopper(stopper) {
|
|
1082
|
+
if (!this._scrollStoppers.includes(stopper)) {
|
|
1083
|
+
this._scrollStoppers.push(stopper);
|
|
1084
|
+
if (this._scrollStoppers.length === 1) {
|
|
1085
|
+
this._updateScrollable();
|
|
1086
|
+
this._syncToObservers(["scrollEnabled"]);
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
return () => {
|
|
1090
|
+
this.removeScrollStopper(stopper);
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
/**
|
|
1094
|
+
* スクロールの停止要求を解除します。<br>
|
|
1095
|
+
* 別のプロセスにより異なる[[ScrollStopper]]が登録されている場合、
|
|
1096
|
+
* スクロールは再開されない事に注意してください。
|
|
1097
|
+
* @param stopper - 停止要求ソース
|
|
1098
|
+
*/
|
|
1099
|
+
removeScrollStopper(stopper) {
|
|
1100
|
+
const index = this._scrollStoppers.indexOf(stopper);
|
|
1101
|
+
if (index !== -1) {
|
|
1102
|
+
this._scrollStoppers.splice(index, 1);
|
|
1103
|
+
if (this._scrollStoppers.length === 0) {
|
|
1104
|
+
this._updateScrollable();
|
|
1105
|
+
this._syncToObservers(["scrollEnabled"]);
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
async _setup() {
|
|
1110
|
+
this._updateScrollable();
|
|
1111
|
+
this._update();
|
|
1112
|
+
this._setState(ScrollerState.Ready);
|
|
1113
|
+
this.start();
|
|
1114
|
+
this.emit("ready", void 0);
|
|
1115
|
+
this._readyResolvers.forEach((resolve) => resolve());
|
|
1116
|
+
this._readyResolvers = [];
|
|
1117
|
+
}
|
|
1118
|
+
_setState(state) {
|
|
1119
|
+
if (this._state !== state) {
|
|
1120
|
+
this._state = state;
|
|
1121
|
+
this._syncToObservers([
|
|
1122
|
+
"state",
|
|
1123
|
+
"isPending",
|
|
1124
|
+
"isReady",
|
|
1125
|
+
"isRunning",
|
|
1126
|
+
"isDestroyed"
|
|
1127
|
+
]);
|
|
1128
|
+
this.emit("changeState", state);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
_checkDestroyed() {
|
|
1132
|
+
if (this.isDestroyed) {
|
|
1133
|
+
const message = "already destroyed.";
|
|
1134
|
+
logger.error(message);
|
|
1135
|
+
throw new Error(message);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
_update(width, height) {
|
|
1139
|
+
this._updateContainerSize(width, height);
|
|
1140
|
+
this._updateScrollSize();
|
|
1141
|
+
this._updateScrollPositions();
|
|
1142
|
+
}
|
|
1143
|
+
_updateContainerSize(width, height) {
|
|
1144
|
+
const { el, _isBodyElement } = this;
|
|
1145
|
+
if (width === void 0) {
|
|
1146
|
+
if (!el) return;
|
|
1147
|
+
width = _isBodyElement ? document.documentElement.clientWidth : el.clientWidth;
|
|
1148
|
+
}
|
|
1149
|
+
if (height === void 0) {
|
|
1150
|
+
if (!el) return;
|
|
1151
|
+
height = _isBodyElement ? document.documentElement.clientHeight : el.clientHeight;
|
|
1152
|
+
}
|
|
1153
|
+
const { _containerWidth, _containerHeight } = this;
|
|
1154
|
+
this._containerWidth = width;
|
|
1155
|
+
this._containerHeight = height;
|
|
1156
|
+
if (width !== _containerWidth || height !== _containerHeight) {
|
|
1157
|
+
this._syncToObservers([
|
|
1158
|
+
"containerWidth",
|
|
1159
|
+
"containerHeight",
|
|
1160
|
+
"scrollableX",
|
|
1161
|
+
"scrollableY"
|
|
1162
|
+
]);
|
|
1163
|
+
this.emit("resize", {
|
|
1164
|
+
width,
|
|
1165
|
+
height
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
_updateScrollSize() {
|
|
1170
|
+
const { el, _scrollWidth, _scrollHeight } = this;
|
|
1171
|
+
if (!el) return;
|
|
1172
|
+
this._scrollWidth = el.scrollWidth;
|
|
1173
|
+
this._scrollHeight = el.scrollHeight;
|
|
1174
|
+
if (_scrollWidth !== this._scrollWidth || _scrollHeight !== this._scrollHeight) this._syncToObservers([
|
|
1175
|
+
"scrollWidth",
|
|
1176
|
+
"scrollHeight",
|
|
1177
|
+
"scrollableX",
|
|
1178
|
+
"scrollableY"
|
|
1179
|
+
]);
|
|
1180
|
+
}
|
|
1181
|
+
_startScrollSizeObserver() {
|
|
1182
|
+
if (!IN_WINDOW) return;
|
|
1183
|
+
this._stopScrollSizeObserver();
|
|
1184
|
+
if (this.scrollSizeObserver) this._scrollSizeObserverPollingId = window.setInterval(() => {
|
|
1185
|
+
if (!this.scrollSizeObserver || this.isDestroyed) {
|
|
1186
|
+
this._stopScrollSizeObserver();
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
this._updateScrollSize();
|
|
1190
|
+
}, this.scrollSizeObserver.interval);
|
|
1191
|
+
}
|
|
1192
|
+
_stopScrollSizeObserver() {
|
|
1193
|
+
if (this._scrollSizeObserverPollingId !== null) {
|
|
1194
|
+
clearInterval(this._scrollSizeObserverPollingId);
|
|
1195
|
+
this._scrollSizeObserverPollingId = null;
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
_updateScrollPositions() {
|
|
1199
|
+
if (!this.el) return;
|
|
1200
|
+
this._scrollTop = this.el.scrollTop;
|
|
1201
|
+
this._scrollLeft = this.el.scrollLeft;
|
|
1202
|
+
this._scrollBottom = this._scrollHeight - this._scrollTop - this._containerHeight;
|
|
1203
|
+
this._scrollRight = this._scrollWidth - this._scrollLeft - this._containerWidth;
|
|
1204
|
+
this._syncToObservers([
|
|
1205
|
+
"scrollTop",
|
|
1206
|
+
"scrollRight",
|
|
1207
|
+
"scrollBottom",
|
|
1208
|
+
"scrollLeft"
|
|
1209
|
+
]);
|
|
1210
|
+
}
|
|
1211
|
+
_startListeners() {
|
|
1212
|
+
this._stopListeners();
|
|
1213
|
+
this._scrollListener = () => {
|
|
1214
|
+
this._onScroll();
|
|
1215
|
+
};
|
|
1216
|
+
this._eventTarget.addEventListener("scroll", this._scrollListener, false);
|
|
1217
|
+
if (this._isRootElement) {
|
|
1218
|
+
this._resizeListener = () => {
|
|
1219
|
+
this._onResize();
|
|
1220
|
+
};
|
|
1221
|
+
window.addEventListener("resize", this._resizeListener, false);
|
|
1222
|
+
} else {
|
|
1223
|
+
this._resizeObserver = new ResizeObserver((entries) => {
|
|
1224
|
+
for (const entry of entries) {
|
|
1225
|
+
const { width, height } = entry.contentRect;
|
|
1226
|
+
this._onResize(width, height);
|
|
1227
|
+
}
|
|
1228
|
+
});
|
|
1229
|
+
this._el && this._resizeObserver.observe(this._el);
|
|
1230
|
+
}
|
|
1231
|
+
if (visibilityManager.isVisible) {
|
|
1232
|
+
this._scrollSizeObserverSuspended = false;
|
|
1233
|
+
this._startScrollSizeObserver();
|
|
1234
|
+
} else this._scrollSizeObserverSuspended = true;
|
|
1235
|
+
}
|
|
1236
|
+
_stopListeners() {
|
|
1237
|
+
if (this._scrollListener) {
|
|
1238
|
+
this._eventTarget.removeEventListener("scroll", this._scrollListener, false);
|
|
1239
|
+
delete this._scrollListener;
|
|
1240
|
+
}
|
|
1241
|
+
if (this._resizeListener) {
|
|
1242
|
+
if (this._isDocumentElement) {
|
|
1243
|
+
window.removeEventListener("resize", this._resizeListener, false);
|
|
1244
|
+
delete this._resizeListener;
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
if (this._resizeObserver && this._el) {
|
|
1248
|
+
this._resizeObserver.unobserve(this._el);
|
|
1249
|
+
this._resizeObserver.disconnect();
|
|
1250
|
+
delete this._resizeObserver;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
_clearScrollingJudgeTimer() {
|
|
1254
|
+
if (this._scrollingJudgeTimerId !== null) {
|
|
1255
|
+
clearTimeout(this._scrollingJudgeTimerId);
|
|
1256
|
+
this._scrollingJudgeTimerId = null;
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
_onResize(width, height) {
|
|
1260
|
+
this._update(width, height);
|
|
1261
|
+
}
|
|
1262
|
+
_triggerScrollTick(event) {
|
|
1263
|
+
const { _nowScrolling } = this;
|
|
1264
|
+
if (event === "scrollStart") {
|
|
1265
|
+
this._startX = this._scrollLeft;
|
|
1266
|
+
this._startY = this._scrollTop;
|
|
1267
|
+
this._lastTotalX = 0;
|
|
1268
|
+
this._lastTotalY = 0;
|
|
1269
|
+
this._nowScrolling = true;
|
|
1270
|
+
} else if (event === "scrollEnd") this._nowScrolling = false;
|
|
1271
|
+
if (_nowScrolling !== this._nowScrolling) this._syncToObservers("nowScrolling");
|
|
1272
|
+
this.emit(event, this.lastPayload);
|
|
1273
|
+
}
|
|
1274
|
+
_onScroll() {
|
|
1275
|
+
if (!this.scrollEnabled && this._el) {
|
|
1276
|
+
this._el.scrollLeft = this._scrollLeft;
|
|
1277
|
+
this._el.scrollTop = this._scrollTop;
|
|
1278
|
+
return;
|
|
1279
|
+
}
|
|
1280
|
+
const { _scrollTop, _scrollLeft, _lastAxis, _lastDirection, _lastXDirection, _lastYDirection } = this;
|
|
1281
|
+
this._updateScrollPositions();
|
|
1282
|
+
const tickedX = this._scrollLeft - _scrollLeft;
|
|
1283
|
+
const tickedY = this._scrollTop - _scrollTop;
|
|
1284
|
+
this._tickedX = tickedX;
|
|
1285
|
+
this._tickedY = tickedY;
|
|
1286
|
+
if (tickedX === tickedY) this._lastAxis = this.baseAxis;
|
|
1287
|
+
else this._lastAxis = Math.abs(tickedX) > Math.abs(tickedY) ? "x" : "y";
|
|
1288
|
+
if (_scrollTop < this._scrollTop) this._lastYDirection = "bottom";
|
|
1289
|
+
else if (_scrollTop > this._scrollTop) this._lastYDirection = "top";
|
|
1290
|
+
if (_scrollLeft < this._scrollLeft) this._lastXDirection = "right";
|
|
1291
|
+
else if (_scrollLeft > this._scrollLeft) this._lastXDirection = "left";
|
|
1292
|
+
this._lastDirection = this._lastAxis === "y" ? this._lastYDirection : this._lastXDirection;
|
|
1293
|
+
const axisIsChanged = this._lastAxis !== _lastAxis;
|
|
1294
|
+
const lastXDirectionIsChanged = this._lastXDirection !== _lastXDirection;
|
|
1295
|
+
const lastYDirectionIsChanged = this._lastYDirection !== _lastYDirection;
|
|
1296
|
+
const lastDirectionIsChanged = this._lastDirection !== _lastDirection;
|
|
1297
|
+
if (axisIsChanged) this.emit("changeAxis", this._lastAxis);
|
|
1298
|
+
if (lastXDirectionIsChanged) this.emit("changeLastXDirection", this._lastXDirection);
|
|
1299
|
+
if (lastYDirectionIsChanged) this.emit("changeLastYDirection", this._lastYDirection);
|
|
1300
|
+
if (lastDirectionIsChanged) this.emit("changeLastDirection", this._lastDirection);
|
|
1301
|
+
if (axisIsChanged || lastXDirectionIsChanged || lastYDirectionIsChanged || lastDirectionIsChanged) this._syncToObservers([
|
|
1302
|
+
"lastAxis",
|
|
1303
|
+
"lastDirection",
|
|
1304
|
+
"lastYDirection",
|
|
1305
|
+
"lastXDirection"
|
|
1306
|
+
]);
|
|
1307
|
+
if (this._nowScrolling) if (axisIsChanged || _lastAxis === "y" && lastYDirectionIsChanged || _lastAxis === "x" && lastXDirectionIsChanged) this._triggerScrollTick("scrollEnd");
|
|
1308
|
+
else {
|
|
1309
|
+
this._lastTotalX = this._scrollLeft - this._startX;
|
|
1310
|
+
this._lastTotalY = this._scrollTop - this._startY;
|
|
1311
|
+
this._triggerScrollTick("scroll");
|
|
1312
|
+
}
|
|
1313
|
+
if (!this._nowScrolling) {
|
|
1314
|
+
this._updateScrollSize();
|
|
1315
|
+
this._triggerScrollTick("scrollStart");
|
|
1316
|
+
}
|
|
1317
|
+
this._clearScrollingJudgeTimer();
|
|
1318
|
+
this._scrollingJudgeTimerId = window.setTimeout(() => {
|
|
1319
|
+
this._triggerScrollTick("scrollEnd");
|
|
1320
|
+
}, this.scrollingJudgeInterval);
|
|
1321
|
+
}
|
|
1322
|
+
_syncToObserver(observer, keys = scrollerObservableKeys) {
|
|
1323
|
+
for (const key of keys) observer[key] = this[key];
|
|
1324
|
+
}
|
|
1325
|
+
_syncToObservers(keys) {
|
|
1326
|
+
if (this._observers.length === 0) return;
|
|
1327
|
+
keys = typeof keys === "string" ? [keys] : keys;
|
|
1328
|
+
for (const observer of this._observers) this._syncToObserver(observer, keys);
|
|
1329
|
+
}
|
|
1330
|
+
_checkElement() {
|
|
1331
|
+
const { _el } = this;
|
|
1332
|
+
if (!_el) {
|
|
1333
|
+
const message = "missing element";
|
|
1334
|
+
logger.error(message);
|
|
1335
|
+
throw new Error(message);
|
|
1336
|
+
}
|
|
1337
|
+
return _el;
|
|
1338
|
+
}
|
|
1339
|
+
_createMergedScrollOptions(source) {
|
|
1340
|
+
return {
|
|
1341
|
+
container: this._checkElement(),
|
|
1342
|
+
...this.scrollSettingsDefaults,
|
|
1343
|
+
...source
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
_createMergedScrollToElementOptions(source) {
|
|
1347
|
+
const merged = {
|
|
1348
|
+
container: this._checkElement(),
|
|
1349
|
+
...this.scrollToElementSettingsDefaults,
|
|
1350
|
+
...source
|
|
1351
|
+
};
|
|
1352
|
+
let { _scrollToElementAdditionalOffset: additionalOffset } = this;
|
|
1353
|
+
if (!additionalOffset) return merged;
|
|
1354
|
+
if (typeof additionalOffset === "function") additionalOffset = additionalOffset(this);
|
|
1355
|
+
if (!additionalOffset) return merged;
|
|
1356
|
+
if (typeof additionalOffset === "number") additionalOffset = {
|
|
1357
|
+
x: additionalOffset,
|
|
1358
|
+
y: additionalOffset
|
|
1359
|
+
};
|
|
1360
|
+
let { offset } = merged;
|
|
1361
|
+
if (!offset) {
|
|
1362
|
+
merged.offset = additionalOffset;
|
|
1363
|
+
return merged;
|
|
1364
|
+
}
|
|
1365
|
+
if (typeof offset === "number") offset = {
|
|
1366
|
+
x: offset,
|
|
1367
|
+
y: offset
|
|
1368
|
+
};
|
|
1369
|
+
offset.x = (offset.x || 0) + (additionalOffset.x || 0);
|
|
1370
|
+
offset.y = (offset.y || 0) + (additionalOffset.y || 0);
|
|
1371
|
+
merged.offset = offset;
|
|
1372
|
+
return merged;
|
|
1373
|
+
}
|
|
1374
|
+
_clearScrollToResult() {
|
|
1375
|
+
if (!this._scrollToResult) return;
|
|
1376
|
+
this._scrollToResult = null;
|
|
1377
|
+
}
|
|
1378
|
+
_setScrollToResult(result) {
|
|
1379
|
+
this._scrollToResult = result;
|
|
1380
|
+
result.promise.then(() => {
|
|
1381
|
+
this._clearScrollToResult();
|
|
1382
|
+
});
|
|
1383
|
+
return result;
|
|
1384
|
+
}
|
|
1385
|
+
_updateScrollable() {
|
|
1386
|
+
if (this.scrollEnabled) this._scrollEnable();
|
|
1387
|
+
else this._scrollDisable();
|
|
1388
|
+
}
|
|
1389
|
+
_scrollEnable() {
|
|
1390
|
+
enableScroll(this._checkElement());
|
|
1391
|
+
}
|
|
1392
|
+
_scrollDisable() {
|
|
1393
|
+
const el = this._checkElement();
|
|
1394
|
+
this.cancel();
|
|
1395
|
+
disableScroll(el);
|
|
1396
|
+
}
|
|
1412
1397
|
};
|
|
1413
1398
|
|
|
1399
|
+
//#endregion
|
|
1414
1400
|
export { SCROLLABLE_KEY_CODES, Scroller, ScrollerState, defaultBaseSettings, defaultSettings, disableScroll, enableScroll, scrollBy, scrollTo, scrollToBottom, scrollToElement, scrollToElementSettingsDefaults, scrollToLeft, scrollToLeftBottom, scrollToLeftTop, scrollToRight, scrollToRightBottom, scrollToRightTop, scrollToSide, scrollToTop };
|
|
1415
|
-
//# sourceMappingURL=scroller.mjs.map
|
|
1416
1401
|
//# sourceMappingURL=scroller.mjs.map
|