@momo-kits/carousel 0.0.8 → 0.0.12
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/Carousel.js +238 -249
- package/package.json +1 -1
package/Carousel.js
CHANGED
|
@@ -31,7 +31,7 @@ const AnimatedScrollView = Animated.createAnimatedComponent(ScrollView);
|
|
|
31
31
|
const IS_RTL = I18nManager.isRTL;
|
|
32
32
|
|
|
33
33
|
export default class Carousel extends PureComponent {
|
|
34
|
-
constructor(props) {
|
|
34
|
+
constructor (props) {
|
|
35
35
|
super(props);
|
|
36
36
|
|
|
37
37
|
this.state = {
|
|
@@ -78,36 +78,29 @@ export default class Carousel extends PureComponent {
|
|
|
78
78
|
// This bool aims at fixing an iOS bug due to scrollTo that triggers onMomentumScrollEnd.
|
|
79
79
|
// onMomentumScrollEnd fires this._snapScroll, thus creating an infinite loop.
|
|
80
80
|
this._ignoreNextMomentum = false;
|
|
81
|
-
this._animated = false;
|
|
82
81
|
|
|
83
82
|
// Warnings
|
|
84
83
|
if (!ViewPropTypes) {
|
|
85
|
-
console.warn(
|
|
86
|
-
It is recommended to use at least version 0.44 of React Native with the plugin`);
|
|
84
|
+
console.warn('react-native-snap-carousel: It is recommended to use at least version 0.44 of React Native with the plugin');
|
|
87
85
|
}
|
|
88
86
|
if (!props.vertical && (!props.sliderWidth || !props.itemWidth)) {
|
|
89
|
-
console.
|
|
90
|
-
for horizontal carousels`);
|
|
87
|
+
console.error('react-native-snap-carousel: You need to specify both `sliderWidth` and `itemWidth` for horizontal carousels');
|
|
91
88
|
}
|
|
92
89
|
if (props.vertical && (!props.sliderHeight || !props.itemHeight)) {
|
|
93
|
-
console.
|
|
94
|
-
for vertical carousels`);
|
|
90
|
+
console.error('react-native-snap-carousel: You need to specify both `sliderHeight` and `itemHeight` for vertical carousels');
|
|
95
91
|
}
|
|
96
92
|
if (props.apparitionDelay && !IS_IOS && !props.useScrollView) {
|
|
97
|
-
console.warn(
|
|
98
|
-
is not recommended since it can lead to rendering issues`);
|
|
93
|
+
console.warn('react-native-snap-carousel: Using `apparitionDelay` on Android is not recommended since it can lead to rendering issues');
|
|
99
94
|
}
|
|
100
95
|
if (props.customAnimationType || props.customAnimationOptions) {
|
|
101
|
-
console.warn(
|
|
102
|
-
customAnimationOptions have been renamed to activeAnimationType and activeAnimationOptions`);
|
|
96
|
+
console.warn('react-native-snap-carousel: Props `customAnimationType` and `customAnimationOptions` have been renamed to `activeAnimationType` and `activeAnimationOptions`');
|
|
103
97
|
}
|
|
104
98
|
if (props.onScrollViewScroll) {
|
|
105
|
-
console.
|
|
106
|
-
Use onScroll instead`);
|
|
99
|
+
console.error('react-native-snap-carousel: Prop `onScrollViewScroll` has been removed. Use `onScroll` instead');
|
|
107
100
|
}
|
|
108
101
|
}
|
|
109
102
|
|
|
110
|
-
componentDidMount() {
|
|
103
|
+
componentDidMount () {
|
|
111
104
|
const { apparitionDelay, autoplay, firstItem } = this.props;
|
|
112
105
|
const _firstItem = this._getFirstItem(firstItem);
|
|
113
106
|
const apparitionCallback = () => {
|
|
@@ -139,39 +132,31 @@ export default class Carousel extends PureComponent {
|
|
|
139
132
|
});
|
|
140
133
|
}
|
|
141
134
|
|
|
142
|
-
// shouldComponentUpdate(nextProps, nextState) {
|
|
143
|
-
//
|
|
144
|
-
// if (shouldOptimizeUpdates === false) {
|
|
135
|
+
// shouldComponentUpdate (nextProps, nextState) {
|
|
136
|
+
// if (this.props.shouldOptimizeUpdates === false) {
|
|
145
137
|
// return true;
|
|
138
|
+
// } else {
|
|
139
|
+
// return shallowCompare(this, nextProps, nextState);
|
|
146
140
|
// }
|
|
147
|
-
// if (shallowCompare(this.props, nextProps)) {
|
|
148
|
-
// return true;
|
|
149
|
-
// }
|
|
150
|
-
// if (shallowCompare(this.state, nextState)) {
|
|
151
|
-
// return true;
|
|
152
|
-
// }
|
|
153
|
-
// return false;
|
|
154
141
|
// }
|
|
155
142
|
|
|
156
|
-
|
|
143
|
+
componentDidUpdate (prevProps) {
|
|
157
144
|
const { interpolators } = this.state;
|
|
158
|
-
const {
|
|
159
|
-
|
|
160
|
-
} = this.props;
|
|
161
|
-
const itemsLength = this._getCustomDataLength(nextProps);
|
|
145
|
+
const { firstItem, itemHeight, itemWidth, scrollEnabled, sliderHeight, sliderWidth } = this.props;
|
|
146
|
+
const itemsLength = this._getCustomDataLength(this.props);
|
|
162
147
|
|
|
163
148
|
if (!itemsLength) {
|
|
164
149
|
return;
|
|
165
150
|
}
|
|
166
151
|
|
|
167
|
-
const nextFirstItem = this._getFirstItem(
|
|
152
|
+
const nextFirstItem = this._getFirstItem(firstItem, this.props);
|
|
168
153
|
let nextActiveItem = this._activeItem || this._activeItem === 0 ? this._activeItem : nextFirstItem;
|
|
169
154
|
|
|
170
|
-
const hasNewSliderWidth =
|
|
171
|
-
const hasNewSliderHeight =
|
|
172
|
-
const hasNewItemWidth =
|
|
173
|
-
const hasNewItemHeight =
|
|
174
|
-
const hasNewScrollEnabled =
|
|
155
|
+
const hasNewSliderWidth = sliderWidth && sliderWidth !== prevProps.sliderWidth;
|
|
156
|
+
const hasNewSliderHeight = sliderHeight && sliderHeight !== prevProps.sliderHeight;
|
|
157
|
+
const hasNewItemWidth = itemWidth && itemWidth !== prevProps.itemWidth;
|
|
158
|
+
const hasNewItemHeight = itemHeight && itemHeight !== prevProps.itemHeight;
|
|
159
|
+
const hasNewScrollEnabled = scrollEnabled !== prevProps.scrollEnabled;
|
|
175
160
|
|
|
176
161
|
// Prevent issues with dynamically removed items
|
|
177
162
|
if (nextActiveItem > itemsLength - 1) {
|
|
@@ -180,15 +165,15 @@ export default class Carousel extends PureComponent {
|
|
|
180
165
|
|
|
181
166
|
// Handle changing scrollEnabled independent of user -> carousel interaction
|
|
182
167
|
if (hasNewScrollEnabled) {
|
|
183
|
-
this._setScrollEnabled(
|
|
168
|
+
this._setScrollEnabled(scrollEnabled);
|
|
184
169
|
}
|
|
185
170
|
|
|
186
|
-
if (interpolators.length !== itemsLength || hasNewSliderWidth
|
|
187
|
-
|
|
171
|
+
if (interpolators.length !== itemsLength || hasNewSliderWidth ||
|
|
172
|
+
hasNewSliderHeight || hasNewItemWidth || hasNewItemHeight) {
|
|
188
173
|
this._activeItem = nextActiveItem;
|
|
189
174
|
this._previousItemsLength = itemsLength;
|
|
190
175
|
|
|
191
|
-
this._initPositionsAndInterpolators(
|
|
176
|
+
this._initPositionsAndInterpolators(this.props);
|
|
192
177
|
|
|
193
178
|
// Handle scroll issue when dynamically removing items (see #133)
|
|
194
179
|
// This also fixes first item's active state on Android
|
|
@@ -206,12 +191,12 @@ export default class Carousel extends PureComponent {
|
|
|
206
191
|
this._snapToItem(nextFirstItem, false, true, false, false);
|
|
207
192
|
}
|
|
208
193
|
|
|
209
|
-
if (
|
|
210
|
-
|
|
194
|
+
if (this.props.onScroll !== prevProps.onScroll) {
|
|
195
|
+
this._setScrollHandler(this.props);
|
|
211
196
|
}
|
|
212
197
|
}
|
|
213
198
|
|
|
214
|
-
componentWillUnmount() {
|
|
199
|
+
componentWillUnmount () {
|
|
215
200
|
this._mounted = false;
|
|
216
201
|
this.stopAutoplay();
|
|
217
202
|
clearTimeout(this._apparitionTimeout);
|
|
@@ -223,101 +208,98 @@ export default class Carousel extends PureComponent {
|
|
|
223
208
|
clearTimeout(this._lockScrollTimeout);
|
|
224
209
|
}
|
|
225
210
|
|
|
226
|
-
get realIndex() {
|
|
211
|
+
get realIndex () {
|
|
227
212
|
return this._activeItem;
|
|
228
213
|
}
|
|
229
214
|
|
|
230
|
-
get currentIndex() {
|
|
215
|
+
get currentIndex () {
|
|
231
216
|
return this._getDataIndex(this._activeItem);
|
|
232
217
|
}
|
|
233
218
|
|
|
234
|
-
get currentScrollPosition() {
|
|
219
|
+
get currentScrollPosition () {
|
|
235
220
|
return this._currentContentOffset;
|
|
236
221
|
}
|
|
237
222
|
|
|
238
223
|
_setScrollHandler(props) {
|
|
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
|
-
|
|
224
|
+
// Native driver for scroll events
|
|
225
|
+
const scrollEventConfig = {
|
|
226
|
+
listener: this._onScroll,
|
|
227
|
+
useNativeDriver: true,
|
|
228
|
+
};
|
|
229
|
+
this._scrollPos = new Animated.Value(0);
|
|
230
|
+
const argMapping = props.vertical
|
|
231
|
+
? [{ nativeEvent: { contentOffset: { y: this._scrollPos } } }]
|
|
232
|
+
: [{ nativeEvent: { contentOffset: { x: this._scrollPos } } }];
|
|
233
|
+
|
|
234
|
+
if (props.onScroll && Array.isArray(props.onScroll._argMapping)) {
|
|
235
|
+
// Because of a react-native issue https://github.com/facebook/react-native/issues/13294
|
|
236
|
+
argMapping.pop();
|
|
237
|
+
const [ argMap ] = props.onScroll._argMapping;
|
|
238
|
+
if (argMap && argMap.nativeEvent && argMap.nativeEvent.contentOffset) {
|
|
239
|
+
// Shares the same animated value passed in props
|
|
240
|
+
this._scrollPos =
|
|
241
|
+
argMap.nativeEvent.contentOffset.x ||
|
|
242
|
+
argMap.nativeEvent.contentOffset.y ||
|
|
243
|
+
this._scrollPos;
|
|
244
|
+
}
|
|
245
|
+
argMapping.push(...props.onScroll._argMapping);
|
|
246
|
+
}
|
|
247
|
+
this._onScrollHandler = Animated.event(
|
|
248
|
+
argMapping,
|
|
249
|
+
scrollEventConfig
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
_needsScrollView () {
|
|
268
254
|
const { useScrollView } = this.props;
|
|
269
255
|
return useScrollView || !AnimatedFlatList || this._shouldUseStackLayout() || this._shouldUseTinderLayout();
|
|
270
256
|
}
|
|
271
257
|
|
|
272
|
-
_needsRTLAdaptations() {
|
|
258
|
+
_needsRTLAdaptations () {
|
|
273
259
|
const { vertical } = this.props;
|
|
274
260
|
return IS_RTL && !IS_IOS && !vertical;
|
|
275
261
|
}
|
|
276
262
|
|
|
277
|
-
_canLockScroll() {
|
|
263
|
+
_canLockScroll () {
|
|
278
264
|
const { scrollEnabled, enableMomentum, lockScrollWhileSnapping } = this.props;
|
|
279
265
|
return scrollEnabled && !enableMomentum && lockScrollWhileSnapping;
|
|
280
266
|
}
|
|
281
267
|
|
|
282
|
-
_enableLoop() {
|
|
268
|
+
_enableLoop () {
|
|
283
269
|
const { data, enableSnap, loop } = this.props;
|
|
284
270
|
return enableSnap && loop && data && data.length && data.length > 1;
|
|
285
271
|
}
|
|
286
272
|
|
|
287
|
-
_shouldAnimateSlides(props = this.props) {
|
|
288
|
-
const {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
||
|
|
293
|
-
||
|
|
294
|
-
||
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
_shouldUseCustomAnimation() {
|
|
273
|
+
_shouldAnimateSlides (props = this.props) {
|
|
274
|
+
const { inactiveSlideOpacity, inactiveSlideScale, scrollInterpolator, slideInterpolatedStyle } = props;
|
|
275
|
+
return inactiveSlideOpacity < 1 ||
|
|
276
|
+
inactiveSlideScale < 1 ||
|
|
277
|
+
!!scrollInterpolator ||
|
|
278
|
+
!!slideInterpolatedStyle ||
|
|
279
|
+
this._shouldUseShiftLayout() ||
|
|
280
|
+
this._shouldUseStackLayout() ||
|
|
281
|
+
this._shouldUseTinderLayout();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
_shouldUseCustomAnimation () {
|
|
301
285
|
const { activeAnimationOptions } = this.props;
|
|
302
286
|
return !!activeAnimationOptions && !this._shouldUseStackLayout() && !this._shouldUseTinderLayout();
|
|
303
287
|
}
|
|
304
288
|
|
|
305
|
-
_shouldUseShiftLayout() {
|
|
289
|
+
_shouldUseShiftLayout () {
|
|
306
290
|
const { inactiveSlideShift, layout } = this.props;
|
|
307
291
|
return layout === 'default' && inactiveSlideShift !== 0;
|
|
308
292
|
}
|
|
309
293
|
|
|
310
|
-
_shouldUseStackLayout() {
|
|
311
|
-
|
|
312
|
-
return layout === 'stack';
|
|
294
|
+
_shouldUseStackLayout () {
|
|
295
|
+
return this.props.layout === 'stack';
|
|
313
296
|
}
|
|
314
297
|
|
|
315
|
-
_shouldUseTinderLayout() {
|
|
316
|
-
|
|
317
|
-
return layout === 'tinder';
|
|
298
|
+
_shouldUseTinderLayout () {
|
|
299
|
+
return this.props.layout === 'tinder';
|
|
318
300
|
}
|
|
319
301
|
|
|
320
|
-
_getCustomData(props = this.props) {
|
|
302
|
+
_getCustomData (props = this.props) {
|
|
321
303
|
const { data, loopClonesPerSide } = props;
|
|
322
304
|
const dataLength = data && data.length;
|
|
323
305
|
|
|
@@ -336,7 +318,7 @@ export default class Carousel extends PureComponent {
|
|
|
336
318
|
const dataMultiplier = Math.floor(loopClonesPerSide / dataLength);
|
|
337
319
|
const remainder = loopClonesPerSide % dataLength;
|
|
338
320
|
|
|
339
|
-
for (let i = 0; i < dataMultiplier; i
|
|
321
|
+
for (let i = 0; i < dataMultiplier; i++) {
|
|
340
322
|
previousItems.push(...data);
|
|
341
323
|
nextItems.push(...data);
|
|
342
324
|
}
|
|
@@ -347,10 +329,11 @@ export default class Carousel extends PureComponent {
|
|
|
347
329
|
previousItems = data.slice(-loopClonesPerSide);
|
|
348
330
|
nextItems = data.slice(0, loopClonesPerSide);
|
|
349
331
|
}
|
|
332
|
+
|
|
350
333
|
return previousItems.concat(data, nextItems);
|
|
351
334
|
}
|
|
352
335
|
|
|
353
|
-
_getCustomDataLength(props = this.props) {
|
|
336
|
+
_getCustomDataLength (props = this.props) {
|
|
354
337
|
const { data, loopClonesPerSide } = props;
|
|
355
338
|
const dataLength = data && data.length;
|
|
356
339
|
|
|
@@ -361,7 +344,7 @@ export default class Carousel extends PureComponent {
|
|
|
361
344
|
return this._enableLoop() ? dataLength + (2 * loopClonesPerSide) : dataLength;
|
|
362
345
|
}
|
|
363
346
|
|
|
364
|
-
_getCustomIndex(index, props = this.props) {
|
|
347
|
+
_getCustomIndex (index, props = this.props) {
|
|
365
348
|
const itemsLength = this._getCustomDataLength(props);
|
|
366
349
|
|
|
367
350
|
if (!itemsLength || (!index && index !== 0)) {
|
|
@@ -371,7 +354,7 @@ export default class Carousel extends PureComponent {
|
|
|
371
354
|
return this._needsRTLAdaptations() ? itemsLength - index - 1 : index;
|
|
372
355
|
}
|
|
373
356
|
|
|
374
|
-
_getDataIndex(index) {
|
|
357
|
+
_getDataIndex (index) {
|
|
375
358
|
const { data, loopClonesPerSide } = this.props;
|
|
376
359
|
const dataLength = data && data.length;
|
|
377
360
|
|
|
@@ -380,10 +363,10 @@ export default class Carousel extends PureComponent {
|
|
|
380
363
|
}
|
|
381
364
|
|
|
382
365
|
if (index >= dataLength + loopClonesPerSide) {
|
|
383
|
-
return loopClonesPerSide > dataLength
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
} if (index < loopClonesPerSide) {
|
|
366
|
+
return loopClonesPerSide > dataLength ?
|
|
367
|
+
(index - loopClonesPerSide) % dataLength :
|
|
368
|
+
index - dataLength - loopClonesPerSide;
|
|
369
|
+
} else if (index < loopClonesPerSide) {
|
|
387
370
|
// TODO: is there a simpler way of determining the interpolated index?
|
|
388
371
|
if (loopClonesPerSide > dataLength) {
|
|
389
372
|
const baseDataIndexes = [];
|
|
@@ -391,29 +374,31 @@ export default class Carousel extends PureComponent {
|
|
|
391
374
|
const dataMultiplier = Math.floor(loopClonesPerSide / dataLength);
|
|
392
375
|
const remainder = loopClonesPerSide % dataLength;
|
|
393
376
|
|
|
394
|
-
for (let i = 0; i < dataLength; i
|
|
377
|
+
for (let i = 0; i < dataLength; i++) {
|
|
395
378
|
baseDataIndexes.push(i);
|
|
396
379
|
}
|
|
397
380
|
|
|
398
|
-
for (let j = 0; j < dataMultiplier; j
|
|
381
|
+
for (let j = 0; j < dataMultiplier; j++) {
|
|
399
382
|
dataIndexes.push(...baseDataIndexes);
|
|
400
383
|
}
|
|
401
384
|
|
|
402
385
|
dataIndexes.unshift(...baseDataIndexes.slice(-remainder));
|
|
403
386
|
return dataIndexes[index];
|
|
387
|
+
} else {
|
|
388
|
+
return index + dataLength - loopClonesPerSide;
|
|
404
389
|
}
|
|
405
|
-
|
|
390
|
+
} else {
|
|
391
|
+
return index - loopClonesPerSide;
|
|
406
392
|
}
|
|
407
|
-
return index - loopClonesPerSide;
|
|
408
393
|
}
|
|
409
394
|
|
|
410
395
|
// Used with `snapToItem()` and 'PaginationDot'
|
|
411
|
-
_getPositionIndex(index) {
|
|
396
|
+
_getPositionIndex (index) {
|
|
412
397
|
const { loop, loopClonesPerSide } = this.props;
|
|
413
398
|
return loop ? index + loopClonesPerSide : index;
|
|
414
399
|
}
|
|
415
400
|
|
|
416
|
-
_getFirstItem(index, props = this.props) {
|
|
401
|
+
_getFirstItem (index, props = this.props) {
|
|
417
402
|
const { loopClonesPerSide } = props;
|
|
418
403
|
const itemsLength = this._getCustomDataLength(props);
|
|
419
404
|
|
|
@@ -424,10 +409,10 @@ export default class Carousel extends PureComponent {
|
|
|
424
409
|
return this._enableLoop() ? index + loopClonesPerSide : index;
|
|
425
410
|
}
|
|
426
411
|
|
|
427
|
-
_getWrappedRef() {
|
|
412
|
+
_getWrappedRef () {
|
|
428
413
|
if (this._carouselRef && (
|
|
429
|
-
(this._needsScrollView() && this._carouselRef.scrollTo)
|
|
430
|
-
|
|
414
|
+
(this._needsScrollView() && this._carouselRef.scrollTo) ||
|
|
415
|
+
(!this._needsScrollView() && this._carouselRef.scrollToOffset)
|
|
431
416
|
)) {
|
|
432
417
|
return this._carouselRef;
|
|
433
418
|
}
|
|
@@ -436,11 +421,11 @@ export default class Carousel extends PureComponent {
|
|
|
436
421
|
return this._carouselRef && this._carouselRef.getNode && this._carouselRef.getNode();
|
|
437
422
|
}
|
|
438
423
|
|
|
439
|
-
_getScrollEnabled() {
|
|
424
|
+
_getScrollEnabled () {
|
|
440
425
|
return this._scrollEnabled;
|
|
441
426
|
}
|
|
442
427
|
|
|
443
|
-
_setScrollEnabled(scrollEnabled = true) {
|
|
428
|
+
_setScrollEnabled (scrollEnabled = true) {
|
|
444
429
|
const wrappedRef = this._getWrappedRef();
|
|
445
430
|
|
|
446
431
|
if (!wrappedRef || !wrappedRef.setNativeProps) {
|
|
@@ -453,56 +438,54 @@ export default class Carousel extends PureComponent {
|
|
|
453
438
|
this._scrollEnabled = scrollEnabled;
|
|
454
439
|
}
|
|
455
440
|
|
|
456
|
-
_getKeyExtractor(item, index) {
|
|
441
|
+
_getKeyExtractor (item, index) {
|
|
457
442
|
return this._needsScrollView() ? `scrollview-item-${index}` : `flatlist-item-${index}`;
|
|
458
443
|
}
|
|
459
444
|
|
|
460
|
-
_getScrollOffset(event) {
|
|
445
|
+
_getScrollOffset (event) {
|
|
461
446
|
const { vertical } = this.props;
|
|
462
|
-
return (event && event.nativeEvent && event.nativeEvent.contentOffset
|
|
463
|
-
|
|
447
|
+
return (event && event.nativeEvent && event.nativeEvent.contentOffset &&
|
|
448
|
+
event.nativeEvent.contentOffset[vertical ? 'y' : 'x']) || 0;
|
|
464
449
|
}
|
|
465
450
|
|
|
466
|
-
_getContainerInnerMargin(opposite = false) {
|
|
467
|
-
const {
|
|
468
|
-
sliderWidth, sliderHeight, itemWidth, itemHeight, vertical, activeSlideAlignment
|
|
469
|
-
} = this.props;
|
|
451
|
+
_getContainerInnerMargin (opposite = false) {
|
|
452
|
+
const { sliderWidth, sliderHeight, itemWidth, itemHeight, vertical, activeSlideAlignment } = this.props;
|
|
470
453
|
|
|
471
|
-
if ((activeSlideAlignment === 'start' && !opposite)
|
|
472
|
-
|
|
454
|
+
if ((activeSlideAlignment === 'start' && !opposite) ||
|
|
455
|
+
(activeSlideAlignment === 'end' && opposite)) {
|
|
473
456
|
return 0;
|
|
474
|
-
} if ((activeSlideAlignment === 'end' && !opposite)
|
|
475
|
-
|
|
457
|
+
} else if ((activeSlideAlignment === 'end' && !opposite) ||
|
|
458
|
+
(activeSlideAlignment === 'start' && opposite)) {
|
|
476
459
|
return vertical ? sliderHeight - itemHeight : sliderWidth - itemWidth;
|
|
460
|
+
} else {
|
|
461
|
+
return vertical ? (sliderHeight - itemHeight) / 2 : (sliderWidth - itemWidth) / 2;
|
|
477
462
|
}
|
|
478
|
-
return vertical ? (sliderHeight - itemHeight) / 2 : (sliderWidth - itemWidth) / 2;
|
|
479
463
|
}
|
|
480
464
|
|
|
481
|
-
_getViewportOffset() {
|
|
482
|
-
const {
|
|
483
|
-
sliderWidth, sliderHeight, itemWidth, itemHeight, vertical, activeSlideAlignment
|
|
484
|
-
} = this.props;
|
|
465
|
+
_getViewportOffset () {
|
|
466
|
+
const { sliderWidth, sliderHeight, itemWidth, itemHeight, vertical, activeSlideAlignment } = this.props;
|
|
485
467
|
|
|
486
468
|
if (activeSlideAlignment === 'start') {
|
|
487
469
|
return vertical ? itemHeight / 2 : itemWidth / 2;
|
|
488
|
-
} if (activeSlideAlignment === 'end') {
|
|
489
|
-
return vertical
|
|
490
|
-
|
|
491
|
-
|
|
470
|
+
} else if (activeSlideAlignment === 'end') {
|
|
471
|
+
return vertical ?
|
|
472
|
+
sliderHeight - (itemHeight / 2) :
|
|
473
|
+
sliderWidth - (itemWidth / 2);
|
|
474
|
+
} else {
|
|
475
|
+
return vertical ? sliderHeight / 2 : sliderWidth / 2;
|
|
492
476
|
}
|
|
493
|
-
return vertical ? sliderHeight / 2 : sliderWidth / 2;
|
|
494
477
|
}
|
|
495
478
|
|
|
496
|
-
_getCenter(offset) {
|
|
479
|
+
_getCenter (offset) {
|
|
497
480
|
return offset + this._getViewportOffset() - this._getContainerInnerMargin();
|
|
498
481
|
}
|
|
499
482
|
|
|
500
|
-
_getActiveItem(offset) {
|
|
483
|
+
_getActiveItem (offset) {
|
|
501
484
|
const { activeSlideOffset, swipeThreshold } = this.props;
|
|
502
485
|
const center = this._getCenter(offset);
|
|
503
486
|
const centerOffset = activeSlideOffset || swipeThreshold;
|
|
504
487
|
|
|
505
|
-
for (let i = 0; i < this._positions.length; i
|
|
488
|
+
for (let i = 0; i < this._positions.length; i++) {
|
|
506
489
|
const { start, end } = this._positions[i];
|
|
507
490
|
if (center + centerOffset >= start && center - centerOffset <= end) {
|
|
508
491
|
return i;
|
|
@@ -517,17 +500,15 @@ export default class Carousel extends PureComponent {
|
|
|
517
500
|
return 0;
|
|
518
501
|
}
|
|
519
502
|
|
|
520
|
-
_initPositionsAndInterpolators(props = this.props) {
|
|
521
|
-
const {
|
|
522
|
-
data, itemWidth, itemHeight, scrollInterpolator, vertical
|
|
523
|
-
} = props;
|
|
503
|
+
_initPositionsAndInterpolators (props = this.props) {
|
|
504
|
+
const { data, itemWidth, itemHeight, scrollInterpolator, vertical } = props;
|
|
524
505
|
const sizeRef = vertical ? itemHeight : itemWidth;
|
|
525
506
|
|
|
526
507
|
if (!data || !data.length) {
|
|
527
508
|
return;
|
|
528
509
|
}
|
|
529
510
|
|
|
530
|
-
|
|
511
|
+
let interpolators = [];
|
|
531
512
|
this._positions = [];
|
|
532
513
|
|
|
533
514
|
this._getCustomData(props).forEach((itemData, index) => {
|
|
@@ -554,7 +535,7 @@ export default class Carousel extends PureComponent {
|
|
|
554
535
|
interpolator = tinderScrollInterpolator(_index, props);
|
|
555
536
|
}
|
|
556
537
|
|
|
557
|
-
if (!interpolator || !interpolator
|
|
538
|
+
if (!interpolator || !interpolator.inputRange || !interpolator.outputRange) {
|
|
558
539
|
interpolator = defaultScrollInterpolator(_index, props);
|
|
559
540
|
}
|
|
560
541
|
|
|
@@ -566,10 +547,11 @@ export default class Carousel extends PureComponent {
|
|
|
566
547
|
|
|
567
548
|
interpolators.push(animatedValue);
|
|
568
549
|
});
|
|
550
|
+
|
|
569
551
|
this.setState({ interpolators });
|
|
570
552
|
}
|
|
571
553
|
|
|
572
|
-
_getSlideAnimation(index, toValue) {
|
|
554
|
+
_getSlideAnimation (index, toValue) {
|
|
573
555
|
const { interpolators } = this.state;
|
|
574
556
|
const { activeAnimationType, activeAnimationOptions } = this.props;
|
|
575
557
|
|
|
@@ -583,11 +565,11 @@ export default class Carousel extends PureComponent {
|
|
|
583
565
|
isInteraction: false,
|
|
584
566
|
useNativeDriver: true,
|
|
585
567
|
...activeAnimationOptions,
|
|
586
|
-
toValue
|
|
568
|
+
toValue: toValue
|
|
587
569
|
};
|
|
588
570
|
|
|
589
571
|
return Animated.parallel([
|
|
590
|
-
Animated
|
|
572
|
+
Animated['timing'](
|
|
591
573
|
animatedValue,
|
|
592
574
|
{ ...animationCommonOptions, easing: Easing.linear }
|
|
593
575
|
),
|
|
@@ -598,18 +580,18 @@ export default class Carousel extends PureComponent {
|
|
|
598
580
|
]);
|
|
599
581
|
}
|
|
600
582
|
|
|
601
|
-
_playCustomSlideAnimation(current, next) {
|
|
583
|
+
_playCustomSlideAnimation (current, next) {
|
|
602
584
|
const { interpolators } = this.state;
|
|
603
585
|
const itemsLength = this._getCustomDataLength();
|
|
604
586
|
const _currentIndex = this._getCustomIndex(current);
|
|
605
587
|
const _currentDataIndex = this._getDataIndex(_currentIndex);
|
|
606
588
|
const _nextIndex = this._getCustomIndex(next);
|
|
607
589
|
const _nextDataIndex = this._getDataIndex(_nextIndex);
|
|
608
|
-
|
|
590
|
+
let animations = [];
|
|
609
591
|
|
|
610
592
|
// Keep animations in sync when looping
|
|
611
593
|
if (this._enableLoop()) {
|
|
612
|
-
for (let i = 0; i < itemsLength; i
|
|
594
|
+
for (let i = 0; i < itemsLength; i++) {
|
|
613
595
|
if (this._getDataIndex(i) === _currentDataIndex && interpolators[i]) {
|
|
614
596
|
animations.push(this._getSlideAnimation(i, 0));
|
|
615
597
|
} else if (this._getDataIndex(i) === _nextDataIndex && interpolators[i]) {
|
|
@@ -628,7 +610,7 @@ export default class Carousel extends PureComponent {
|
|
|
628
610
|
Animated.parallel(animations, { stopTogether: false }).start();
|
|
629
611
|
}
|
|
630
612
|
|
|
631
|
-
_hackActiveSlideAnimation(index, goTo, force = false) {
|
|
613
|
+
_hackActiveSlideAnimation (index, goTo, force = false) {
|
|
632
614
|
const { data } = this.props;
|
|
633
615
|
|
|
634
616
|
if (!this._mounted || !this._carouselRef || !this._positions[index] || (!force && this._enableLoop())) {
|
|
@@ -652,7 +634,7 @@ export default class Carousel extends PureComponent {
|
|
|
652
634
|
}, 50); // works randomly when set to '0'
|
|
653
635
|
}
|
|
654
636
|
|
|
655
|
-
_lockScroll() {
|
|
637
|
+
_lockScroll () {
|
|
656
638
|
const { lockScrollTimeoutDuration } = this.props;
|
|
657
639
|
clearTimeout(this._lockScrollTimeout);
|
|
658
640
|
this._lockScrollTimeout = setTimeout(() => {
|
|
@@ -661,17 +643,17 @@ export default class Carousel extends PureComponent {
|
|
|
661
643
|
this._setScrollEnabled(false);
|
|
662
644
|
}
|
|
663
645
|
|
|
664
|
-
_releaseScroll() {
|
|
646
|
+
_releaseScroll () {
|
|
665
647
|
clearTimeout(this._lockScrollTimeout);
|
|
666
648
|
this._setScrollEnabled(true);
|
|
667
649
|
}
|
|
668
650
|
|
|
669
|
-
_repositionScroll(index) {
|
|
651
|
+
_repositionScroll (index) {
|
|
670
652
|
const { data, loopClonesPerSide } = this.props;
|
|
671
653
|
const dataLength = data && data.length;
|
|
672
654
|
|
|
673
|
-
if (!this._enableLoop() || !dataLength
|
|
674
|
-
|
|
655
|
+
if (!this._enableLoop() || !dataLength ||
|
|
656
|
+
(index >= loopClonesPerSide && index < dataLength + loopClonesPerSide)) {
|
|
675
657
|
return;
|
|
676
658
|
}
|
|
677
659
|
|
|
@@ -682,10 +664,11 @@ export default class Carousel extends PureComponent {
|
|
|
682
664
|
} else if (index < loopClonesPerSide) {
|
|
683
665
|
repositionTo = index + dataLength;
|
|
684
666
|
}
|
|
667
|
+
|
|
685
668
|
this._snapToItem(repositionTo, false, false, false, false);
|
|
686
669
|
}
|
|
687
670
|
|
|
688
|
-
_scrollTo(offset, animated = true) {
|
|
671
|
+
_scrollTo (offset, animated = true) {
|
|
689
672
|
const { vertical } = this.props;
|
|
690
673
|
const wrappedRef = this._getWrappedRef();
|
|
691
674
|
|
|
@@ -704,25 +687,22 @@ export default class Carousel extends PureComponent {
|
|
|
704
687
|
animated
|
|
705
688
|
};
|
|
706
689
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
}
|
|
713
|
-
}, (!animated && this._animated) ? 200 : 0);
|
|
714
|
-
|
|
715
|
-
this._animated = animated;
|
|
690
|
+
if (this._needsScrollView()) {
|
|
691
|
+
wrappedRef.scrollTo(options);
|
|
692
|
+
} else {
|
|
693
|
+
wrappedRef.scrollToOffset(options);
|
|
694
|
+
}
|
|
716
695
|
}
|
|
717
696
|
|
|
718
|
-
_onScroll(event) {
|
|
697
|
+
_onScroll (event) {
|
|
719
698
|
const { callbackOffsetMargin, enableMomentum, onScroll } = this.props;
|
|
720
699
|
|
|
721
700
|
const scrollOffset = event ? this._getScrollOffset(event) : this._currentContentOffset;
|
|
722
701
|
const nextActiveItem = this._getActiveItem(scrollOffset);
|
|
723
702
|
const itemReached = nextActiveItem === this._itemToSnapTo;
|
|
724
|
-
const scrollConditions =
|
|
725
|
-
|
|
703
|
+
const scrollConditions =
|
|
704
|
+
scrollOffset >= this._scrollOffsetRef - callbackOffsetMargin &&
|
|
705
|
+
scrollOffset <= this._scrollOffsetRef + callbackOffsetMargin;
|
|
726
706
|
|
|
727
707
|
this._currentContentOffset = scrollOffset;
|
|
728
708
|
this._onScrollTriggered = true;
|
|
@@ -765,17 +745,18 @@ export default class Carousel extends PureComponent {
|
|
|
765
745
|
}
|
|
766
746
|
}
|
|
767
747
|
}
|
|
768
|
-
|
|
769
|
-
|
|
748
|
+
|
|
749
|
+
if (nextActiveItem === this._itemToSnapTo &&
|
|
750
|
+
scrollOffset === this._scrollOffsetRef) {
|
|
770
751
|
this._repositionScroll(nextActiveItem);
|
|
771
752
|
}
|
|
772
753
|
|
|
773
|
-
if (typeof onScroll ===
|
|
754
|
+
if (typeof onScroll === "function" && event) {
|
|
774
755
|
onScroll(event);
|
|
775
756
|
}
|
|
776
757
|
}
|
|
777
758
|
|
|
778
|
-
_onStartShouldSetResponderCapture(event) {
|
|
759
|
+
_onStartShouldSetResponderCapture (event) {
|
|
779
760
|
const { onStartShouldSetResponderCapture } = this.props;
|
|
780
761
|
|
|
781
762
|
if (onStartShouldSetResponderCapture) {
|
|
@@ -785,34 +766,34 @@ export default class Carousel extends PureComponent {
|
|
|
785
766
|
return this._getScrollEnabled();
|
|
786
767
|
}
|
|
787
768
|
|
|
788
|
-
_onTouchStart() {
|
|
789
|
-
const { onTouchStart } = this.props
|
|
769
|
+
_onTouchStart () {
|
|
770
|
+
const { onTouchStart } = this.props
|
|
790
771
|
|
|
791
772
|
// `onTouchStart` is fired even when `scrollEnabled` is set to `false`
|
|
792
773
|
if (this._getScrollEnabled() !== false && this._autoplaying) {
|
|
793
|
-
this.
|
|
774
|
+
this.pauseAutoPlay();
|
|
794
775
|
}
|
|
795
776
|
|
|
796
777
|
if (onTouchStart) {
|
|
797
|
-
onTouchStart()
|
|
778
|
+
onTouchStart()
|
|
798
779
|
}
|
|
799
780
|
}
|
|
800
781
|
|
|
801
|
-
_onTouchEnd() {
|
|
802
|
-
const { onTouchEnd
|
|
782
|
+
_onTouchEnd () {
|
|
783
|
+
const { onTouchEnd } = this.props
|
|
803
784
|
|
|
804
|
-
if (this._getScrollEnabled() !== false &&
|
|
785
|
+
if (this._getScrollEnabled() !== false && this._autoplay && !this._autoplaying) {
|
|
805
786
|
// This event is buggy on Android, so a fallback is provided in _onScrollEnd()
|
|
806
787
|
this.startAutoplay();
|
|
807
788
|
}
|
|
808
789
|
|
|
809
790
|
if (onTouchEnd) {
|
|
810
|
-
onTouchEnd()
|
|
791
|
+
onTouchEnd()
|
|
811
792
|
}
|
|
812
793
|
}
|
|
813
794
|
|
|
814
795
|
// Used when `enableSnap` is ENABLED
|
|
815
|
-
_onScrollBeginDrag(event) {
|
|
796
|
+
_onScrollBeginDrag (event) {
|
|
816
797
|
const { onScrollBeginDrag } = this.props;
|
|
817
798
|
|
|
818
799
|
if (!this._getScrollEnabled()) {
|
|
@@ -830,11 +811,11 @@ export default class Carousel extends PureComponent {
|
|
|
830
811
|
}
|
|
831
812
|
|
|
832
813
|
// Used when `enableMomentum` is DISABLED
|
|
833
|
-
_onScrollEndDrag(event) {
|
|
814
|
+
_onScrollEndDrag (event) {
|
|
834
815
|
const { onScrollEndDrag } = this.props;
|
|
835
816
|
|
|
836
817
|
if (this._carouselRef) {
|
|
837
|
-
|
|
818
|
+
this._onScrollEnd && this._onScrollEnd();
|
|
838
819
|
}
|
|
839
820
|
|
|
840
821
|
if (onScrollEndDrag) {
|
|
@@ -843,11 +824,11 @@ export default class Carousel extends PureComponent {
|
|
|
843
824
|
}
|
|
844
825
|
|
|
845
826
|
// Used when `enableMomentum` is ENABLED
|
|
846
|
-
_onMomentumScrollEnd(event) {
|
|
827
|
+
_onMomentumScrollEnd (event) {
|
|
847
828
|
const { onMomentumScrollEnd } = this.props;
|
|
848
829
|
|
|
849
830
|
if (this._carouselRef) {
|
|
850
|
-
|
|
831
|
+
this._onScrollEnd && this._onScrollEnd();
|
|
851
832
|
}
|
|
852
833
|
|
|
853
834
|
if (onMomentumScrollEnd) {
|
|
@@ -855,8 +836,8 @@ export default class Carousel extends PureComponent {
|
|
|
855
836
|
}
|
|
856
837
|
}
|
|
857
838
|
|
|
858
|
-
_onScrollEnd() {
|
|
859
|
-
const {
|
|
839
|
+
_onScrollEnd (event) {
|
|
840
|
+
const { autoplayDelay, enableSnap } = this.props;
|
|
860
841
|
|
|
861
842
|
if (this._ignoreNextMomentum) {
|
|
862
843
|
// iOS fix
|
|
@@ -864,6 +845,10 @@ export default class Carousel extends PureComponent {
|
|
|
864
845
|
return;
|
|
865
846
|
}
|
|
866
847
|
|
|
848
|
+
if (this._currentContentOffset === this._scrollEndOffset) {
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
|
|
867
852
|
this._scrollEndOffset = this._currentContentOffset;
|
|
868
853
|
this._scrollEndActive = this._getActiveItem(this._scrollEndOffset);
|
|
869
854
|
|
|
@@ -873,7 +858,7 @@ export default class Carousel extends PureComponent {
|
|
|
873
858
|
|
|
874
859
|
// The touchEnd event is buggy on Android, so this will serve as a fallback whenever needed
|
|
875
860
|
// https://github.com/facebook/react-native/issues/9439
|
|
876
|
-
if (
|
|
861
|
+
if (this._autoplay && !this._autoplaying) {
|
|
877
862
|
clearTimeout(this._enableAutoplayTimeout);
|
|
878
863
|
this._enableAutoplayTimeout = setTimeout(() => {
|
|
879
864
|
this.startAutoplay();
|
|
@@ -884,7 +869,7 @@ export default class Carousel extends PureComponent {
|
|
|
884
869
|
// Due to a bug, this event is only fired on iOS
|
|
885
870
|
// https://github.com/facebook/react-native/issues/6791
|
|
886
871
|
// it's fine since we're only fixing an iOS bug in it, so ...
|
|
887
|
-
_onTouchRelease() {
|
|
872
|
+
_onTouchRelease (event) {
|
|
888
873
|
const { enableMomentum } = this.props;
|
|
889
874
|
|
|
890
875
|
if (enableMomentum && IS_IOS) {
|
|
@@ -895,7 +880,7 @@ export default class Carousel extends PureComponent {
|
|
|
895
880
|
}
|
|
896
881
|
}
|
|
897
882
|
|
|
898
|
-
_onLayout(event) {
|
|
883
|
+
_onLayout (event) {
|
|
899
884
|
const { onLayout } = this.props;
|
|
900
885
|
|
|
901
886
|
// Prevent unneeded actions during the first 'onLayout' (triggered on init)
|
|
@@ -911,7 +896,7 @@ export default class Carousel extends PureComponent {
|
|
|
911
896
|
}
|
|
912
897
|
}
|
|
913
898
|
|
|
914
|
-
_snapScroll(delta) {
|
|
899
|
+
_snapScroll (delta) {
|
|
915
900
|
const { swipeThreshold } = this.props;
|
|
916
901
|
|
|
917
902
|
// When using momentum and releasing the touch with
|
|
@@ -944,7 +929,7 @@ export default class Carousel extends PureComponent {
|
|
|
944
929
|
}
|
|
945
930
|
}
|
|
946
931
|
|
|
947
|
-
_snapToItem(index, animated = true, fireCallback = true, initial = false, lockScroll = true) {
|
|
932
|
+
_snapToItem (index, animated = true, fireCallback = true, initial = false, lockScroll = true) {
|
|
948
933
|
const { enableMomentum, onSnapToItem, onBeforeSnapToItem } = this.props;
|
|
949
934
|
const itemsLength = this._getCustomDataLength();
|
|
950
935
|
const wrappedRef = this._getWrappedRef();
|
|
@@ -988,9 +973,11 @@ export default class Carousel extends PureComponent {
|
|
|
988
973
|
|
|
989
974
|
this._scrollTo(this._scrollOffsetRef, animated);
|
|
990
975
|
|
|
976
|
+
this._scrollEndOffset = this._currentContentOffset;
|
|
977
|
+
|
|
991
978
|
if (enableMomentum) {
|
|
992
979
|
// iOS fix, check the note in the constructor
|
|
993
|
-
if (
|
|
980
|
+
if (!initial) {
|
|
994
981
|
this._ignoreNextMomentum = true;
|
|
995
982
|
}
|
|
996
983
|
|
|
@@ -1011,7 +998,7 @@ export default class Carousel extends PureComponent {
|
|
|
1011
998
|
}
|
|
1012
999
|
}
|
|
1013
1000
|
|
|
1014
|
-
_onBeforeSnap(index) {
|
|
1001
|
+
_onBeforeSnap (index) {
|
|
1015
1002
|
const { onBeforeSnapToItem } = this.props;
|
|
1016
1003
|
|
|
1017
1004
|
if (!this._carouselRef) {
|
|
@@ -1019,10 +1006,10 @@ export default class Carousel extends PureComponent {
|
|
|
1019
1006
|
}
|
|
1020
1007
|
|
|
1021
1008
|
this._canFireBeforeCallback = false;
|
|
1022
|
-
|
|
1009
|
+
onBeforeSnapToItem && onBeforeSnapToItem(index);
|
|
1023
1010
|
}
|
|
1024
1011
|
|
|
1025
|
-
_onSnap(index) {
|
|
1012
|
+
_onSnap (index) {
|
|
1026
1013
|
const { onSnapToItem } = this.props;
|
|
1027
1014
|
|
|
1028
1015
|
if (!this._carouselRef) {
|
|
@@ -1030,11 +1017,12 @@ export default class Carousel extends PureComponent {
|
|
|
1030
1017
|
}
|
|
1031
1018
|
|
|
1032
1019
|
this._canFireCallback = false;
|
|
1033
|
-
|
|
1020
|
+
onSnapToItem && onSnapToItem(index);
|
|
1034
1021
|
}
|
|
1035
1022
|
|
|
1036
|
-
startAutoplay() {
|
|
1023
|
+
startAutoplay () {
|
|
1037
1024
|
const { autoplayInterval, autoplayDelay } = this.props;
|
|
1025
|
+
this._autoplay = true;
|
|
1038
1026
|
|
|
1039
1027
|
if (this._autoplaying) {
|
|
1040
1028
|
return;
|
|
@@ -1051,12 +1039,19 @@ export default class Carousel extends PureComponent {
|
|
|
1051
1039
|
}, autoplayDelay);
|
|
1052
1040
|
}
|
|
1053
1041
|
|
|
1054
|
-
|
|
1042
|
+
pauseAutoPlay () {
|
|
1055
1043
|
this._autoplaying = false;
|
|
1044
|
+
clearTimeout(this._autoplayTimeout);
|
|
1045
|
+
clearTimeout(this._enableAutoplayTimeout);
|
|
1056
1046
|
clearInterval(this._autoplayInterval);
|
|
1057
1047
|
}
|
|
1058
1048
|
|
|
1059
|
-
|
|
1049
|
+
stopAutoplay () {
|
|
1050
|
+
this._autoplay = false;
|
|
1051
|
+
this.pauseAutoPlay();
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
snapToItem (index, animated = true, fireCallback = true) {
|
|
1060
1055
|
if (!index || index < 0) {
|
|
1061
1056
|
index = 0;
|
|
1062
1057
|
}
|
|
@@ -1070,7 +1065,7 @@ export default class Carousel extends PureComponent {
|
|
|
1070
1065
|
this._snapToItem(positionIndex, animated, fireCallback);
|
|
1071
1066
|
}
|
|
1072
1067
|
|
|
1073
|
-
snapToNext(animated = true, fireCallback = true) {
|
|
1068
|
+
snapToNext (animated = true, fireCallback = true) {
|
|
1074
1069
|
const itemsLength = this._getCustomDataLength();
|
|
1075
1070
|
|
|
1076
1071
|
let newIndex = this._activeItem + 1;
|
|
@@ -1083,7 +1078,7 @@ export default class Carousel extends PureComponent {
|
|
|
1083
1078
|
this._snapToItem(newIndex, animated, fireCallback);
|
|
1084
1079
|
}
|
|
1085
1080
|
|
|
1086
|
-
snapToPrev(animated = true, fireCallback = true) {
|
|
1081
|
+
snapToPrev (animated = true, fireCallback = true) {
|
|
1087
1082
|
const itemsLength = this._getCustomDataLength();
|
|
1088
1083
|
|
|
1089
1084
|
let newIndex = this._activeItem - 1;
|
|
@@ -1097,7 +1092,7 @@ export default class Carousel extends PureComponent {
|
|
|
1097
1092
|
}
|
|
1098
1093
|
|
|
1099
1094
|
// https://github.com/facebook/react-native/issues/1831#issuecomment-231069668
|
|
1100
|
-
triggerRenderingHack(offset) {
|
|
1095
|
+
triggerRenderingHack (offset) {
|
|
1101
1096
|
// Avoid messing with user scroll
|
|
1102
1097
|
if (Date.now() - this._lastScrollDate < 500) {
|
|
1103
1098
|
return;
|
|
@@ -1112,22 +1107,23 @@ export default class Carousel extends PureComponent {
|
|
|
1112
1107
|
this._scrollTo(scrollPosition + scrollOffset, false);
|
|
1113
1108
|
}
|
|
1114
1109
|
|
|
1115
|
-
_getSlideInterpolatedStyle(index, animatedValue) {
|
|
1110
|
+
_getSlideInterpolatedStyle (index, animatedValue) {
|
|
1116
1111
|
const { layoutCardOffset, slideInterpolatedStyle } = this.props;
|
|
1117
1112
|
|
|
1118
1113
|
if (slideInterpolatedStyle) {
|
|
1119
1114
|
return slideInterpolatedStyle(index, animatedValue, this.props);
|
|
1120
|
-
} if (this._shouldUseTinderLayout()) {
|
|
1115
|
+
} else if (this._shouldUseTinderLayout()) {
|
|
1121
1116
|
return tinderAnimatedStyles(index, animatedValue, this.props, layoutCardOffset);
|
|
1122
|
-
} if (this._shouldUseStackLayout()) {
|
|
1117
|
+
} else if (this._shouldUseStackLayout()) {
|
|
1123
1118
|
return stackAnimatedStyles(index, animatedValue, this.props, layoutCardOffset);
|
|
1124
|
-
} if (this._shouldUseShiftLayout()) {
|
|
1119
|
+
} else if (this._shouldUseShiftLayout()) {
|
|
1125
1120
|
return shiftAnimatedStyles(index, animatedValue, this.props);
|
|
1121
|
+
} else {
|
|
1122
|
+
return defaultAnimatedStyles(index, animatedValue, this.props);
|
|
1126
1123
|
}
|
|
1127
|
-
return defaultAnimatedStyles(index, animatedValue, this.props);
|
|
1128
1124
|
}
|
|
1129
1125
|
|
|
1130
|
-
_renderItem({ item, index }) {
|
|
1126
|
+
_renderItem ({ item, index }) {
|
|
1131
1127
|
const { interpolators } = this.state;
|
|
1132
1128
|
const {
|
|
1133
1129
|
hasParallaxImages,
|
|
@@ -1138,8 +1134,7 @@ export default class Carousel extends PureComponent {
|
|
|
1138
1134
|
sliderHeight,
|
|
1139
1135
|
sliderWidth,
|
|
1140
1136
|
slideStyle,
|
|
1141
|
-
vertical
|
|
1142
|
-
isCustomScrollWidth
|
|
1137
|
+
vertical
|
|
1143
1138
|
} = this.props;
|
|
1144
1139
|
|
|
1145
1140
|
const animatedValue = interpolators && interpolators[index];
|
|
@@ -1149,7 +1144,7 @@ export default class Carousel extends PureComponent {
|
|
|
1149
1144
|
}
|
|
1150
1145
|
|
|
1151
1146
|
const animate = this._shouldAnimateSlides();
|
|
1152
|
-
const
|
|
1147
|
+
const Component = animate ? Animated.View : View;
|
|
1153
1148
|
const animatedStyle = animate ? this._getSlideInterpolatedStyle(index, animatedValue) : {};
|
|
1154
1149
|
|
|
1155
1150
|
const parallaxProps = hasParallaxImages ? {
|
|
@@ -1162,24 +1157,19 @@ export default class Carousel extends PureComponent {
|
|
|
1162
1157
|
itemHeight
|
|
1163
1158
|
} : undefined;
|
|
1164
1159
|
|
|
1160
|
+
const mainDimension = vertical ? { height: itemHeight } : { width: itemWidth };
|
|
1165
1161
|
const specificProps = this._needsScrollView() ? {
|
|
1166
1162
|
key: keyExtractor ? keyExtractor(item, index) : this._getKeyExtractor(item, index)
|
|
1167
1163
|
} : {};
|
|
1168
|
-
|
|
1164
|
+
|
|
1169
1165
|
return (
|
|
1170
|
-
<
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
{...specificProps}
|
|
1174
|
-
>
|
|
1175
|
-
{renderItem({
|
|
1176
|
-
item, index, realIndex: this._getDataIndex(index), activeIndex: this._getDataIndex(this._activeItem)
|
|
1177
|
-
}, parallaxProps)}
|
|
1178
|
-
</ComponentView>
|
|
1166
|
+
<Component style={[mainDimension, slideStyle, animatedStyle]} pointerEvents={'box-none'} {...specificProps}>
|
|
1167
|
+
{ renderItem({ item, index, realIndex: this._getDataIndex(index), activeIndex: this._getDataIndex(this._activeItem) }, parallaxProps) }
|
|
1168
|
+
</Component>
|
|
1179
1169
|
);
|
|
1180
1170
|
}
|
|
1181
1171
|
|
|
1182
|
-
_getComponentOverridableProps() {
|
|
1172
|
+
_getComponentOverridableProps () {
|
|
1183
1173
|
const {
|
|
1184
1174
|
enableMomentum,
|
|
1185
1175
|
itemWidth,
|
|
@@ -1190,18 +1180,18 @@ export default class Carousel extends PureComponent {
|
|
|
1190
1180
|
vertical
|
|
1191
1181
|
} = this.props;
|
|
1192
1182
|
|
|
1193
|
-
const visibleItems = Math.ceil(vertical
|
|
1194
|
-
|
|
1195
|
-
|
|
1183
|
+
const visibleItems = Math.ceil(vertical ?
|
|
1184
|
+
sliderHeight / itemHeight :
|
|
1185
|
+
sliderWidth / itemWidth) + 1;
|
|
1196
1186
|
const initialNumPerSide = this._enableLoop() ? loopClonesPerSide : 2;
|
|
1197
1187
|
const initialNumToRender = visibleItems + (initialNumPerSide * 2);
|
|
1198
1188
|
const maxToRenderPerBatch = 1 + (initialNumToRender * 2);
|
|
1199
1189
|
const windowSize = maxToRenderPerBatch;
|
|
1200
1190
|
|
|
1201
1191
|
const specificProps = !this._needsScrollView() ? {
|
|
1202
|
-
initialNumToRender,
|
|
1203
|
-
maxToRenderPerBatch,
|
|
1204
|
-
windowSize
|
|
1192
|
+
initialNumToRender: initialNumToRender,
|
|
1193
|
+
maxToRenderPerBatch: maxToRenderPerBatch,
|
|
1194
|
+
windowSize: windowSize
|
|
1205
1195
|
// updateCellsBatchingPeriod
|
|
1206
1196
|
} : {};
|
|
1207
1197
|
|
|
@@ -1221,7 +1211,7 @@ export default class Carousel extends PureComponent {
|
|
|
1221
1211
|
};
|
|
1222
1212
|
}
|
|
1223
1213
|
|
|
1224
|
-
_getComponentStaticProps() {
|
|
1214
|
+
_getComponentStaticProps () {
|
|
1225
1215
|
const { hideCarousel } = this.state;
|
|
1226
1216
|
const {
|
|
1227
1217
|
containerCustomStyle,
|
|
@@ -1236,11 +1226,11 @@ export default class Carousel extends PureComponent {
|
|
|
1236
1226
|
const containerStyle = [
|
|
1237
1227
|
containerCustomStyle || style || {},
|
|
1238
1228
|
hideCarousel ? { opacity: 0 } : {},
|
|
1239
|
-
vertical
|
|
1240
|
-
|
|
1229
|
+
vertical ?
|
|
1230
|
+
{ height: sliderHeight, flexDirection: 'column' } :
|
|
1241
1231
|
// LTR hack; see https://github.com/facebook/react-native/issues/11960
|
|
1242
1232
|
// and https://github.com/facebook/react-native/issues/13100#issuecomment-328986423
|
|
1243
|
-
|
|
1233
|
+
{ width: sliderWidth, flexDirection: this._needsRTLAdaptations() ? 'row-reverse' : 'row' }
|
|
1244
1234
|
];
|
|
1245
1235
|
const contentContainerStyle = [
|
|
1246
1236
|
vertical ? {
|
|
@@ -1257,15 +1247,14 @@ export default class Carousel extends PureComponent {
|
|
|
1257
1247
|
// extraData: this.state,
|
|
1258
1248
|
renderItem: this._renderItem,
|
|
1259
1249
|
numColumns: 1,
|
|
1260
|
-
getItemLayout: undefined, // see #193
|
|
1261
|
-
initialScrollIndex: undefined, // see #193
|
|
1262
1250
|
keyExtractor: keyExtractor || this._getKeyExtractor
|
|
1263
1251
|
} : {};
|
|
1252
|
+
|
|
1264
1253
|
return {
|
|
1265
|
-
ref:
|
|
1254
|
+
ref: c => this._carouselRef = c,
|
|
1266
1255
|
data: this._getCustomData(),
|
|
1267
1256
|
style: containerStyle,
|
|
1268
|
-
contentContainerStyle,
|
|
1257
|
+
contentContainerStyle: contentContainerStyle,
|
|
1269
1258
|
horizontal: !vertical,
|
|
1270
1259
|
scrollEventThrottle: 1,
|
|
1271
1260
|
onScroll: this._onScrollHandler,
|
|
@@ -1281,7 +1270,7 @@ export default class Carousel extends PureComponent {
|
|
|
1281
1270
|
};
|
|
1282
1271
|
}
|
|
1283
1272
|
|
|
1284
|
-
render() {
|
|
1273
|
+
render () {
|
|
1285
1274
|
const { data, renderItem, useScrollView } = this.props;
|
|
1286
1275
|
|
|
1287
1276
|
if (!data || !renderItem) {
|
|
@@ -1294,14 +1283,14 @@ export default class Carousel extends PureComponent {
|
|
|
1294
1283
|
...this._getComponentStaticProps()
|
|
1295
1284
|
};
|
|
1296
1285
|
|
|
1297
|
-
const ScrollViewComponent = typeof useScrollView === 'function' ? useScrollView : AnimatedScrollView
|
|
1286
|
+
const ScrollViewComponent = typeof useScrollView === 'function' ? useScrollView : AnimatedScrollView
|
|
1298
1287
|
|
|
1299
1288
|
return this._needsScrollView() ? (
|
|
1300
1289
|
<ScrollViewComponent {...props}>
|
|
1301
1290
|
{
|
|
1302
|
-
this._getCustomData().map((item, index) =>
|
|
1303
|
-
item, index, realIndex: this._getDataIndex(index), activeIndex: this._getDataIndex(this._activeItem)
|
|
1304
|
-
})
|
|
1291
|
+
this._getCustomData().map((item, index) => {
|
|
1292
|
+
return this._renderItem({ item, index, realIndex: this._getDataIndex(index), activeIndex: this._getDataIndex(this._activeItem) });
|
|
1293
|
+
})
|
|
1305
1294
|
}
|
|
1306
1295
|
</ScrollViewComponent>
|
|
1307
1296
|
) : (
|