-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
127 lines (89 loc) · 3.31 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import vs from 'virtual-scroll'
import sniffer from 'sniffer'
import { on, off } from 'dom-event'
export default class Manager {
constructor(opt = {}) {
if(!opt.callback)
console.error('You need to provide a callback function in the options')
this.el = opt.el || document.body
this.animating = false
this.index = 0
this.length = opt.length
this.options = {
direction: opt.direction || 'y',
loop: opt.loop || false,
delta: opt.delta || 1,
callback: opt.callback,
limitInertia: opt.limitInertia || false,
passive: opt.passive || undefined
}
this.vs = null
this.onScroll = this.onScroll.bind(this)
this.onKeyDown = this.onKeyDown.bind(this)
}
init() {
this.vs = new vs({
passive: this.options.passive,
limitInertia: this.options.limitInertia
})
this.vs.on(this.onScroll)
if(sniffer.isDesktop) {
on(document, 'keydown', this.onKeyDown)
}
}
destroy() {
this.vs.off(this.onScroll)
this.vs.destroy()
this.vs = null
if(sniffer.isDesktop) {
off(document, 'keydown', this.onKeyDown)
}
}
getNext(delta) {
const next = delta >= this.options.delta ? this.index + 1 : this.index - 1
return this.checkLoop(next)
}
checkLoop(next) {
return next < 0 ? this.options.loop ? this.length : 0 : next > this.length ? this.options.loop ? 0 : this.length : next
}
getEvent(index) {
const prev = this.options.direction == 'y' ? 'up' : 'left'
const next = this.options.direction == 'y' ? 'down' : 'right'
let direction = index > this.index ? next : prev
if (this.options.loop) {
if (this.index == 0 && index == this.length) direction = prev
if (this.index == this.length && index == 0) direction = next
}
return {
current: index,
previous: this.index,
direction: direction
}
}
onScroll(event) {
const { deltaX, deltaY } = event
const norm = this.options.direction == 'y' ? deltaY - (deltaY * 2) : deltaX - (deltaX * 2)
if(this.animating || norm > -this.options.delta && norm < this.options.delta) return
this.animating = true
this.callback(norm)
}
onKeyDown(e) {
const prev = this.options.direction == 'y' ? '38' : '37'
const next = this.options.direction == 'y' ? '40' : '39'
if(this.animating || e.keyCode != prev && e.keyCode != next) return
this.animating = true
this.callback(e.keyCode == next ? this.options.delta+1 : -(this.options.delta+1))
}
goTo(index) {
const check = this.checkLoop(index)
const event = this.getEvent(check)
this.index = check
this.options.callback(event)
}
callback(delta) {
const index = this.getNext(delta)
const event = this.getEvent(index)
this.index = index
this.options.callback(event, delta)
}
}