@momo-kits/carousel 0.80.1-beta.2 → 0.80.4-beta.2
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/animation.ts +18 -6
- package/index.tsx +154 -301
- package/package.json +1 -1
- package/types.ts +19 -34
- package/newCarousel.tsx +0 -1041
package/index.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import {
|
|
3
3
|
Animated,
|
|
4
4
|
Dimensions,
|
|
5
|
-
|
|
5
|
+
GestureResponderEvent,
|
|
6
6
|
LayoutChangeEvent,
|
|
7
7
|
NativeScrollEvent,
|
|
8
8
|
NativeSyntheticEvent,
|
|
@@ -10,12 +10,11 @@ import {
|
|
|
10
10
|
View,
|
|
11
11
|
} from 'react-native';
|
|
12
12
|
import {defaultAnimatedStyles, defaultScrollInterpolator} from './animation';
|
|
13
|
-
import {CarouselProps, CarouselState, Position} from './types';
|
|
13
|
+
import {CarouselProps, CarouselRef, CarouselState, Position} from './types';
|
|
14
14
|
import {Spacing} from '@momo-kits/foundation';
|
|
15
15
|
|
|
16
16
|
const IS_ANDROID = Platform.OS === 'android';
|
|
17
17
|
const IS_IOS = Platform.OS === 'ios';
|
|
18
|
-
const IS_RTL = I18nManager.isRTL;
|
|
19
18
|
const screenWidth = Dimensions.get('window').width;
|
|
20
19
|
|
|
21
20
|
export default class Carousel extends React.PureComponent<
|
|
@@ -23,7 +22,7 @@ export default class Carousel extends React.PureComponent<
|
|
|
23
22
|
CarouselState
|
|
24
23
|
> {
|
|
25
24
|
static defaultProps = {
|
|
26
|
-
activeSlideAlignment: '
|
|
25
|
+
activeSlideAlignment: 'start',
|
|
27
26
|
activeSlideOffset: 20,
|
|
28
27
|
apparitionDelay: 0,
|
|
29
28
|
autoplay: false,
|
|
@@ -35,10 +34,6 @@ export default class Carousel extends React.PureComponent<
|
|
|
35
34
|
enableSnap: true,
|
|
36
35
|
firstItem: 0,
|
|
37
36
|
hasParallaxImages: false,
|
|
38
|
-
inactiveSlideOpacity: 0.7,
|
|
39
|
-
inactiveSlideScale: 0.9,
|
|
40
|
-
inactiveSlideShift: 0,
|
|
41
|
-
layout: 'default',
|
|
42
37
|
loop: false,
|
|
43
38
|
loopClonesPerSide: 3,
|
|
44
39
|
scrollEnabled: true,
|
|
@@ -61,7 +56,6 @@ export default class Carousel extends React.PureComponent<
|
|
|
61
56
|
_scrollEnabled;
|
|
62
57
|
_initTimeout?: NodeJS.Timeout;
|
|
63
58
|
_apparitionTimeout?: NodeJS.Timeout;
|
|
64
|
-
_hackSlideAnimationTimeout?: NodeJS.Timeout;
|
|
65
59
|
_enableAutoplayTimeout?: NodeJS.Timeout;
|
|
66
60
|
_autoplayTimeout?: NodeJS.Timeout;
|
|
67
61
|
_snapNoMomentumTimeout?: NodeJS.Timeout;
|
|
@@ -71,9 +65,8 @@ export default class Carousel extends React.PureComponent<
|
|
|
71
65
|
_autoplay?: boolean;
|
|
72
66
|
_autoplaying?: boolean;
|
|
73
67
|
_autoplayInterval?: NodeJS.Timeout;
|
|
74
|
-
_carouselRef
|
|
68
|
+
_carouselRef: any;
|
|
75
69
|
_onLayoutInitDone?: boolean;
|
|
76
|
-
itemWidth: number;
|
|
77
70
|
constructor(props: CarouselProps) {
|
|
78
71
|
super(props);
|
|
79
72
|
|
|
@@ -81,6 +74,7 @@ export default class Carousel extends React.PureComponent<
|
|
|
81
74
|
hideCarousel: !!props.apparitionDelay,
|
|
82
75
|
interpolators: [],
|
|
83
76
|
containerWidth: screenWidth,
|
|
77
|
+
itemWidth: screenWidth - Spacing.L * 2,
|
|
84
78
|
};
|
|
85
79
|
|
|
86
80
|
const initialActiveItem = this._getFirstItem(props.firstItem);
|
|
@@ -93,9 +87,6 @@ export default class Carousel extends React.PureComponent<
|
|
|
93
87
|
this._positions = [];
|
|
94
88
|
this._currentScrollOffset = 0;
|
|
95
89
|
this._scrollEnabled = props.scrollEnabled;
|
|
96
|
-
this.itemWidth =
|
|
97
|
-
(this.state.containerWidth * 0.9 - (props.visibleItem - 1) * 12) /
|
|
98
|
-
props.visibleItem;
|
|
99
90
|
|
|
100
91
|
this._getItemLayout = this._getItemLayout.bind(this);
|
|
101
92
|
this._getKeyExtractor = this._getKeyExtractor.bind(this);
|
|
@@ -108,20 +99,8 @@ export default class Carousel extends React.PureComponent<
|
|
|
108
99
|
this._setScrollHandler(props);
|
|
109
100
|
}
|
|
110
101
|
|
|
111
|
-
get realIndex() {
|
|
112
|
-
return this._activeItem;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
get currentIndex() {
|
|
116
|
-
return this._getDataIndex(this._activeItem);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
get currentScrollPosition() {
|
|
120
|
-
return this._currentScrollOffset;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
102
|
componentDidMount() {
|
|
124
|
-
const {apparitionDelay, autoplay
|
|
103
|
+
const {apparitionDelay, autoplay} = this.props;
|
|
125
104
|
|
|
126
105
|
this._mounted = true;
|
|
127
106
|
this._initPositionsAndInterpolators();
|
|
@@ -179,10 +158,6 @@ export default class Carousel extends React.PureComponent<
|
|
|
179
158
|
this._previousItemsLength = itemsLength;
|
|
180
159
|
|
|
181
160
|
this._initPositionsAndInterpolators(this.props);
|
|
182
|
-
|
|
183
|
-
if (this._previousItemsLength > itemsLength) {
|
|
184
|
-
this._hackActiveSlideAnimation(nextActiveItem);
|
|
185
|
-
}
|
|
186
161
|
} else if (
|
|
187
162
|
nextFirstItem !== this._previousFirstItem &&
|
|
188
163
|
nextFirstItem !== this._activeItem
|
|
@@ -202,7 +177,6 @@ export default class Carousel extends React.PureComponent<
|
|
|
202
177
|
this.stopAutoplay();
|
|
203
178
|
clearTimeout(this._initTimeout);
|
|
204
179
|
clearTimeout(this._apparitionTimeout);
|
|
205
|
-
clearTimeout(this._hackSlideAnimationTimeout);
|
|
206
180
|
clearTimeout(this._enableAutoplayTimeout);
|
|
207
181
|
clearTimeout(this._autoplayTimeout);
|
|
208
182
|
clearTimeout(this._snapNoMomentumTimeout);
|
|
@@ -231,28 +205,14 @@ export default class Carousel extends React.PureComponent<
|
|
|
231
205
|
this._onScrollHandler = Animated.event(argMapping, scrollEventConfig);
|
|
232
206
|
}
|
|
233
207
|
|
|
234
|
-
_needsRTLAdaptations() {
|
|
235
|
-
return IS_RTL && IS_ANDROID;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
208
|
_enableLoop() {
|
|
239
209
|
const {data, enableSnap, loop} = this.props;
|
|
240
210
|
return enableSnap && loop && data && data.length && data.length > 1;
|
|
241
211
|
}
|
|
242
212
|
|
|
243
213
|
_shouldAnimateSlides(props = this.props) {
|
|
244
|
-
const {
|
|
245
|
-
|
|
246
|
-
inactiveSlideScale,
|
|
247
|
-
scrollInterpolator,
|
|
248
|
-
slideInterpolatedStyle,
|
|
249
|
-
} = props;
|
|
250
|
-
return (
|
|
251
|
-
inactiveSlideOpacity < 1 ||
|
|
252
|
-
inactiveSlideScale < 1 ||
|
|
253
|
-
!!scrollInterpolator ||
|
|
254
|
-
!!slideInterpolatedStyle
|
|
255
|
-
);
|
|
214
|
+
const {inactiveSlideOpacity, inactiveSlideScale} = props;
|
|
215
|
+
return inactiveSlideOpacity < 1 || inactiveSlideScale < 1;
|
|
256
216
|
}
|
|
257
217
|
|
|
258
218
|
_shouldRepositionScroll(index: number) {
|
|
@@ -322,7 +282,7 @@ export default class Carousel extends React.PureComponent<
|
|
|
322
282
|
return 0;
|
|
323
283
|
}
|
|
324
284
|
|
|
325
|
-
return
|
|
285
|
+
return index;
|
|
326
286
|
}
|
|
327
287
|
|
|
328
288
|
_getDataIndex(index: number) {
|
|
@@ -360,19 +320,6 @@ export default class Carousel extends React.PureComponent<
|
|
|
360
320
|
return index - loopClonesPerSide;
|
|
361
321
|
}
|
|
362
322
|
}
|
|
363
|
-
//
|
|
364
|
-
// _getPositionIndex(index: number) {
|
|
365
|
-
// const {loop, loopClonesPerSide} = this.props;
|
|
366
|
-
// return loop ? index + loopClonesPerSide : index;
|
|
367
|
-
// }
|
|
368
|
-
|
|
369
|
-
_getSnapOffsets(props = this.props) {
|
|
370
|
-
const offset = this._getItemMainDimension();
|
|
371
|
-
if (!props.enableSnap) return;
|
|
372
|
-
return [...Array(this._getCustomDataLength(props))].map((_, i) => {
|
|
373
|
-
return i * offset;
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
323
|
|
|
377
324
|
_getFirstItem(index: number, props = this.props) {
|
|
378
325
|
const {loopClonesPerSide} = props;
|
|
@@ -386,14 +333,7 @@ export default class Carousel extends React.PureComponent<
|
|
|
386
333
|
}
|
|
387
334
|
|
|
388
335
|
_getWrappedRef() {
|
|
389
|
-
|
|
390
|
-
return this._carouselRef;
|
|
391
|
-
}
|
|
392
|
-
return (
|
|
393
|
-
this._carouselRef &&
|
|
394
|
-
this._carouselRef.getNode &&
|
|
395
|
-
this._carouselRef.getNode()
|
|
396
|
-
);
|
|
336
|
+
return this._carouselRef;
|
|
397
337
|
}
|
|
398
338
|
|
|
399
339
|
_getScrollEnabled() {
|
|
@@ -401,23 +341,12 @@ export default class Carousel extends React.PureComponent<
|
|
|
401
341
|
}
|
|
402
342
|
|
|
403
343
|
_setScrollEnabled(scrollEnabled = true) {
|
|
404
|
-
const wrappedRef = this._getWrappedRef();
|
|
405
|
-
|
|
406
|
-
if (!wrappedRef || !wrappedRef.setNativeProps) {
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
wrappedRef.setNativeProps({scrollEnabled});
|
|
411
344
|
this._scrollEnabled = scrollEnabled;
|
|
412
345
|
}
|
|
413
346
|
|
|
414
347
|
_getItemMainDimension() {
|
|
415
|
-
const {
|
|
416
|
-
|
|
417
|
-
return (
|
|
418
|
-
(containerWidth * 0.9 - (visibleItem - 1) * Spacing.M) / visibleItem +
|
|
419
|
-
Spacing.M
|
|
420
|
-
);
|
|
348
|
+
const {itemWidth} = this.state;
|
|
349
|
+
return itemWidth + Spacing.S;
|
|
421
350
|
}
|
|
422
351
|
|
|
423
352
|
_getItemScrollOffset(index: number) {
|
|
@@ -485,17 +414,11 @@ export default class Carousel extends React.PureComponent<
|
|
|
485
414
|
}
|
|
486
415
|
|
|
487
416
|
_getSlideInterpolatedStyle(index: number, animatedValue: Animated.Value) {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
if (slideInterpolatedStyle) {
|
|
491
|
-
return slideInterpolatedStyle(index, animatedValue, this.props);
|
|
492
|
-
} else {
|
|
493
|
-
return defaultAnimatedStyles(index, animatedValue, this.props);
|
|
494
|
-
}
|
|
417
|
+
return defaultAnimatedStyles(animatedValue, this.props);
|
|
495
418
|
}
|
|
496
419
|
|
|
497
420
|
_initPositionsAndInterpolators(props = this.props) {
|
|
498
|
-
const {data
|
|
421
|
+
const {data} = props;
|
|
499
422
|
const itemMainDimension = this._getItemMainDimension();
|
|
500
423
|
|
|
501
424
|
if (!data || !data.length) {
|
|
@@ -517,19 +440,10 @@ export default class Carousel extends React.PureComponent<
|
|
|
517
440
|
if (!this._shouldAnimateSlides(props) || !this._scrollPos) {
|
|
518
441
|
animatedValue = new Animated.Value(1);
|
|
519
442
|
} else {
|
|
520
|
-
let interpolator
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
if (
|
|
527
|
-
!interpolator ||
|
|
528
|
-
!interpolator.inputRange ||
|
|
529
|
-
!interpolator.outputRange
|
|
530
|
-
) {
|
|
531
|
-
interpolator = defaultScrollInterpolator(_index, props);
|
|
532
|
-
}
|
|
443
|
+
let interpolator = defaultScrollInterpolator(
|
|
444
|
+
_index,
|
|
445
|
+
this.state.itemWidth,
|
|
446
|
+
);
|
|
533
447
|
|
|
534
448
|
animatedValue = this._scrollPos.interpolate({
|
|
535
449
|
...interpolator,
|
|
@@ -543,30 +457,6 @@ export default class Carousel extends React.PureComponent<
|
|
|
543
457
|
this.setState({interpolators});
|
|
544
458
|
}
|
|
545
459
|
|
|
546
|
-
_hackActiveSlideAnimation(index: number, scrollValue = 1) {
|
|
547
|
-
const offset = this._getItemScrollOffset(index);
|
|
548
|
-
|
|
549
|
-
if (!this._mounted || !this._carouselRef || typeof offset === 'undefined') {
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
const multiplier = this._currentScrollOffset === 0 ? 1 : -1;
|
|
554
|
-
const scrollDelta = scrollValue * multiplier;
|
|
555
|
-
|
|
556
|
-
this._scrollTo({
|
|
557
|
-
offset: offset + scrollDelta,
|
|
558
|
-
animated: false,
|
|
559
|
-
});
|
|
560
|
-
|
|
561
|
-
clearTimeout(this._hackSlideAnimationTimeout);
|
|
562
|
-
this._hackSlideAnimationTimeout = setTimeout(() => {
|
|
563
|
-
this._scrollTo({
|
|
564
|
-
offset,
|
|
565
|
-
animated: false,
|
|
566
|
-
});
|
|
567
|
-
}, 1);
|
|
568
|
-
}
|
|
569
|
-
|
|
570
460
|
_repositionScroll(index: number, animated = false) {
|
|
571
461
|
const {data, loopClonesPerSide} = this.props;
|
|
572
462
|
const dataLength = data && data.length;
|
|
@@ -586,36 +476,6 @@ export default class Carousel extends React.PureComponent<
|
|
|
586
476
|
this._snapToItem(repositionTo, animated, false);
|
|
587
477
|
}
|
|
588
478
|
|
|
589
|
-
_scrollTo(info: {offset?: number; index?: number; animated?: boolean}) {
|
|
590
|
-
const {offset, index, animated = true} = info;
|
|
591
|
-
const wrappedRef = this._getWrappedRef();
|
|
592
|
-
if (
|
|
593
|
-
!this._mounted ||
|
|
594
|
-
!wrappedRef ||
|
|
595
|
-
(typeof offset === 'undefined' && typeof index === 'undefined')
|
|
596
|
-
) {
|
|
597
|
-
return;
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
let scrollToOffset;
|
|
601
|
-
if (typeof index !== 'undefined') {
|
|
602
|
-
scrollToOffset = this._getItemScrollOffset(index);
|
|
603
|
-
} else {
|
|
604
|
-
scrollToOffset = offset;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
if (typeof scrollToOffset === 'undefined') {
|
|
608
|
-
return;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
const options = {
|
|
612
|
-
offset,
|
|
613
|
-
animated,
|
|
614
|
-
};
|
|
615
|
-
|
|
616
|
-
wrappedRef.scrollToOffset(options);
|
|
617
|
-
}
|
|
618
|
-
|
|
619
479
|
_onTouchStart(event: any) {
|
|
620
480
|
const {onTouchStart} = this.props;
|
|
621
481
|
|
|
@@ -626,7 +486,7 @@ export default class Carousel extends React.PureComponent<
|
|
|
626
486
|
onTouchStart && onTouchStart(event);
|
|
627
487
|
}
|
|
628
488
|
|
|
629
|
-
_onTouchEnd(event:
|
|
489
|
+
_onTouchEnd(event: GestureResponderEvent) {
|
|
630
490
|
const {onTouchEnd} = this.props;
|
|
631
491
|
|
|
632
492
|
if (
|
|
@@ -675,11 +535,12 @@ export default class Carousel extends React.PureComponent<
|
|
|
675
535
|
|
|
676
536
|
_onMomentumScrollEnd(event: NativeSyntheticEvent<NativeScrollEvent>) {
|
|
677
537
|
const {autoplayDelay, onMomentumScrollEnd, onSnapToItem} = this.props;
|
|
538
|
+
const {itemWidth} = this.state;
|
|
678
539
|
const scrollOffset = event
|
|
679
540
|
? this._getScrollOffset(event)
|
|
680
541
|
: this._currentScrollOffset;
|
|
681
542
|
const nextActiveItem = this._getActiveItem(scrollOffset);
|
|
682
|
-
const hasSnapped = this._isMultiple(scrollOffset,
|
|
543
|
+
const hasSnapped = this._isMultiple(scrollOffset, itemWidth);
|
|
683
544
|
|
|
684
545
|
if (nextActiveItem !== this._activeItem) {
|
|
685
546
|
this._activeItem = nextActiveItem;
|
|
@@ -703,7 +564,7 @@ export default class Carousel extends React.PureComponent<
|
|
|
703
564
|
}
|
|
704
565
|
|
|
705
566
|
_onLayout(event: LayoutChangeEvent) {
|
|
706
|
-
const {onLayout} = this.props;
|
|
567
|
+
const {onLayout, visibleItem} = this.props;
|
|
707
568
|
|
|
708
569
|
if (this._onLayoutInitDone) {
|
|
709
570
|
this._initPositionsAndInterpolators();
|
|
@@ -711,11 +572,25 @@ export default class Carousel extends React.PureComponent<
|
|
|
711
572
|
} else {
|
|
712
573
|
this._onLayoutInitDone = true;
|
|
713
574
|
}
|
|
575
|
+
const containerWidth = event.nativeEvent.layout.width;
|
|
576
|
+
const itemWidth =
|
|
577
|
+
this.props.itemWidth ||
|
|
578
|
+
(this.props.visibleItem === 1
|
|
579
|
+
? screenWidth - Spacing.M * 2
|
|
580
|
+
: Math.ceil(
|
|
581
|
+
(containerWidth * 0.9 - visibleItem * Spacing.S) / visibleItem,
|
|
582
|
+
));
|
|
583
|
+
|
|
584
|
+
this.setState({containerWidth, itemWidth});
|
|
714
585
|
|
|
715
|
-
this.setState({containerWidth: event.nativeEvent.layout.width});
|
|
716
586
|
onLayout && onLayout(event);
|
|
717
587
|
}
|
|
718
588
|
|
|
589
|
+
_getPositionIndex(index: number) {
|
|
590
|
+
const {loop, loopClonesPerSide} = this.props;
|
|
591
|
+
return loop ? index + loopClonesPerSide : index;
|
|
592
|
+
}
|
|
593
|
+
|
|
719
594
|
_snapToItem(
|
|
720
595
|
index: number,
|
|
721
596
|
animated = true,
|
|
@@ -739,15 +614,9 @@ export default class Carousel extends React.PureComponent<
|
|
|
739
614
|
return;
|
|
740
615
|
}
|
|
741
616
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
return;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
this._scrollTo({
|
|
749
|
-
offset,
|
|
750
|
-
animated,
|
|
617
|
+
this._carouselRef.scrollToIndex({
|
|
618
|
+
index,
|
|
619
|
+
animated: true,
|
|
751
620
|
});
|
|
752
621
|
|
|
753
622
|
const requiresManualTrigger = !animated || IS_ANDROID;
|
|
@@ -770,6 +639,50 @@ export default class Carousel extends React.PureComponent<
|
|
|
770
639
|
}
|
|
771
640
|
}
|
|
772
641
|
|
|
642
|
+
_renderItem(info: {item: any; index: number}) {
|
|
643
|
+
const {item, index} = info;
|
|
644
|
+
const {interpolators, itemWidth} = this.state;
|
|
645
|
+
const {slideStyle} = this.props;
|
|
646
|
+
const animatedValue = interpolators && interpolators[index];
|
|
647
|
+
|
|
648
|
+
if (typeof animatedValue === 'undefined') {
|
|
649
|
+
return null;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const animate = this._shouldAnimateSlides();
|
|
653
|
+
const Component = animate ? Animated.View : View;
|
|
654
|
+
// const animatedStyle = animate
|
|
655
|
+
// ? this._getSlideInterpolatedStyle(index, animatedValue)
|
|
656
|
+
// : {};
|
|
657
|
+
|
|
658
|
+
const mainDimension = {width: itemWidth};
|
|
659
|
+
|
|
660
|
+
return (
|
|
661
|
+
<Component
|
|
662
|
+
style={[
|
|
663
|
+
mainDimension,
|
|
664
|
+
slideStyle,
|
|
665
|
+
// animatedStyle,
|
|
666
|
+
{overflow: 'hidden'},
|
|
667
|
+
this.props.loop
|
|
668
|
+
? {marginLeft: Spacing.S}
|
|
669
|
+
: {
|
|
670
|
+
marginLeft: index === 0 ? Spacing.M : 0,
|
|
671
|
+
marginRight:
|
|
672
|
+
index === this._getCustomDataLength() - 1
|
|
673
|
+
? Spacing.M
|
|
674
|
+
: Spacing.S,
|
|
675
|
+
},
|
|
676
|
+
]}
|
|
677
|
+
pointerEvents="box-none">
|
|
678
|
+
{this.props.renderItem({
|
|
679
|
+
item,
|
|
680
|
+
index,
|
|
681
|
+
})}
|
|
682
|
+
</Component>
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
|
|
773
686
|
startAutoplay() {
|
|
774
687
|
const {autoplayInterval, autoplayDelay} = this.props;
|
|
775
688
|
this._autoplay = true;
|
|
@@ -801,6 +714,20 @@ export default class Carousel extends React.PureComponent<
|
|
|
801
714
|
this.pauseAutoPlay();
|
|
802
715
|
}
|
|
803
716
|
|
|
717
|
+
snapToItem(index: number, animated = true, fireCallback = true) {
|
|
718
|
+
if (!index || index < 0) {
|
|
719
|
+
index = 0;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
const positionIndex = this._getPositionIndex(index);
|
|
723
|
+
|
|
724
|
+
if (positionIndex === this._activeItem) {
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
this._snapToItem(positionIndex, animated, fireCallback);
|
|
729
|
+
}
|
|
730
|
+
|
|
804
731
|
snapToNext(animated = true, fireCallback = true) {
|
|
805
732
|
const itemsLength = this._getCustomDataLength();
|
|
806
733
|
|
|
@@ -821,150 +748,76 @@ export default class Carousel extends React.PureComponent<
|
|
|
821
748
|
this._snapToItem(newIndex, animated, fireCallback);
|
|
822
749
|
}
|
|
823
750
|
|
|
824
|
-
|
|
825
|
-
this._hackActiveSlideAnimation(this._activeItem, offset);
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
_renderItem(info: {item: any; index: number}) {
|
|
829
|
-
const {item, index} = info;
|
|
830
|
-
const {interpolators} = this.state;
|
|
831
|
-
const {slideStyle} = this.props;
|
|
832
|
-
const animatedValue = interpolators && interpolators[index];
|
|
833
|
-
|
|
834
|
-
if (typeof animatedValue === 'undefined') {
|
|
835
|
-
return null;
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
const animate = this._shouldAnimateSlides();
|
|
839
|
-
const Component = animate ? Animated.View : View;
|
|
840
|
-
const animatedStyle = animate
|
|
841
|
-
? this._getSlideInterpolatedStyle(index, animatedValue)
|
|
842
|
-
: {};
|
|
843
|
-
|
|
844
|
-
const mainDimension = {width: this.itemWidth};
|
|
845
|
-
|
|
846
|
-
return (
|
|
847
|
-
<Component
|
|
848
|
-
style={[
|
|
849
|
-
mainDimension,
|
|
850
|
-
slideStyle,
|
|
851
|
-
// animatedStyle,
|
|
852
|
-
this.props.loop
|
|
853
|
-
? {marginLeft: Spacing.M}
|
|
854
|
-
: {
|
|
855
|
-
marginLeft: index === 0 ? Spacing.M : 0,
|
|
856
|
-
marginRight:
|
|
857
|
-
index === this._getCustomDataLength() - 1 ? 0 : Spacing.M,
|
|
858
|
-
},
|
|
859
|
-
]}
|
|
860
|
-
pointerEvents="box-none">
|
|
861
|
-
{this.props.renderItem({
|
|
862
|
-
item,
|
|
863
|
-
index,
|
|
864
|
-
})}
|
|
865
|
-
</Component>
|
|
866
|
-
);
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
_getComponentOverridableProps() {
|
|
870
|
-
const {hideCarousel, containerWidth} = this.state;
|
|
871
|
-
const {loopClonesPerSide, visibleItem} = this.props;
|
|
872
|
-
const visibleItems = visibleItem;
|
|
873
|
-
const initialNumPerSide = this._enableLoop() ? loopClonesPerSide : 2;
|
|
874
|
-
const initialNumToRender =
|
|
875
|
-
visibleItems > 2
|
|
876
|
-
? visibleItems + initialNumPerSide * 2
|
|
877
|
-
: initialNumPerSide * 2;
|
|
878
|
-
const maxToRenderPerBatch = initialNumToRender;
|
|
879
|
-
const windowSize = maxToRenderPerBatch;
|
|
880
|
-
const specificProps = {
|
|
881
|
-
initialNumToRender,
|
|
882
|
-
maxToRenderPerBatch,
|
|
883
|
-
windowSize,
|
|
884
|
-
};
|
|
885
|
-
|
|
886
|
-
return {
|
|
887
|
-
...specificProps,
|
|
888
|
-
automaticallyAdjustContentInsets: false,
|
|
889
|
-
decelerationRate: 'fast',
|
|
890
|
-
directionalLockEnabled: true,
|
|
891
|
-
disableScrollViewPanResponder: false,
|
|
892
|
-
inverted: this._needsRTLAdaptations(),
|
|
893
|
-
overScrollMode: 'never',
|
|
894
|
-
pinchGestureEnabled: false,
|
|
895
|
-
pointerEvents: hideCarousel ? 'none' : 'auto',
|
|
896
|
-
scrollsToTop: false,
|
|
897
|
-
showsHorizontalScrollIndicator: false,
|
|
898
|
-
showsVerticalScrollIndicator: false,
|
|
899
|
-
};
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
_getComponentStaticProps() {
|
|
903
|
-
const {hideCarousel, containerWidth} = this.state;
|
|
751
|
+
render() {
|
|
904
752
|
const {
|
|
905
|
-
|
|
906
|
-
|
|
753
|
+
loopClonesPerSide,
|
|
754
|
+
visibleItem,
|
|
907
755
|
firstItem,
|
|
908
756
|
getItemLayout,
|
|
909
757
|
keyExtractor,
|
|
910
758
|
style,
|
|
911
759
|
disableIntervalMomentum,
|
|
760
|
+
enableSnap,
|
|
912
761
|
} = this.props;
|
|
913
|
-
const
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
};
|
|
762
|
+
const {hideCarousel, containerWidth} = this.state;
|
|
763
|
+
|
|
764
|
+
const initialNumPerSide = this._enableLoop() ? loopClonesPerSide : 2;
|
|
765
|
+
const initialNumToRender =
|
|
766
|
+
visibleItem > 2
|
|
767
|
+
? visibleItem + initialNumPerSide * 2
|
|
768
|
+
: initialNumPerSide * 2;
|
|
769
|
+
const maxToRenderPerBatch = initialNumToRender;
|
|
770
|
+
const windowSize = maxToRenderPerBatch;
|
|
771
|
+
|
|
772
|
+
const snapToInterval = enableSnap
|
|
773
|
+
? this._getItemMainDimension()
|
|
774
|
+
: undefined;
|
|
927
775
|
|
|
928
776
|
const specificProps = {
|
|
929
777
|
getItemLayout: getItemLayout || this._getItemLayout,
|
|
930
778
|
initialScrollIndex: this._getFirstItem(firstItem),
|
|
931
779
|
keyExtractor: keyExtractor || this._getKeyExtractor,
|
|
932
|
-
numColumns: 1,
|
|
933
780
|
renderItem: this._renderItem,
|
|
934
781
|
};
|
|
935
782
|
|
|
936
|
-
return
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
c
|
|
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
|
-
|
|
783
|
+
return (
|
|
784
|
+
<Animated.FlatList
|
|
785
|
+
{...this.props}
|
|
786
|
+
{...specificProps}
|
|
787
|
+
ref={c => (this._carouselRef = c)}
|
|
788
|
+
overScrollMode={'never'}
|
|
789
|
+
snapToInterval={snapToInterval}
|
|
790
|
+
disableIntervalMomentum={disableIntervalMomentum}
|
|
791
|
+
pointerEvents={hideCarousel ? 'none' : 'auto'}
|
|
792
|
+
decelerationRate={'fast'}
|
|
793
|
+
numColumns={1}
|
|
794
|
+
style={[
|
|
795
|
+
style,
|
|
796
|
+
{width: '100%', flexDirection: 'row'},
|
|
797
|
+
hideCarousel ? {opacity: 0} : {},
|
|
798
|
+
]}
|
|
799
|
+
automaticallyAdjustContentInsets={false}
|
|
800
|
+
directionalLockEnabled
|
|
801
|
+
disableScrollViewPanResponder={false}
|
|
802
|
+
pinchGestureEnabled={false}
|
|
803
|
+
scrollsToTop={false}
|
|
804
|
+
showsHorizontalScrollIndicator={false}
|
|
805
|
+
showsVerticalScrollIndicator={false}
|
|
806
|
+
initialNumToRender={initialNumToRender}
|
|
807
|
+
maxToRenderPerBatch={maxToRenderPerBatch}
|
|
808
|
+
windowSize={windowSize}
|
|
809
|
+
pagingEnabled={enableSnap}
|
|
810
|
+
data={this._getCustomData()}
|
|
811
|
+
horizontal
|
|
812
|
+
scrollEventThrottle={1}
|
|
813
|
+
onLayout={this._onLayout}
|
|
814
|
+
onMomentumScrollEnd={this._onMomentumScrollEnd}
|
|
815
|
+
onScroll={this._onScrollHandler}
|
|
816
|
+
onTouchStart={this._onTouchStart}
|
|
817
|
+
onTouchEnd={this._onTouchEnd}
|
|
818
|
+
/>
|
|
819
|
+
);
|
|
969
820
|
}
|
|
970
821
|
}
|
|
822
|
+
|
|
823
|
+
export type {CarouselProps, CarouselRef};
|