-
Notifications
You must be signed in to change notification settings - Fork 1
/
lib.js
141 lines (123 loc) · 4.08 KB
/
lib.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
var DISABLED = 'carousel-button-disabled';
/**
* Returns max leftOffset for the carousel
* @param {object} carousel
* @return {number}
*/
function getMaxScroll ( carousel ) {
return carousel.scrollWidth - carousel.clientWidth;
}
/**
* Returns an object that describes whether or not the next/previous buttons
* should be disabled.
* @param {integer} newIndex Index position of the new (just scrolled to) item
* @param {number} newPos Left offset of the new item
* @param {object} carousel
* @return {object}
*/
function isDisabled ( newIndex, newPos, carousel ) {
return {
previous: newIndex === 0,
next: newPos >= getMaxScroll( carousel )
};
}
/**
* When native scroll is utilized, estimate the scroll index position so
* that we have a starting spot if the user begins utilizing the next/previous
* buttons.
* @param {object} carousel
* @param {array} items
* @return {integer}
*/
function getScrollIndex ( carousel, items ) {
var carouselScroll = carousel.scrollLeft;
var carouselOffset = carousel.offsetLeft;
for ( var i = 0; i < items.length; ++i ) {
if ( ( items[ i ].offsetLeft - carouselOffset ) >= carouselScroll ) {
return i;
}
}
return -1;
}
/**
* Returns the left offset of the new item relative to the
* left offset of the carousel.
* @param {object} carousel
* @param {object} newItem
* @return {number}
*/
function getNewPosition ( carousel, newItem ) {
return newItem.offsetLeft - carousel.offsetLeft;
}
/**
* Calculates the new left offset of the carousel, and enables/disables
* the next/previous buttons accordingly.
* @param {object} carousel
* @param {array} items
* @param {integer} newIndex
* @param {object} next
* @param {object} previous
* @return {number}
*/
function syncPositionState ( carousel, items, newIndex, next, previous ) {
var newItem = items[ newIndex ];
var newPos = getNewPosition( carousel, newItem );
var disabled = isDisabled( newIndex, newPos, carousel );
toggleDisabled( previous, disabled.previous );
toggleDisabled( next, disabled.next );
return newPos;
}
/**
* Whether or not the carousel has items outside the visible area.
* @param {object} carousel
* @param {array} items
* @return {boolean}
*/
function carouselCanScroll ( carousel, items ) {
var lastItem = items[ items.length - 1 ];
var lastItemRightOffset = lastItem.offsetLeft - carousel.offsetLeft + lastItem.offsetWidth;
return lastItemRightOffset <= carousel.clientWidth;
}
/**
* Upon use of native scroll, estimate the carousel index position and sync
* the enabled/disabled state for the next/previous buttons.
* @param {object} carousel
* @param {array} items
* @param {object} next
* @param {object} previous
*/
function handleScroll ( carousel, items, next, previous ) {
var newIndex = Math.max(
getScrollIndex( carousel, items ),
0
);
syncPositionState( carousel, items, newIndex, next, previous );
carousel.currentIndex = newIndex;
}
/**
* Toggles the disabled class and attribute
* @param {object} el DOM element
* @param {boolean} shouldDisable
*/
function toggleDisabled ( el, shouldDisable ) {
el.classList.toggle( DISABLED, shouldDisable );
el.disabled = shouldDisable;
}
function getRotator ( carousel, items, next, previous ) {
return function ( reverse ) {
var currentIndex = carousel.currentIndex || 0;
var incrementor = reverse ? -1 : 1;
var direction = reverse ? previous : next;
var newIndex = currentIndex + incrementor;
if ( direction.classList.contains( DISABLED ) ) {
return;
}
carousel.scrollLeft = syncPositionState( carousel, items, newIndex, next, previous );
carousel.currentIndex = newIndex;
};
}
module.exports.toggleDisabled = toggleDisabled;
module.exports.getRotator = getRotator;
module.exports.getScrollIndex = getScrollIndex;
module.exports.carouselCanScroll = carouselCanScroll;
module.exports.handleScroll = handleScroll;