@momo-kits/carousel 0.0.3-beta → 0.0.7
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 +1390 -1
- package/index.js +6 -1
- package/package.json +3 -10
- package/pagination/Pagination.js +158 -1
- package/pagination/PaginationDot.js +145 -1
- package/pagination/styles.js +24 -1
- package/publish.sh +1 -1
- package/styles.js +189 -1
- package/utils/animation.js +329 -1
- package/babel.config.js +0 -1
package/Carousel.js
CHANGED
|
@@ -1 +1,1390 @@
|
|
|
1
|
-
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var _extends2=_interopRequireDefault(require("@babel/runtime/helpers/extends"));var _defineProperty2=_interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));var _toConsumableArray2=_interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));var _slicedToArray2=_interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));var _classCallCheck2=_interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));var _createClass2=_interopRequireDefault(require("@babel/runtime/helpers/createClass"));var _assertThisInitialized2=_interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));var _inherits2=_interopRequireDefault(require("@babel/runtime/helpers/inherits"));var _possibleConstructorReturn2=_interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));var _getPrototypeOf2=_interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _propTypes=_interopRequireDefault(require("prop-types"));var _animation=require("./utils/animation");var _jsxFileName="/Users/trinh.ho2/momo-folk/kits/src/libs/carousel/dist/Carousel.js";function _getRequireWildcardCache(nodeInterop){if(typeof WeakMap!=="function")return null;var cacheBabelInterop=new WeakMap();var cacheNodeInterop=new WeakMap();return(_getRequireWildcardCache=function _getRequireWildcardCache(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop;})(nodeInterop);}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule){return obj;}if(obj===null||typeof obj!=="object"&&typeof obj!=="function"){return{default:obj};}var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj)){return cache.get(obj);}var newObj={};var hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj){if(key!=="default"&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;if(desc&&(desc.get||desc.set)){Object.defineProperty(newObj,key,desc);}else{newObj[key]=obj[key];}}}newObj.default=obj;if(cache){cache.set(obj,newObj);}return newObj;}function ownKeys(object,enumerableOnly){var keys=Object.keys(object);if(Object.getOwnPropertySymbols){var symbols=Object.getOwnPropertySymbols(object);if(enumerableOnly){symbols=symbols.filter(function(sym){return Object.getOwnPropertyDescriptor(object,sym).enumerable;});}keys.push.apply(keys,symbols);}return keys;}function _objectSpread(target){for(var i=1;i<arguments.length;i++){var source=arguments[i]!=null?arguments[i]:{};if(i%2){ownKeys(Object(source),true).forEach(function(key){(0,_defineProperty2.default)(target,key,source[key]);});}else if(Object.getOwnPropertyDescriptors){Object.defineProperties(target,Object.getOwnPropertyDescriptors(source));}else{ownKeys(Object(source)).forEach(function(key){Object.defineProperty(target,key,Object.getOwnPropertyDescriptor(source,key));});}}return target;}function _createSuper(Derived){var hasNativeReflectConstruct=_isNativeReflectConstruct();return function _createSuperInternal(){var Super=(0,_getPrototypeOf2.default)(Derived),result;if(hasNativeReflectConstruct){var NewTarget=(0,_getPrototypeOf2.default)(this).constructor;result=Reflect.construct(Super,arguments,NewTarget);}else{result=Super.apply(this,arguments);}return(0,_possibleConstructorReturn2.default)(this,result);};}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));return true;}catch(e){return false;}}var IS_IOS=_reactNative.Platform.OS==='ios';var AnimatedFlatList=_reactNative.FlatList?_reactNative.Animated.createAnimatedComponent(_reactNative.FlatList):null;var AnimatedScrollView=_reactNative.Animated.createAnimatedComponent(_reactNative.ScrollView);var IS_RTL=_reactNative.I18nManager.isRTL;var Carousel=function(_PureComponent){(0,_inherits2.default)(Carousel,_PureComponent);var _super=_createSuper(Carousel);function Carousel(props){var _this;(0,_classCallCheck2.default)(this,Carousel);_this=_super.call(this,props);_this.state={hideCarousel:true,interpolators:[]};var initialActiveItem=_this._getFirstItem(props.firstItem);_this._activeItem=initialActiveItem;_this._previousActiveItem=initialActiveItem;_this._previousFirstItem=initialActiveItem;_this._previousItemsLength=initialActiveItem;_this._mounted=false;_this._positions=[];_this._currentContentOffset=0;_this._canFireBeforeCallback=false;_this._canFireCallback=false;_this._scrollOffsetRef=null;_this._onScrollTriggered=true;_this._lastScrollDate=0;_this._scrollEnabled=props.scrollEnabled!==false;_this._initPositionsAndInterpolators=_this._initPositionsAndInterpolators.bind((0,_assertThisInitialized2.default)(_this));_this._renderItem=_this._renderItem.bind((0,_assertThisInitialized2.default)(_this));_this._onSnap=_this._onSnap.bind((0,_assertThisInitialized2.default)(_this));_this._onLayout=_this._onLayout.bind((0,_assertThisInitialized2.default)(_this));_this._onScroll=_this._onScroll.bind((0,_assertThisInitialized2.default)(_this));_this._onScrollBeginDrag=props.enableSnap?_this._onScrollBeginDrag.bind((0,_assertThisInitialized2.default)(_this)):undefined;_this._onScrollEnd=props.enableSnap||props.autoplay?_this._onScrollEnd.bind((0,_assertThisInitialized2.default)(_this)):undefined;_this._onScrollEndDrag=!props.enableMomentum?_this._onScrollEndDrag.bind((0,_assertThisInitialized2.default)(_this)):undefined;_this._onMomentumScrollEnd=props.enableMomentum?_this._onMomentumScrollEnd.bind((0,_assertThisInitialized2.default)(_this)):undefined;_this._onTouchStart=_this._onTouchStart.bind((0,_assertThisInitialized2.default)(_this));_this._onTouchEnd=_this._onTouchEnd.bind((0,_assertThisInitialized2.default)(_this));_this._onTouchRelease=_this._onTouchRelease.bind((0,_assertThisInitialized2.default)(_this));_this._getKeyExtractor=_this._getKeyExtractor.bind((0,_assertThisInitialized2.default)(_this));_this._setScrollHandler(props);_this._ignoreNextMomentum=false;if(!_reactNative.ViewPropTypes){console.warn("react-native-snap-carousel: \n It is recommended to use at least version 0.44 of React Native with the plugin");}if(!props.vertical&&(!props.sliderWidth||!props.itemWidth)){console.warn("react-native-snap-carousel: You need to specify both sliderWidth and itemWidth \n for horizontal carousels");}if(props.vertical&&(!props.sliderHeight||!props.itemHeight)){console.warn("react-native-snap-carousel: You need to specify both sliderHeight and itemHeight \n for vertical carousels");}if(props.apparitionDelay&&!IS_IOS&&!props.useScrollView){console.warn("react-native-snap-carousel: Using apparitionDelay on Android \n is not recommended since it can lead to rendering issues");}if(props.customAnimationType||props.customAnimationOptions){console.warn("react-native-snap-carousel: Props customAnimationType and \n customAnimationOptions have been renamed to activeAnimationType and activeAnimationOptions");}if(props.onScrollViewScroll){console.warn("react-native-snap-carousel: Prop onScrollViewScroll has been removed. \n Use onScroll instead");}return _this;}(0,_createClass2.default)(Carousel,[{key:"componentDidMount",value:function componentDidMount(){var _this2=this;var _this$props=this.props,apparitionDelay=_this$props.apparitionDelay,autoplay=_this$props.autoplay,firstItem=_this$props.firstItem;var _firstItem=this._getFirstItem(firstItem);var apparitionCallback=function apparitionCallback(){_this2.setState({hideCarousel:false});if(autoplay){_this2.startAutoplay();}};this._mounted=true;this._initPositionsAndInterpolators();requestAnimationFrame(function(){if(!_this2._mounted){return;}_this2._snapToItem(_firstItem,false,false,true,false);_this2._hackActiveSlideAnimation(_firstItem,'start',true);if(apparitionDelay){_this2._apparitionTimeout=setTimeout(function(){apparitionCallback();},apparitionDelay);}else{apparitionCallback();}});}},{key:"UNSAFE_componentWillReceiveProps",value:function UNSAFE_componentWillReceiveProps(nextProps){var interpolators=this.state.interpolators;var _this$props2=this.props,itemHeight=_this$props2.itemHeight,itemWidth=_this$props2.itemWidth,scrollEnabled=_this$props2.scrollEnabled,sliderHeight=_this$props2.sliderHeight,sliderWidth=_this$props2.sliderWidth,onScroll=_this$props2.onScroll;var itemsLength=this._getCustomDataLength(nextProps);if(!itemsLength){return;}var nextFirstItem=this._getFirstItem(nextProps.firstItem,nextProps);var nextActiveItem=this._activeItem||this._activeItem===0?this._activeItem:nextFirstItem;var hasNewSliderWidth=nextProps.sliderWidth&&nextProps.sliderWidth!==sliderWidth;var hasNewSliderHeight=nextProps.sliderHeight&&nextProps.sliderHeight!==sliderHeight;var hasNewItemWidth=nextProps.itemWidth&&nextProps.itemWidth!==itemWidth;var hasNewItemHeight=nextProps.itemHeight&&nextProps.itemHeight!==itemHeight;var hasNewScrollEnabled=nextProps.scrollEnabled!==scrollEnabled;if(nextActiveItem>itemsLength-1){nextActiveItem=itemsLength-1;}if(hasNewScrollEnabled){this._setScrollEnabled(nextProps.scrollEnabled);}if(interpolators.length!==itemsLength||hasNewSliderWidth||hasNewSliderHeight||hasNewItemWidth||hasNewItemHeight){this._activeItem=nextActiveItem;this._previousItemsLength=itemsLength;this._initPositionsAndInterpolators(nextProps);if(this._previousItemsLength>itemsLength){this._hackActiveSlideAnimation(nextActiveItem,null,true);}if(hasNewSliderWidth||hasNewSliderHeight||hasNewItemWidth||hasNewItemHeight){this._snapToItem(nextActiveItem,false,false,false,false);}}else if(nextFirstItem!==this._previousFirstItem&&nextFirstItem!==this._activeItem){this._activeItem=nextFirstItem;this._previousFirstItem=nextFirstItem;this._snapToItem(nextFirstItem,false,true,false,false);}if(nextProps.onScroll!==onScroll){this._setScrollHandler(nextProps);}}},{key:"componentWillUnmount",value:function componentWillUnmount(){this._mounted=false;this.stopAutoplay();clearTimeout(this._apparitionTimeout);clearTimeout(this._hackSlideAnimationTimeout);clearTimeout(this._enableAutoplayTimeout);clearTimeout(this._autoplayTimeout);clearTimeout(this._snapNoMomentumTimeout);clearTimeout(this._edgeItemTimeout);clearTimeout(this._lockScrollTimeout);}},{key:"realIndex",get:function get(){return this._activeItem;}},{key:"currentIndex",get:function get(){return this._getDataIndex(this._activeItem);}},{key:"currentScrollPosition",get:function get(){return this._currentContentOffset;}},{key:"_setScrollHandler",value:function _setScrollHandler(props){var scrollEventConfig={listener:this._onScroll,useNativeDriver:true};this._scrollPos=new _reactNative.Animated.Value(0);var argMapping=props.vertical?[{nativeEvent:{contentOffset:{y:this._scrollPos}}}]:[{nativeEvent:{contentOffset:{x:this._scrollPos}}}];if(props.onScroll&&Array.isArray(props.onScroll._argMapping)){argMapping.pop();var _props$onScroll$_argM=(0,_slicedToArray2.default)(props.onScroll._argMapping,1),argMap=_props$onScroll$_argM[0];if(argMap&&argMap.nativeEvent&&argMap.nativeEvent.contentOffset){this._scrollPos=argMap.nativeEvent.contentOffset.x||argMap.nativeEvent.contentOffset.y||this._scrollPos;}argMapping.push.apply(argMapping,(0,_toConsumableArray2.default)(props.onScroll._argMapping));}this._onScrollHandler=_reactNative.Animated.event(argMapping,scrollEventConfig);}},{key:"_needsScrollView",value:function _needsScrollView(){var useScrollView=this.props.useScrollView;return useScrollView||!AnimatedFlatList||this._shouldUseStackLayout()||this._shouldUseTinderLayout();}},{key:"_needsRTLAdaptations",value:function _needsRTLAdaptations(){var vertical=this.props.vertical;return IS_RTL&&!IS_IOS&&!vertical;}},{key:"_canLockScroll",value:function _canLockScroll(){var _this$props3=this.props,scrollEnabled=_this$props3.scrollEnabled,enableMomentum=_this$props3.enableMomentum,lockScrollWhileSnapping=_this$props3.lockScrollWhileSnapping;return scrollEnabled&&!enableMomentum&&lockScrollWhileSnapping;}},{key:"_enableLoop",value:function _enableLoop(){var _this$props4=this.props,data=_this$props4.data,enableSnap=_this$props4.enableSnap,loop=_this$props4.loop;return enableSnap&&loop&&data&&data.length&&data.length>1;}},{key:"_shouldAnimateSlides",value:function _shouldAnimateSlides(){var props=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.props;var inactiveSlideOpacity=props.inactiveSlideOpacity,inactiveSlideScale=props.inactiveSlideScale,scrollInterpolator=props.scrollInterpolator,slideInterpolatedStyle=props.slideInterpolatedStyle;return inactiveSlideOpacity<1||inactiveSlideScale<1||!!scrollInterpolator||!!slideInterpolatedStyle||this._shouldUseShiftLayout()||this._shouldUseStackLayout()||this._shouldUseTinderLayout();}},{key:"_shouldUseCustomAnimation",value:function _shouldUseCustomAnimation(){var activeAnimationOptions=this.props.activeAnimationOptions;return!!activeAnimationOptions&&!this._shouldUseStackLayout()&&!this._shouldUseTinderLayout();}},{key:"_shouldUseShiftLayout",value:function _shouldUseShiftLayout(){var _this$props5=this.props,inactiveSlideShift=_this$props5.inactiveSlideShift,layout=_this$props5.layout;return layout==='default'&&inactiveSlideShift!==0;}},{key:"_shouldUseStackLayout",value:function _shouldUseStackLayout(){var layout=this.props.layout;return layout==='stack';}},{key:"_shouldUseTinderLayout",value:function _shouldUseTinderLayout(){var layout=this.props.layout;return layout==='tinder';}},{key:"_getCustomData",value:function _getCustomData(){var props=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.props;var data=props.data,loopClonesPerSide=props.loopClonesPerSide;var dataLength=data&&data.length;if(!dataLength){return[];}if(!this._enableLoop()){return data;}var previousItems=[];var nextItems=[];if(loopClonesPerSide>dataLength){var _previousItems2,_nextItems2;var dataMultiplier=Math.floor(loopClonesPerSide/dataLength);var remainder=loopClonesPerSide%dataLength;for(var i=0;i<dataMultiplier;i+=1){var _previousItems,_nextItems;(_previousItems=previousItems).push.apply(_previousItems,(0,_toConsumableArray2.default)(data));(_nextItems=nextItems).push.apply(_nextItems,(0,_toConsumableArray2.default)(data));}(_previousItems2=previousItems).unshift.apply(_previousItems2,(0,_toConsumableArray2.default)(data.slice(-remainder)));(_nextItems2=nextItems).push.apply(_nextItems2,(0,_toConsumableArray2.default)(data.slice(0,remainder)));}else{previousItems=data.slice(-loopClonesPerSide);nextItems=data.slice(0,loopClonesPerSide);}return previousItems.concat(data,nextItems);}},{key:"_getCustomDataLength",value:function _getCustomDataLength(){var props=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.props;var data=props.data,loopClonesPerSide=props.loopClonesPerSide;var dataLength=data&&data.length;if(!dataLength){return 0;}return this._enableLoop()?dataLength+2*loopClonesPerSide:dataLength;}},{key:"_getCustomIndex",value:function _getCustomIndex(index){var props=arguments.length>1&&arguments[1]!==undefined?arguments[1]:this.props;var itemsLength=this._getCustomDataLength(props);if(!itemsLength||!index&&index!==0){return 0;}return this._needsRTLAdaptations()?itemsLength-index-1:index;}},{key:"_getDataIndex",value:function _getDataIndex(index){var _this$props6=this.props,data=_this$props6.data,loopClonesPerSide=_this$props6.loopClonesPerSide;var dataLength=data&&data.length;if(!this._enableLoop()||!dataLength){return index;}if(index>=dataLength+loopClonesPerSide){return loopClonesPerSide>dataLength?(index-loopClonesPerSide)%dataLength:index-dataLength-loopClonesPerSide;}if(index<loopClonesPerSide){if(loopClonesPerSide>dataLength){var baseDataIndexes=[];var dataIndexes=[];var dataMultiplier=Math.floor(loopClonesPerSide/dataLength);var remainder=loopClonesPerSide%dataLength;for(var i=0;i<dataLength;i+=1){baseDataIndexes.push(i);}for(var j=0;j<dataMultiplier;j+=1){dataIndexes.push.apply(dataIndexes,baseDataIndexes);}dataIndexes.unshift.apply(dataIndexes,(0,_toConsumableArray2.default)(baseDataIndexes.slice(-remainder)));return dataIndexes[index];}return index+dataLength-loopClonesPerSide;}return index-loopClonesPerSide;}},{key:"_getPositionIndex",value:function _getPositionIndex(index){var _this$props7=this.props,loop=_this$props7.loop,loopClonesPerSide=_this$props7.loopClonesPerSide;return loop?index+loopClonesPerSide:index;}},{key:"_getFirstItem",value:function _getFirstItem(index){var props=arguments.length>1&&arguments[1]!==undefined?arguments[1]:this.props;var loopClonesPerSide=props.loopClonesPerSide;var itemsLength=this._getCustomDataLength(props);if(!itemsLength||index>itemsLength-1||index<0){return 0;}return this._enableLoop()?index+loopClonesPerSide:index;}},{key:"_getWrappedRef",value:function _getWrappedRef(){return this._carouselRef&&this._carouselRef.getNode&&this._carouselRef.getNode();}},{key:"_getScrollEnabled",value:function _getScrollEnabled(){return this._scrollEnabled;}},{key:"_setScrollEnabled",value:function _setScrollEnabled(){var scrollEnabled=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;var wrappedRef=this._getWrappedRef();if(!wrappedRef||!wrappedRef.setNativeProps){return;}wrappedRef.setNativeProps({scrollEnabled:scrollEnabled});this._scrollEnabled=scrollEnabled;}},{key:"_getKeyExtractor",value:function _getKeyExtractor(item,index){return this._needsScrollView()?"scrollview-item-"+index:"flatlist-item-"+index;}},{key:"_getScrollOffset",value:function _getScrollOffset(event){var vertical=this.props.vertical;return event&&event.nativeEvent&&event.nativeEvent.contentOffset&&event.nativeEvent.contentOffset[vertical?'y':'x']||0;}},{key:"_getContainerInnerMargin",value:function _getContainerInnerMargin(){var opposite=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;var _this$props8=this.props,sliderWidth=_this$props8.sliderWidth,sliderHeight=_this$props8.sliderHeight,itemWidth=_this$props8.itemWidth,itemHeight=_this$props8.itemHeight,vertical=_this$props8.vertical,activeSlideAlignment=_this$props8.activeSlideAlignment;if(activeSlideAlignment==='start'&&!opposite||activeSlideAlignment==='end'&&opposite){return 0;}if(activeSlideAlignment==='end'&&!opposite||activeSlideAlignment==='start'&&opposite){return vertical?sliderHeight-itemHeight:sliderWidth-itemWidth;}return vertical?(sliderHeight-itemHeight)/2:(sliderWidth-itemWidth)/2;}},{key:"_getViewportOffset",value:function _getViewportOffset(){var _this$props9=this.props,sliderWidth=_this$props9.sliderWidth,sliderHeight=_this$props9.sliderHeight,itemWidth=_this$props9.itemWidth,itemHeight=_this$props9.itemHeight,vertical=_this$props9.vertical,activeSlideAlignment=_this$props9.activeSlideAlignment;if(activeSlideAlignment==='start'){return vertical?itemHeight/2:itemWidth/2;}if(activeSlideAlignment==='end'){return vertical?sliderHeight-itemHeight/2:sliderWidth-itemWidth/2;}return vertical?sliderHeight/2:sliderWidth/2;}},{key:"_getCenter",value:function _getCenter(offset){return offset+this._getViewportOffset()-this._getContainerInnerMargin();}},{key:"_getActiveItem",value:function _getActiveItem(offset){var _this$props10=this.props,activeSlideOffset=_this$props10.activeSlideOffset,swipeThreshold=_this$props10.swipeThreshold;var center=this._getCenter(offset);var centerOffset=activeSlideOffset||swipeThreshold;for(var i=0;i<this._positions.length;i+=1){var _this$_positions$i=this._positions[i],start=_this$_positions$i.start,end=_this$_positions$i.end;if(center+centerOffset>=start&¢er-centerOffset<=end){return i;}}var lastIndex=this._positions.length-1;if(this._positions[lastIndex]&¢er-centerOffset>this._positions[lastIndex].end){return lastIndex;}return 0;}},{key:"_initPositionsAndInterpolators",value:function _initPositionsAndInterpolators(){var _this3=this;var props=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.props;var data=props.data,itemWidth=props.itemWidth,itemHeight=props.itemHeight,scrollInterpolator=props.scrollInterpolator,vertical=props.vertical;var sizeRef=vertical?itemHeight:itemWidth;if(!data||!data.length){return;}var interpolators=[];this._positions=[];this._getCustomData(props).forEach(function(itemData,index){var _index=_this3._getCustomIndex(index,props);var animatedValue;_this3._positions[index]={start:index*sizeRef,end:index*sizeRef+sizeRef};if(!_this3._shouldAnimateSlides(props)){animatedValue=new _reactNative.Animated.Value(1);}else if(_this3._shouldUseCustomAnimation()){animatedValue=new _reactNative.Animated.Value(_index===_this3._activeItem?1:0);}else{var interpolator;if(scrollInterpolator){interpolator=scrollInterpolator(_index,props);}else if(_this3._shouldUseStackLayout()){interpolator=(0,_animation.stackScrollInterpolator)(_index,props);}else if(_this3._shouldUseTinderLayout()){interpolator=(0,_animation.tinderScrollInterpolator)(_index,props);}if(!interpolator||!interpolator.inputRange||!interpolator.outputRange){interpolator=(0,_animation.defaultScrollInterpolator)(_index,props);}animatedValue=_this3._scrollPos.interpolate(_objectSpread(_objectSpread({},interpolator),{},{extrapolate:'clamp'}));}interpolators.push(animatedValue);});this.setState({interpolators:interpolators});}},{key:"_getSlideAnimation",value:function _getSlideAnimation(index,toValue){var interpolators=this.state.interpolators;var _this$props11=this.props,activeAnimationType=_this$props11.activeAnimationType,activeAnimationOptions=_this$props11.activeAnimationOptions;var animatedValue=interpolators&&interpolators[index];if(!animatedValue&&animatedValue!==0){return null;}var animationCommonOptions=_objectSpread(_objectSpread({isInteraction:false,useNativeDriver:true},activeAnimationOptions),{},{toValue:toValue});return _reactNative.Animated.parallel([_reactNative.Animated.timing(animatedValue,_objectSpread(_objectSpread({},animationCommonOptions),{},{easing:_reactNative.Easing.linear})),_reactNative.Animated[activeAnimationType](animatedValue,_objectSpread({},animationCommonOptions))]);}},{key:"_playCustomSlideAnimation",value:function _playCustomSlideAnimation(current,next){var interpolators=this.state.interpolators;var itemsLength=this._getCustomDataLength();var _currentIndex=this._getCustomIndex(current);var _currentDataIndex=this._getDataIndex(_currentIndex);var _nextIndex=this._getCustomIndex(next);var _nextDataIndex=this._getDataIndex(_nextIndex);var animations=[];if(this._enableLoop()){for(var i=0;i<itemsLength;i+=1){if(this._getDataIndex(i)===_currentDataIndex&&interpolators[i]){animations.push(this._getSlideAnimation(i,0));}else if(this._getDataIndex(i)===_nextDataIndex&&interpolators[i]){animations.push(this._getSlideAnimation(i,1));}}}else{if(interpolators[current]){animations.push(this._getSlideAnimation(current,0));}if(interpolators[next]){animations.push(this._getSlideAnimation(next,1));}}_reactNative.Animated.parallel(animations,{stopTogether:false}).start();}},{key:"_hackActiveSlideAnimation",value:function _hackActiveSlideAnimation(index,goTo){var _this4=this;var force=arguments.length>2&&arguments[2]!==undefined?arguments[2]:false;var data=this.props.data;if(!this._mounted||!this._carouselRef||!this._positions[index]||!force&&this._enableLoop()){return;}var offset=this._positions[index]&&this._positions[index].start;if(!offset&&offset!==0){return;}var itemsLength=data&&data.length;var direction=goTo||itemsLength===1?'start':'end';this._scrollTo(offset+(direction==='start'?-1:1),false);clearTimeout(this._hackSlideAnimationTimeout);this._hackSlideAnimationTimeout=setTimeout(function(){_this4._scrollTo(offset,false);},50);}},{key:"_lockScroll",value:function _lockScroll(){var _this5=this;var lockScrollTimeoutDuration=this.props.lockScrollTimeoutDuration;clearTimeout(this._lockScrollTimeout);this._lockScrollTimeout=setTimeout(function(){_this5._releaseScroll();},lockScrollTimeoutDuration);this._setScrollEnabled(false);}},{key:"_releaseScroll",value:function _releaseScroll(){clearTimeout(this._lockScrollTimeout);this._setScrollEnabled(true);}},{key:"_repositionScroll",value:function _repositionScroll(index){var _this$props12=this.props,data=_this$props12.data,loopClonesPerSide=_this$props12.loopClonesPerSide;var dataLength=data&&data.length;if(!this._enableLoop()||!dataLength||index>=loopClonesPerSide&&index<dataLength+loopClonesPerSide){return;}var repositionTo=index;if(index>=dataLength+loopClonesPerSide){repositionTo=index-dataLength;}else if(index<loopClonesPerSide){repositionTo=index+dataLength;}this._snapToItem(repositionTo,false,false,false,false);}},{key:"_scrollTo",value:function _scrollTo(offset){var animated=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;var vertical=this.props.vertical;var wrappedRef=this._getWrappedRef();if(!this._mounted||!wrappedRef){return;}var specificOptions=this._needsScrollView()?{x:vertical?0:offset,y:vertical?offset:0}:{offset:offset};var options=_objectSpread(_objectSpread({},specificOptions),{},{animated:animated});if(this._needsScrollView()){wrappedRef.scrollTo(options);}else{wrappedRef.scrollToOffset(options);}}},{key:"_onScroll",value:function _onScroll(event){var _this$props13=this.props,callbackOffsetMargin=_this$props13.callbackOffsetMargin,enableMomentum=_this$props13.enableMomentum,onScroll=_this$props13.onScroll;var scrollOffset=event?this._getScrollOffset(event):this._currentContentOffset;var nextActiveItem=this._getActiveItem(scrollOffset);var itemReached=nextActiveItem===this._itemToSnapTo;var scrollConditions=scrollOffset>=this._scrollOffsetRef-callbackOffsetMargin&&scrollOffset<=this._scrollOffsetRef+callbackOffsetMargin;this._currentContentOffset=scrollOffset;this._onScrollTriggered=true;this._lastScrollDate=Date.now();if(this._activeItem!==nextActiveItem&&this._shouldUseCustomAnimation()){this._playCustomSlideAnimation(this._activeItem,nextActiveItem);}if(enableMomentum){clearTimeout(this._snapNoMomentumTimeout);if(this._activeItem!==nextActiveItem){this._activeItem=nextActiveItem;}if(itemReached){if(this._canFireBeforeCallback){this._onBeforeSnap(this._getDataIndex(nextActiveItem));}if(scrollConditions&&this._canFireCallback){this._onSnap(this._getDataIndex(nextActiveItem));}}}else if(this._activeItem!==nextActiveItem&&itemReached){if(this._canFireBeforeCallback){this._onBeforeSnap(this._getDataIndex(nextActiveItem));}if(scrollConditions){this._activeItem=nextActiveItem;if(this._canLockScroll()){this._releaseScroll();}if(this._canFireCallback){this._onSnap(this._getDataIndex(nextActiveItem));}}}if(nextActiveItem===this._itemToSnapTo&&scrollOffset===this._scrollOffsetRef){this._repositionScroll(nextActiveItem);}if(typeof onScroll==='function'&&event){onScroll(event);}}},{key:"_onStartShouldSetResponderCapture",value:function _onStartShouldSetResponderCapture(event){var onStartShouldSetResponderCapture=this.props.onStartShouldSetResponderCapture;if(onStartShouldSetResponderCapture){onStartShouldSetResponderCapture(event);}return this._getScrollEnabled();}},{key:"_onTouchStart",value:function _onTouchStart(){var onTouchStart=this.props.onTouchStart;if(this._getScrollEnabled()!==false&&this._autoplaying){this.stopAutoplay();}if(onTouchStart){onTouchStart();}}},{key:"_onTouchEnd",value:function _onTouchEnd(){var _this$props14=this.props,onTouchEnd=_this$props14.onTouchEnd,autoplay=_this$props14.autoplay;if(this._getScrollEnabled()!==false&&autoplay&&!this._autoplaying){this.startAutoplay();}if(onTouchEnd){onTouchEnd();}}},{key:"_onScrollBeginDrag",value:function _onScrollBeginDrag(event){var onScrollBeginDrag=this.props.onScrollBeginDrag;if(!this._getScrollEnabled()){return;}this._scrollStartOffset=this._getScrollOffset(event);this._scrollStartActive=this._getActiveItem(this._scrollStartOffset);this._ignoreNextMomentum=false;if(onScrollBeginDrag){onScrollBeginDrag(event);}}},{key:"_onScrollEndDrag",value:function _onScrollEndDrag(event){var onScrollEndDrag=this.props.onScrollEndDrag;if(this._carouselRef){if(this._onScrollEnd)this._onScrollEnd();}if(onScrollEndDrag){onScrollEndDrag(event);}}},{key:"_onMomentumScrollEnd",value:function _onMomentumScrollEnd(event){var onMomentumScrollEnd=this.props.onMomentumScrollEnd;if(this._carouselRef){if(this._onScrollEnd)this._onScrollEnd();}if(onMomentumScrollEnd){onMomentumScrollEnd(event);}}},{key:"_onScrollEnd",value:function _onScrollEnd(){var _this6=this;var _this$props15=this.props,autoplay=_this$props15.autoplay,autoplayDelay=_this$props15.autoplayDelay,enableSnap=_this$props15.enableSnap;if(this._ignoreNextMomentum){this._ignoreNextMomentum=false;return;}this._scrollEndOffset=this._currentContentOffset;this._scrollEndActive=this._getActiveItem(this._scrollEndOffset);if(enableSnap){this._snapScroll(this._scrollEndOffset-this._scrollStartOffset);}if(autoplay&&!this._autoplaying){clearTimeout(this._enableAutoplayTimeout);this._enableAutoplayTimeout=setTimeout(function(){_this6.startAutoplay();},autoplayDelay+50);}}},{key:"_onTouchRelease",value:function _onTouchRelease(){var _this7=this;var enableMomentum=this.props.enableMomentum;if(enableMomentum&&IS_IOS){clearTimeout(this._snapNoMomentumTimeout);this._snapNoMomentumTimeout=setTimeout(function(){_this7._snapToItem(_this7._activeItem);},100);}}},{key:"_onLayout",value:function _onLayout(event){var onLayout=this.props.onLayout;if(this._onLayoutInitDone){this._initPositionsAndInterpolators();this._snapToItem(this._activeItem,false,false,false,false);}else{this._onLayoutInitDone=true;}if(onLayout){onLayout(event);}}},{key:"_snapScroll",value:function _snapScroll(delta){var swipeThreshold=this.props.swipeThreshold;if(!this._scrollEndActive&&this._scrollEndActive!==0&&IS_IOS){this._scrollEndActive=this._scrollStartActive;}if(this._scrollStartActive!==this._scrollEndActive){this._snapToItem(this._scrollEndActive);}else{if(delta>0){if(delta>swipeThreshold){this._snapToItem(this._scrollStartActive+1);}else{this._snapToItem(this._scrollEndActive);}}else if(delta<0){if(delta<-swipeThreshold){this._snapToItem(this._scrollStartActive-1);}else{this._snapToItem(this._scrollEndActive);}}else{this._snapToItem(this._scrollEndActive);}}}},{key:"_snapToItem",value:function _snapToItem(index){var _this8=this;var animated=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;var fireCallback=arguments.length>2&&arguments[2]!==undefined?arguments[2]:true;var initial=arguments.length>3&&arguments[3]!==undefined?arguments[3]:false;var lockScroll=arguments.length>4&&arguments[4]!==undefined?arguments[4]:true;var _this$props16=this.props,enableMomentum=_this$props16.enableMomentum,onSnapToItem=_this$props16.onSnapToItem,onBeforeSnapToItem=_this$props16.onBeforeSnapToItem;var itemsLength=this._getCustomDataLength();var wrappedRef=this._getWrappedRef();if(!itemsLength||!wrappedRef){return;}if(!index||index<0){index=0;}else if(itemsLength>0&&index>=itemsLength){index=itemsLength-1;}if(index!==this._previousActiveItem){this._previousActiveItem=index;if(lockScroll&&this._canLockScroll()){this._lockScroll();}if(fireCallback){if(onBeforeSnapToItem){this._canFireBeforeCallback=true;}if(onSnapToItem){this._canFireCallback=true;}}}this._itemToSnapTo=index;this._scrollOffsetRef=this._positions[index]&&this._positions[index].start;this._onScrollTriggered=false;if(!this._scrollOffsetRef&&this._scrollOffsetRef!==0){return;}this._scrollTo(this._scrollOffsetRef,animated);if(enableMomentum){if(IS_IOS&&!initial){this._ignoreNextMomentum=true;}if(index===0||index===itemsLength-1){clearTimeout(this._edgeItemTimeout);this._edgeItemTimeout=setTimeout(function(){if(!initial&&index===_this8._activeItem&&!_this8._onScrollTriggered){_this8._onScroll();}},250);}}}},{key:"_onBeforeSnap",value:function _onBeforeSnap(index){var onBeforeSnapToItem=this.props.onBeforeSnapToItem;if(!this._carouselRef){return;}this._canFireBeforeCallback=false;if(onBeforeSnapToItem)onBeforeSnapToItem(index);}},{key:"_onSnap",value:function _onSnap(index){var onSnapToItem=this.props.onSnapToItem;if(!this._carouselRef){return;}this._canFireCallback=false;if(onSnapToItem)onSnapToItem(index);}},{key:"startAutoplay",value:function startAutoplay(){var _this9=this;var _this$props17=this.props,autoplayInterval=_this$props17.autoplayInterval,autoplayDelay=_this$props17.autoplayDelay;if(this._autoplaying){return;}clearTimeout(this._autoplayTimeout);this._autoplayTimeout=setTimeout(function(){_this9._autoplaying=true;_this9._autoplayInterval=setInterval(function(){if(_this9._autoplaying){_this9.snapToNext();}},autoplayInterval);},autoplayDelay);}},{key:"stopAutoplay",value:function stopAutoplay(){this._autoplaying=false;clearInterval(this._autoplayInterval);}},{key:"snapToItem",value:function snapToItem(index){var animated=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;var fireCallback=arguments.length>2&&arguments[2]!==undefined?arguments[2]:true;if(!index||index<0){index=0;}var positionIndex=this._getPositionIndex(index);if(positionIndex===this._activeItem){return;}this._snapToItem(positionIndex,animated,fireCallback);}},{key:"snapToNext",value:function snapToNext(){var animated=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;var fireCallback=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;var itemsLength=this._getCustomDataLength();var newIndex=this._activeItem+1;if(newIndex>itemsLength-1){if(!this._enableLoop()){return;}newIndex=0;}this._snapToItem(newIndex,animated,fireCallback);}},{key:"snapToPrev",value:function snapToPrev(){var animated=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;var fireCallback=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;var itemsLength=this._getCustomDataLength();var newIndex=this._activeItem-1;if(newIndex<0){if(!this._enableLoop()){return;}newIndex=itemsLength-1;}this._snapToItem(newIndex,animated,fireCallback);}},{key:"triggerRenderingHack",value:function triggerRenderingHack(offset){if(Date.now()-this._lastScrollDate<500){return;}var scrollPosition=this._currentContentOffset;if(!scrollPosition&&scrollPosition!==0){return;}var scrollOffset=offset||(scrollPosition===0?1:-1);this._scrollTo(scrollPosition+scrollOffset,false);}},{key:"_getSlideInterpolatedStyle",value:function _getSlideInterpolatedStyle(index,animatedValue){var _this$props18=this.props,layoutCardOffset=_this$props18.layoutCardOffset,slideInterpolatedStyle=_this$props18.slideInterpolatedStyle;if(slideInterpolatedStyle){return slideInterpolatedStyle(index,animatedValue,this.props);}if(this._shouldUseTinderLayout()){return(0,_animation.tinderAnimatedStyles)(index,animatedValue,this.props,layoutCardOffset);}if(this._shouldUseStackLayout()){return(0,_animation.stackAnimatedStyles)(index,animatedValue,this.props,layoutCardOffset);}if(this._shouldUseShiftLayout()){return(0,_animation.shiftAnimatedStyles)(index,animatedValue,this.props);}return(0,_animation.defaultAnimatedStyles)(index,animatedValue,this.props);}},{key:"_renderItem",value:function _renderItem(_ref){var item=_ref.item,index=_ref.index;var interpolators=this.state.interpolators;var _this$props19=this.props,hasParallaxImages=_this$props19.hasParallaxImages,itemWidth=_this$props19.itemWidth,itemHeight=_this$props19.itemHeight,keyExtractor=_this$props19.keyExtractor,renderItem=_this$props19.renderItem,sliderHeight=_this$props19.sliderHeight,sliderWidth=_this$props19.sliderWidth,slideStyle=_this$props19.slideStyle,vertical=_this$props19.vertical,isCustomScrollWidth=_this$props19.isCustomScrollWidth;var animatedValue=interpolators&&interpolators[index];if(!animatedValue&&animatedValue!==0){return null;}var animate=this._shouldAnimateSlides();var ComponentView=animate?_reactNative.Animated.View:_reactNative.View;var animatedStyle=animate?this._getSlideInterpolatedStyle(index,animatedValue):{};var parallaxProps=hasParallaxImages?{scrollPosition:this._scrollPos,carouselRef:this._carouselRef,vertical:vertical,sliderWidth:sliderWidth,sliderHeight:sliderHeight,itemWidth:itemWidth,itemHeight:itemHeight}:undefined;var specificProps=this._needsScrollView()?{key:keyExtractor?keyExtractor(item,index):this._getKeyExtractor(item,index)}:{};var mainDimension=isCustomScrollWidth?{}:{width:itemWidth};return _react.default.createElement(ComponentView,(0,_extends2.default)({style:[mainDimension,slideStyle,animatedStyle],pointerEvents:"box-none"},specificProps,{__source:{fileName:_jsxFileName,lineNumber:1159,columnNumber:13}}),renderItem({item:item,index:index,realIndex:this._getDataIndex(index),activeIndex:this._getDataIndex(this._activeItem)},parallaxProps));}},{key:"_getComponentOverridableProps",value:function _getComponentOverridableProps(){var _this$props20=this.props,enableMomentum=_this$props20.enableMomentum,itemWidth=_this$props20.itemWidth,itemHeight=_this$props20.itemHeight,loopClonesPerSide=_this$props20.loopClonesPerSide,sliderWidth=_this$props20.sliderWidth,sliderHeight=_this$props20.sliderHeight,vertical=_this$props20.vertical;var visibleItems=Math.ceil(vertical?sliderHeight/itemHeight:sliderWidth/itemWidth)+1;var initialNumPerSide=this._enableLoop()?loopClonesPerSide:2;var initialNumToRender=visibleItems+initialNumPerSide*2;var maxToRenderPerBatch=1+initialNumToRender*2;var windowSize=maxToRenderPerBatch;var specificProps=!this._needsScrollView()?{initialNumToRender:initialNumToRender,maxToRenderPerBatch:maxToRenderPerBatch,windowSize:windowSize}:{};return _objectSpread({decelerationRate:enableMomentum?0.9:'fast',showsHorizontalScrollIndicator:false,showsVerticalScrollIndicator:false,overScrollMode:'never',automaticallyAdjustContentInsets:false,directionalLockEnabled:true,pinchGestureEnabled:false,scrollsToTop:false,removeClippedSubviews:!this._needsScrollView(),inverted:this._needsRTLAdaptations()},specificProps);}},{key:"_getComponentStaticProps",value:function _getComponentStaticProps(){var _this10=this;var hideCarousel=this.state.hideCarousel;var _this$props21=this.props,containerCustomStyle=_this$props21.containerCustomStyle,contentContainerCustomStyle=_this$props21.contentContainerCustomStyle,keyExtractor=_this$props21.keyExtractor,sliderWidth=_this$props21.sliderWidth,sliderHeight=_this$props21.sliderHeight,style=_this$props21.style,vertical=_this$props21.vertical;var containerStyle=[containerCustomStyle||style||{},hideCarousel?{opacity:0}:{},vertical?{height:sliderHeight,flexDirection:'column'}:{width:sliderWidth,flexDirection:this._needsRTLAdaptations()?'row-reverse':'row'}];var contentContainerStyle=[vertical?{paddingTop:this._getContainerInnerMargin(),paddingBottom:this._getContainerInnerMargin(true)}:{paddingLeft:this._getContainerInnerMargin(),paddingRight:this._getContainerInnerMargin(true)},contentContainerCustomStyle||{}];var specificProps=!this._needsScrollView()?{renderItem:this._renderItem,numColumns:1,getItemLayout:undefined,initialScrollIndex:undefined,keyExtractor:keyExtractor||this._getKeyExtractor}:{};return _objectSpread({ref:function ref(c){return _this10._carouselRef=c;},data:this._getCustomData(),style:containerStyle,contentContainerStyle:contentContainerStyle,horizontal:!vertical,scrollEventThrottle:1,onScroll:this._onScrollHandler,onScrollBeginDrag:this._onScrollBeginDrag,onScrollEndDrag:this._onScrollEndDrag,onMomentumScrollEnd:this._onMomentumScrollEnd,onResponderRelease:this._onTouchRelease,onStartShouldSetResponderCapture:this._onStartShouldSetResponderCapture,onTouchStart:this._onTouchStart,onTouchEnd:this._onScrollEnd,onLayout:this._onLayout},specificProps);}},{key:"render",value:function render(){var _this11=this;var _this$props22=this.props,data=_this$props22.data,renderItem=_this$props22.renderItem,useScrollView=_this$props22.useScrollView;if(!data||!renderItem){return null;}var props=_objectSpread(_objectSpread(_objectSpread({},this._getComponentOverridableProps()),this.props),this._getComponentStaticProps());var ScrollViewComponent=typeof useScrollView==='function'?useScrollView:AnimatedScrollView;return this._needsScrollView()?_react.default.createElement(ScrollViewComponent,(0,_extends2.default)({},props,{__source:{fileName:_jsxFileName,lineNumber:1289,columnNumber:13}}),this._getCustomData().map(function(item,index){return _this11._renderItem({item:item,index:index,realIndex:_this11._getDataIndex(index),activeIndex:_this11._getDataIndex(_this11._activeItem)});})):_react.default.createElement(AnimatedFlatList,(0,_extends2.default)({},props,{__source:{fileName:_jsxFileName,lineNumber:1297,columnNumber:13}}));}}]);return Carousel;}(_react.PureComponent);exports.default=Carousel;Carousel.propTypes={data:_propTypes.default.array.isRequired,renderItem:_propTypes.default.func.isRequired,itemWidth:_propTypes.default.number,itemHeight:_propTypes.default.number,sliderWidth:_propTypes.default.number,sliderHeight:_propTypes.default.number,activeAnimationType:_propTypes.default.string,activeAnimationOptions:_propTypes.default.object,activeSlideAlignment:_propTypes.default.oneOf(['center','end','start']),activeSlideOffset:_propTypes.default.number,apparitionDelay:_propTypes.default.number,autoplay:_propTypes.default.bool,autoplayDelay:_propTypes.default.number,autoplayInterval:_propTypes.default.number,callbackOffsetMargin:_propTypes.default.number,containerCustomStyle:_propTypes.default.oneOfType([_propTypes.default.object,_propTypes.default.array]),contentContainerCustomStyle:_propTypes.default.oneOfType([_propTypes.default.object,_propTypes.default.array]),enableMomentum:_propTypes.default.bool,enableSnap:_propTypes.default.bool,firstItem:_propTypes.default.number,hasParallaxImages:_propTypes.default.bool,inactiveSlideOpacity:_propTypes.default.number,inactiveSlideScale:_propTypes.default.number,inactiveSlideShift:_propTypes.default.number,layout:_propTypes.default.oneOf(['default','stack','tinder']),layoutCardOffset:_propTypes.default.number,lockScrollTimeoutDuration:_propTypes.default.number,lockScrollWhileSnapping:_propTypes.default.bool,loop:_propTypes.default.bool,loopClonesPerSide:_propTypes.default.number,scrollEnabled:_propTypes.default.bool,scrollInterpolator:_propTypes.default.func,slideInterpolatedStyle:_propTypes.default.func,slideStyle:_propTypes.default.object,shouldOptimizeUpdates:_propTypes.default.bool,swipeThreshold:_propTypes.default.number,useScrollView:_propTypes.default.oneOfType([_propTypes.default.bool,_propTypes.default.func]),vertical:_propTypes.default.bool,showsPagination:_propTypes.default.bool,isCustomScrollWidth:_propTypes.default.bool,onBeforeSnapToItem:_propTypes.default.func,onSnapToItem:_propTypes.default.func};Carousel.defaultProps={activeAnimationType:'timing',activeAnimationOptions:null,activeSlideAlignment:'center',activeSlideOffset:20,apparitionDelay:0,autoplay:false,autoplayDelay:1000,autoplayInterval:3000,callbackOffsetMargin:5,containerCustomStyle:{},contentContainerCustomStyle:{},enableMomentum:false,enableSnap:true,firstItem:0,hasParallaxImages:false,inactiveSlideOpacity:0.7,inactiveSlideScale:0.9,inactiveSlideShift:0,layout:'default',lockScrollTimeoutDuration:1000,lockScrollWhileSnapping:false,loop:false,loopClonesPerSide:3,scrollEnabled:true,slideStyle:{},shouldOptimizeUpdates:true,swipeThreshold:20,useScrollView:!AnimatedFlatList,vertical:false,showsPagination:true,isCustomScrollWidth:false};
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
/* eslint-disable no-lonely-if */
|
|
3
|
+
/* eslint-disable no-param-reassign */
|
|
4
|
+
/* eslint-disable react/jsx-props-no-spreading */
|
|
5
|
+
import React, { PureComponent } from 'react';
|
|
6
|
+
import {
|
|
7
|
+
Animated, Easing, FlatList, I18nManager, Platform, ScrollView, View, ViewPropTypes
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
import PropTypes from 'prop-types';
|
|
10
|
+
import {
|
|
11
|
+
defaultScrollInterpolator,
|
|
12
|
+
stackScrollInterpolator,
|
|
13
|
+
tinderScrollInterpolator,
|
|
14
|
+
defaultAnimatedStyles,
|
|
15
|
+
shiftAnimatedStyles,
|
|
16
|
+
stackAnimatedStyles,
|
|
17
|
+
tinderAnimatedStyles
|
|
18
|
+
} from './utils/animation';
|
|
19
|
+
|
|
20
|
+
const IS_IOS = Platform.OS === 'ios';
|
|
21
|
+
|
|
22
|
+
// Native driver for scroll events
|
|
23
|
+
// See: https://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html
|
|
24
|
+
const AnimatedFlatList = FlatList ? Animated.createAnimatedComponent(FlatList) : null;
|
|
25
|
+
const AnimatedScrollView = Animated.createAnimatedComponent(ScrollView);
|
|
26
|
+
|
|
27
|
+
// React Native automatically handles RTL layouts; unfortunately, it's buggy with horizontal ScrollView
|
|
28
|
+
// See https://github.com/facebook/react-native/issues/11960
|
|
29
|
+
// NOTE: the following variable is not declared in the constructor
|
|
30
|
+
// otherwise it is undefined at init, which messes with custom indexes
|
|
31
|
+
const IS_RTL = I18nManager.isRTL;
|
|
32
|
+
|
|
33
|
+
export default class Carousel extends PureComponent {
|
|
34
|
+
constructor(props) {
|
|
35
|
+
super(props);
|
|
36
|
+
|
|
37
|
+
this.state = {
|
|
38
|
+
hideCarousel: true,
|
|
39
|
+
interpolators: []
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// The following values are not stored in the state because 'setState()' is asynchronous
|
|
43
|
+
// and this results in an absolutely crappy behavior on Android while swiping (see #156)
|
|
44
|
+
const initialActiveItem = this._getFirstItem(props.firstItem);
|
|
45
|
+
this._activeItem = initialActiveItem;
|
|
46
|
+
this._previousActiveItem = initialActiveItem;
|
|
47
|
+
this._previousFirstItem = initialActiveItem;
|
|
48
|
+
this._previousItemsLength = initialActiveItem;
|
|
49
|
+
|
|
50
|
+
this._mounted = false;
|
|
51
|
+
this._positions = [];
|
|
52
|
+
this._currentContentOffset = 0; // store ScrollView's scroll position
|
|
53
|
+
this._canFireBeforeCallback = false;
|
|
54
|
+
this._canFireCallback = false;
|
|
55
|
+
this._scrollOffsetRef = null;
|
|
56
|
+
this._onScrollTriggered = true; // used when momentum is enabled to prevent an issue with edges items
|
|
57
|
+
this._lastScrollDate = 0; // used to work around a FlatList bug
|
|
58
|
+
this._scrollEnabled = props.scrollEnabled !== false;
|
|
59
|
+
|
|
60
|
+
this._initPositionsAndInterpolators = this._initPositionsAndInterpolators.bind(this);
|
|
61
|
+
this._renderItem = this._renderItem.bind(this);
|
|
62
|
+
this._onSnap = this._onSnap.bind(this);
|
|
63
|
+
|
|
64
|
+
this._onLayout = this._onLayout.bind(this);
|
|
65
|
+
this._onScroll = this._onScroll.bind(this);
|
|
66
|
+
this._onScrollBeginDrag = props.enableSnap ? this._onScrollBeginDrag.bind(this) : undefined;
|
|
67
|
+
this._onScrollEnd = props.enableSnap || props.autoplay ? this._onScrollEnd.bind(this) : undefined;
|
|
68
|
+
this._onScrollEndDrag = !props.enableMomentum ? this._onScrollEndDrag.bind(this) : undefined;
|
|
69
|
+
this._onMomentumScrollEnd = props.enableMomentum ? this._onMomentumScrollEnd.bind(this) : undefined;
|
|
70
|
+
this._onTouchStart = this._onTouchStart.bind(this);
|
|
71
|
+
this._onTouchEnd = this._onTouchEnd.bind(this);
|
|
72
|
+
this._onTouchRelease = this._onTouchRelease.bind(this);
|
|
73
|
+
|
|
74
|
+
this._getKeyExtractor = this._getKeyExtractor.bind(this);
|
|
75
|
+
|
|
76
|
+
this._setScrollHandler(props);
|
|
77
|
+
|
|
78
|
+
// This bool aims at fixing an iOS bug due to scrollTo that triggers onMomentumScrollEnd.
|
|
79
|
+
// onMomentumScrollEnd fires this._snapScroll, thus creating an infinite loop.
|
|
80
|
+
this._ignoreNextMomentum = false;
|
|
81
|
+
this._animated = false;
|
|
82
|
+
|
|
83
|
+
// Warnings
|
|
84
|
+
if (!ViewPropTypes) {
|
|
85
|
+
console.warn(`react-native-snap-carousel:
|
|
86
|
+
It is recommended to use at least version 0.44 of React Native with the plugin`);
|
|
87
|
+
}
|
|
88
|
+
if (!props.vertical && (!props.sliderWidth || !props.itemWidth)) {
|
|
89
|
+
console.warn(`react-native-snap-carousel: You need to specify both sliderWidth and itemWidth
|
|
90
|
+
for horizontal carousels`);
|
|
91
|
+
}
|
|
92
|
+
if (props.vertical && (!props.sliderHeight || !props.itemHeight)) {
|
|
93
|
+
console.warn(`react-native-snap-carousel: You need to specify both sliderHeight and itemHeight
|
|
94
|
+
for vertical carousels`);
|
|
95
|
+
}
|
|
96
|
+
if (props.apparitionDelay && !IS_IOS && !props.useScrollView) {
|
|
97
|
+
console.warn(`react-native-snap-carousel: Using apparitionDelay on Android
|
|
98
|
+
is not recommended since it can lead to rendering issues`);
|
|
99
|
+
}
|
|
100
|
+
if (props.customAnimationType || props.customAnimationOptions) {
|
|
101
|
+
console.warn(`react-native-snap-carousel: Props customAnimationType and
|
|
102
|
+
customAnimationOptions have been renamed to activeAnimationType and activeAnimationOptions`);
|
|
103
|
+
}
|
|
104
|
+
if (props.onScrollViewScroll) {
|
|
105
|
+
console.warn(`react-native-snap-carousel: Prop onScrollViewScroll has been removed.
|
|
106
|
+
Use onScroll instead`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
componentDidMount() {
|
|
111
|
+
const { apparitionDelay, autoplay, firstItem } = this.props;
|
|
112
|
+
const _firstItem = this._getFirstItem(firstItem);
|
|
113
|
+
const apparitionCallback = () => {
|
|
114
|
+
this.setState({ hideCarousel: false });
|
|
115
|
+
if (autoplay) {
|
|
116
|
+
this.startAutoplay();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
this._mounted = true;
|
|
121
|
+
this._initPositionsAndInterpolators();
|
|
122
|
+
|
|
123
|
+
// Without 'requestAnimationFrame' or a `0` timeout, images will randomly not be rendered on Android...
|
|
124
|
+
requestAnimationFrame(() => {
|
|
125
|
+
if (!this._mounted) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
this._snapToItem(_firstItem, false, false, true, false);
|
|
130
|
+
this._hackActiveSlideAnimation(_firstItem, 'start', true);
|
|
131
|
+
|
|
132
|
+
if (apparitionDelay) {
|
|
133
|
+
this._apparitionTimeout = setTimeout(() => {
|
|
134
|
+
apparitionCallback();
|
|
135
|
+
}, apparitionDelay);
|
|
136
|
+
} else {
|
|
137
|
+
apparitionCallback();
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// shouldComponentUpdate(nextProps, nextState) {
|
|
143
|
+
// const { shouldOptimizeUpdates } = this.props;
|
|
144
|
+
// if (shouldOptimizeUpdates === false) {
|
|
145
|
+
// return true;
|
|
146
|
+
// }
|
|
147
|
+
// if (shallowCompare(this.props, nextProps)) {
|
|
148
|
+
// return true;
|
|
149
|
+
// }
|
|
150
|
+
// if (shallowCompare(this.state, nextState)) {
|
|
151
|
+
// return true;
|
|
152
|
+
// }
|
|
153
|
+
// return false;
|
|
154
|
+
// }
|
|
155
|
+
|
|
156
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
157
|
+
const { interpolators } = this.state;
|
|
158
|
+
const {
|
|
159
|
+
itemHeight, itemWidth, scrollEnabled, sliderHeight, sliderWidth, onScroll
|
|
160
|
+
} = this.props;
|
|
161
|
+
const itemsLength = this._getCustomDataLength(nextProps);
|
|
162
|
+
|
|
163
|
+
if (!itemsLength) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const nextFirstItem = this._getFirstItem(nextProps.firstItem, nextProps);
|
|
168
|
+
let nextActiveItem = this._activeItem || this._activeItem === 0 ? this._activeItem : nextFirstItem;
|
|
169
|
+
|
|
170
|
+
const hasNewSliderWidth = nextProps.sliderWidth && nextProps.sliderWidth !== sliderWidth;
|
|
171
|
+
const hasNewSliderHeight = nextProps.sliderHeight && nextProps.sliderHeight !== sliderHeight;
|
|
172
|
+
const hasNewItemWidth = nextProps.itemWidth && nextProps.itemWidth !== itemWidth;
|
|
173
|
+
const hasNewItemHeight = nextProps.itemHeight && nextProps.itemHeight !== itemHeight;
|
|
174
|
+
const hasNewScrollEnabled = nextProps.scrollEnabled !== scrollEnabled;
|
|
175
|
+
|
|
176
|
+
// Prevent issues with dynamically removed items
|
|
177
|
+
if (nextActiveItem > itemsLength - 1) {
|
|
178
|
+
nextActiveItem = itemsLength - 1;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Handle changing scrollEnabled independent of user -> carousel interaction
|
|
182
|
+
if (hasNewScrollEnabled) {
|
|
183
|
+
this._setScrollEnabled(nextProps.scrollEnabled);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (interpolators.length !== itemsLength || hasNewSliderWidth
|
|
187
|
+
|| hasNewSliderHeight || hasNewItemWidth || hasNewItemHeight) {
|
|
188
|
+
this._activeItem = nextActiveItem;
|
|
189
|
+
this._previousItemsLength = itemsLength;
|
|
190
|
+
|
|
191
|
+
this._initPositionsAndInterpolators(nextProps);
|
|
192
|
+
|
|
193
|
+
// Handle scroll issue when dynamically removing items (see #133)
|
|
194
|
+
// This also fixes first item's active state on Android
|
|
195
|
+
// Because 'initialScrollIndex' apparently doesn't trigger scroll
|
|
196
|
+
if (this._previousItemsLength > itemsLength) {
|
|
197
|
+
this._hackActiveSlideAnimation(nextActiveItem, null, true);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (hasNewSliderWidth || hasNewSliderHeight || hasNewItemWidth || hasNewItemHeight) {
|
|
201
|
+
this._snapToItem(nextActiveItem, false, false, false, false);
|
|
202
|
+
}
|
|
203
|
+
} else if (nextFirstItem !== this._previousFirstItem && nextFirstItem !== this._activeItem) {
|
|
204
|
+
this._activeItem = nextFirstItem;
|
|
205
|
+
this._previousFirstItem = nextFirstItem;
|
|
206
|
+
this._snapToItem(nextFirstItem, false, true, false, false);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (nextProps.onScroll !== onScroll) {
|
|
210
|
+
this._setScrollHandler(nextProps);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
componentWillUnmount() {
|
|
215
|
+
this._mounted = false;
|
|
216
|
+
this.stopAutoplay();
|
|
217
|
+
clearTimeout(this._apparitionTimeout);
|
|
218
|
+
clearTimeout(this._hackSlideAnimationTimeout);
|
|
219
|
+
clearTimeout(this._enableAutoplayTimeout);
|
|
220
|
+
clearTimeout(this._autoplayTimeout);
|
|
221
|
+
clearTimeout(this._snapNoMomentumTimeout);
|
|
222
|
+
clearTimeout(this._edgeItemTimeout);
|
|
223
|
+
clearTimeout(this._lockScrollTimeout);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
get realIndex() {
|
|
227
|
+
return this._activeItem;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
get currentIndex() {
|
|
231
|
+
return this._getDataIndex(this._activeItem);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
get currentScrollPosition() {
|
|
235
|
+
return this._currentContentOffset;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
_setScrollHandler(props) {
|
|
239
|
+
// Native driver for scroll events
|
|
240
|
+
const scrollEventConfig = {
|
|
241
|
+
listener: this._onScroll,
|
|
242
|
+
useNativeDriver: true,
|
|
243
|
+
};
|
|
244
|
+
this._scrollPos = new Animated.Value(0);
|
|
245
|
+
const argMapping = props.vertical
|
|
246
|
+
? [{ nativeEvent: { contentOffset: { y: this._scrollPos } } }]
|
|
247
|
+
: [{ nativeEvent: { contentOffset: { x: this._scrollPos } } }];
|
|
248
|
+
|
|
249
|
+
if (props.onScroll && Array.isArray(props.onScroll._argMapping)) {
|
|
250
|
+
// Because of a react-native issue https://github.com/facebook/react-native/issues/13294
|
|
251
|
+
argMapping.pop();
|
|
252
|
+
const [argMap] = props.onScroll._argMapping;
|
|
253
|
+
if (argMap && argMap.nativeEvent && argMap.nativeEvent.contentOffset) {
|
|
254
|
+
// Shares the same animated value passed in props
|
|
255
|
+
this._scrollPos = argMap.nativeEvent.contentOffset.x
|
|
256
|
+
|| argMap.nativeEvent.contentOffset.y
|
|
257
|
+
|| this._scrollPos;
|
|
258
|
+
}
|
|
259
|
+
argMapping.push(...props.onScroll._argMapping);
|
|
260
|
+
}
|
|
261
|
+
this._onScrollHandler = Animated.event(
|
|
262
|
+
argMapping,
|
|
263
|
+
scrollEventConfig
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
_needsScrollView() {
|
|
268
|
+
const { useScrollView } = this.props;
|
|
269
|
+
return useScrollView || !AnimatedFlatList || this._shouldUseStackLayout() || this._shouldUseTinderLayout();
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
_needsRTLAdaptations() {
|
|
273
|
+
const { vertical } = this.props;
|
|
274
|
+
return IS_RTL && !IS_IOS && !vertical;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
_canLockScroll() {
|
|
278
|
+
const { scrollEnabled, enableMomentum, lockScrollWhileSnapping } = this.props;
|
|
279
|
+
return scrollEnabled && !enableMomentum && lockScrollWhileSnapping;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
_enableLoop() {
|
|
283
|
+
const { data, enableSnap, loop } = this.props;
|
|
284
|
+
return enableSnap && loop && data && data.length && data.length > 1;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
_shouldAnimateSlides(props = this.props) {
|
|
288
|
+
const {
|
|
289
|
+
inactiveSlideOpacity, inactiveSlideScale, scrollInterpolator, slideInterpolatedStyle
|
|
290
|
+
} = props;
|
|
291
|
+
return inactiveSlideOpacity < 1
|
|
292
|
+
|| inactiveSlideScale < 1
|
|
293
|
+
|| !!scrollInterpolator
|
|
294
|
+
|| !!slideInterpolatedStyle
|
|
295
|
+
|| this._shouldUseShiftLayout()
|
|
296
|
+
|| this._shouldUseStackLayout()
|
|
297
|
+
|| this._shouldUseTinderLayout();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
_shouldUseCustomAnimation() {
|
|
301
|
+
const { activeAnimationOptions } = this.props;
|
|
302
|
+
return !!activeAnimationOptions && !this._shouldUseStackLayout() && !this._shouldUseTinderLayout();
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
_shouldUseShiftLayout() {
|
|
306
|
+
const { inactiveSlideShift, layout } = this.props;
|
|
307
|
+
return layout === 'default' && inactiveSlideShift !== 0;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
_shouldUseStackLayout() {
|
|
311
|
+
const { layout } = this.props;
|
|
312
|
+
return layout === 'stack';
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
_shouldUseTinderLayout() {
|
|
316
|
+
const { layout } = this.props;
|
|
317
|
+
return layout === 'tinder';
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
_getCustomData(props = this.props) {
|
|
321
|
+
const { data, loopClonesPerSide } = props;
|
|
322
|
+
const dataLength = data && data.length;
|
|
323
|
+
|
|
324
|
+
if (!dataLength) {
|
|
325
|
+
return [];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (!this._enableLoop()) {
|
|
329
|
+
return data;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
let previousItems = [];
|
|
333
|
+
let nextItems = [];
|
|
334
|
+
|
|
335
|
+
if (loopClonesPerSide > dataLength) {
|
|
336
|
+
const dataMultiplier = Math.floor(loopClonesPerSide / dataLength);
|
|
337
|
+
const remainder = loopClonesPerSide % dataLength;
|
|
338
|
+
|
|
339
|
+
for (let i = 0; i < dataMultiplier; i += 1) {
|
|
340
|
+
previousItems.push(...data);
|
|
341
|
+
nextItems.push(...data);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
previousItems.unshift(...data.slice(-remainder));
|
|
345
|
+
nextItems.push(...data.slice(0, remainder));
|
|
346
|
+
} else {
|
|
347
|
+
previousItems = data.slice(-loopClonesPerSide);
|
|
348
|
+
nextItems = data.slice(0, loopClonesPerSide);
|
|
349
|
+
}
|
|
350
|
+
return previousItems.concat(data, nextItems);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
_getCustomDataLength(props = this.props) {
|
|
354
|
+
const { data, loopClonesPerSide } = props;
|
|
355
|
+
const dataLength = data && data.length;
|
|
356
|
+
|
|
357
|
+
if (!dataLength) {
|
|
358
|
+
return 0;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return this._enableLoop() ? dataLength + (2 * loopClonesPerSide) : dataLength;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
_getCustomIndex(index, props = this.props) {
|
|
365
|
+
const itemsLength = this._getCustomDataLength(props);
|
|
366
|
+
|
|
367
|
+
if (!itemsLength || (!index && index !== 0)) {
|
|
368
|
+
return 0;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return this._needsRTLAdaptations() ? itemsLength - index - 1 : index;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
_getDataIndex(index) {
|
|
375
|
+
const { data, loopClonesPerSide } = this.props;
|
|
376
|
+
const dataLength = data && data.length;
|
|
377
|
+
|
|
378
|
+
if (!this._enableLoop() || !dataLength) {
|
|
379
|
+
return index;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (index >= dataLength + loopClonesPerSide) {
|
|
383
|
+
return loopClonesPerSide > dataLength
|
|
384
|
+
? (index - loopClonesPerSide) % dataLength
|
|
385
|
+
: index - dataLength - loopClonesPerSide;
|
|
386
|
+
} if (index < loopClonesPerSide) {
|
|
387
|
+
// TODO: is there a simpler way of determining the interpolated index?
|
|
388
|
+
if (loopClonesPerSide > dataLength) {
|
|
389
|
+
const baseDataIndexes = [];
|
|
390
|
+
const dataIndexes = [];
|
|
391
|
+
const dataMultiplier = Math.floor(loopClonesPerSide / dataLength);
|
|
392
|
+
const remainder = loopClonesPerSide % dataLength;
|
|
393
|
+
|
|
394
|
+
for (let i = 0; i < dataLength; i += 1) {
|
|
395
|
+
baseDataIndexes.push(i);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
for (let j = 0; j < dataMultiplier; j += 1) {
|
|
399
|
+
dataIndexes.push(...baseDataIndexes);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
dataIndexes.unshift(...baseDataIndexes.slice(-remainder));
|
|
403
|
+
return dataIndexes[index];
|
|
404
|
+
}
|
|
405
|
+
return index + dataLength - loopClonesPerSide;
|
|
406
|
+
}
|
|
407
|
+
return index - loopClonesPerSide;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Used with `snapToItem()` and 'PaginationDot'
|
|
411
|
+
_getPositionIndex(index) {
|
|
412
|
+
const { loop, loopClonesPerSide } = this.props;
|
|
413
|
+
return loop ? index + loopClonesPerSide : index;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
_getFirstItem(index, props = this.props) {
|
|
417
|
+
const { loopClonesPerSide } = props;
|
|
418
|
+
const itemsLength = this._getCustomDataLength(props);
|
|
419
|
+
|
|
420
|
+
if (!itemsLength || index > itemsLength - 1 || index < 0) {
|
|
421
|
+
return 0;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
return this._enableLoop() ? index + loopClonesPerSide : index;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
_getWrappedRef() {
|
|
428
|
+
if (this._carouselRef && (
|
|
429
|
+
(this._needsScrollView() && this._carouselRef.scrollTo)
|
|
430
|
+
|| (!this._needsScrollView() && this._carouselRef.scrollToOffset)
|
|
431
|
+
)) {
|
|
432
|
+
return this._carouselRef;
|
|
433
|
+
}
|
|
434
|
+
// https://github.com/facebook/react-native/issues/10635
|
|
435
|
+
// https://stackoverflow.com/a/48786374/8412141
|
|
436
|
+
return this._carouselRef && this._carouselRef.getNode && this._carouselRef.getNode();
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
_getScrollEnabled() {
|
|
440
|
+
return this._scrollEnabled;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
_setScrollEnabled(scrollEnabled = true) {
|
|
444
|
+
const wrappedRef = this._getWrappedRef();
|
|
445
|
+
|
|
446
|
+
if (!wrappedRef || !wrappedRef.setNativeProps) {
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// 'setNativeProps()' is used instead of 'setState()' because the latter
|
|
451
|
+
// really takes a toll on Android behavior when momentum is disabled
|
|
452
|
+
wrappedRef.setNativeProps({ scrollEnabled });
|
|
453
|
+
this._scrollEnabled = scrollEnabled;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
_getKeyExtractor(item, index) {
|
|
457
|
+
return this._needsScrollView() ? `scrollview-item-${index}` : `flatlist-item-${index}`;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
_getScrollOffset(event) {
|
|
461
|
+
const { vertical } = this.props;
|
|
462
|
+
return (event && event.nativeEvent && event.nativeEvent.contentOffset
|
|
463
|
+
&& event.nativeEvent.contentOffset[vertical ? 'y' : 'x']) || 0;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
_getContainerInnerMargin(opposite = false) {
|
|
467
|
+
const {
|
|
468
|
+
sliderWidth, sliderHeight, itemWidth, itemHeight, vertical, activeSlideAlignment
|
|
469
|
+
} = this.props;
|
|
470
|
+
|
|
471
|
+
if ((activeSlideAlignment === 'start' && !opposite)
|
|
472
|
+
|| (activeSlideAlignment === 'end' && opposite)) {
|
|
473
|
+
return 0;
|
|
474
|
+
} if ((activeSlideAlignment === 'end' && !opposite)
|
|
475
|
+
|| (activeSlideAlignment === 'start' && opposite)) {
|
|
476
|
+
return vertical ? sliderHeight - itemHeight : sliderWidth - itemWidth;
|
|
477
|
+
}
|
|
478
|
+
return vertical ? (sliderHeight - itemHeight) / 2 : (sliderWidth - itemWidth) / 2;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
_getViewportOffset() {
|
|
482
|
+
const {
|
|
483
|
+
sliderWidth, sliderHeight, itemWidth, itemHeight, vertical, activeSlideAlignment
|
|
484
|
+
} = this.props;
|
|
485
|
+
|
|
486
|
+
if (activeSlideAlignment === 'start') {
|
|
487
|
+
return vertical ? itemHeight / 2 : itemWidth / 2;
|
|
488
|
+
} if (activeSlideAlignment === 'end') {
|
|
489
|
+
return vertical
|
|
490
|
+
? sliderHeight - (itemHeight / 2)
|
|
491
|
+
: sliderWidth - (itemWidth / 2);
|
|
492
|
+
}
|
|
493
|
+
return vertical ? sliderHeight / 2 : sliderWidth / 2;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
_getCenter(offset) {
|
|
497
|
+
return offset + this._getViewportOffset() - this._getContainerInnerMargin();
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
_getActiveItem(offset) {
|
|
501
|
+
const { activeSlideOffset, swipeThreshold } = this.props;
|
|
502
|
+
const center = this._getCenter(offset);
|
|
503
|
+
const centerOffset = activeSlideOffset || swipeThreshold;
|
|
504
|
+
|
|
505
|
+
for (let i = 0; i < this._positions.length; i += 1) {
|
|
506
|
+
const { start, end } = this._positions[i];
|
|
507
|
+
if (center + centerOffset >= start && center - centerOffset <= end) {
|
|
508
|
+
return i;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const lastIndex = this._positions.length - 1;
|
|
513
|
+
if (this._positions[lastIndex] && center - centerOffset > this._positions[lastIndex].end) {
|
|
514
|
+
return lastIndex;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
return 0;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
_initPositionsAndInterpolators(props = this.props) {
|
|
521
|
+
const {
|
|
522
|
+
data, itemWidth, itemHeight, scrollInterpolator, vertical
|
|
523
|
+
} = props;
|
|
524
|
+
const sizeRef = vertical ? itemHeight : itemWidth;
|
|
525
|
+
|
|
526
|
+
if (!data || !data.length) {
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
const interpolators = [];
|
|
531
|
+
this._positions = [];
|
|
532
|
+
|
|
533
|
+
this._getCustomData(props).forEach((itemData, index) => {
|
|
534
|
+
const _index = this._getCustomIndex(index, props);
|
|
535
|
+
let animatedValue;
|
|
536
|
+
|
|
537
|
+
this._positions[index] = {
|
|
538
|
+
start: index * sizeRef,
|
|
539
|
+
end: index * sizeRef + sizeRef
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
if (!this._shouldAnimateSlides(props)) {
|
|
543
|
+
animatedValue = new Animated.Value(1);
|
|
544
|
+
} else if (this._shouldUseCustomAnimation()) {
|
|
545
|
+
animatedValue = new Animated.Value(_index === this._activeItem ? 1 : 0);
|
|
546
|
+
} else {
|
|
547
|
+
let interpolator;
|
|
548
|
+
|
|
549
|
+
if (scrollInterpolator) {
|
|
550
|
+
interpolator = scrollInterpolator(_index, props);
|
|
551
|
+
} else if (this._shouldUseStackLayout()) {
|
|
552
|
+
interpolator = stackScrollInterpolator(_index, props);
|
|
553
|
+
} else if (this._shouldUseTinderLayout()) {
|
|
554
|
+
interpolator = tinderScrollInterpolator(_index, props);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
if (!interpolator || !interpolator?.inputRange || !interpolator?.outputRange) {
|
|
558
|
+
interpolator = defaultScrollInterpolator(_index, props);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
animatedValue = this._scrollPos.interpolate({
|
|
562
|
+
...interpolator,
|
|
563
|
+
extrapolate: 'clamp'
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
interpolators.push(animatedValue);
|
|
568
|
+
});
|
|
569
|
+
this.setState({ interpolators });
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
_getSlideAnimation(index, toValue) {
|
|
573
|
+
const { interpolators } = this.state;
|
|
574
|
+
const { activeAnimationType, activeAnimationOptions } = this.props;
|
|
575
|
+
|
|
576
|
+
const animatedValue = interpolators && interpolators[index];
|
|
577
|
+
|
|
578
|
+
if (!animatedValue && animatedValue !== 0) {
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
const animationCommonOptions = {
|
|
583
|
+
isInteraction: false,
|
|
584
|
+
useNativeDriver: true,
|
|
585
|
+
...activeAnimationOptions,
|
|
586
|
+
toValue
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
return Animated.parallel([
|
|
590
|
+
Animated.timing(
|
|
591
|
+
animatedValue,
|
|
592
|
+
{ ...animationCommonOptions, easing: Easing.linear }
|
|
593
|
+
),
|
|
594
|
+
Animated[activeAnimationType](
|
|
595
|
+
animatedValue,
|
|
596
|
+
{ ...animationCommonOptions }
|
|
597
|
+
)
|
|
598
|
+
]);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
_playCustomSlideAnimation(current, next) {
|
|
602
|
+
const { interpolators } = this.state;
|
|
603
|
+
const itemsLength = this._getCustomDataLength();
|
|
604
|
+
const _currentIndex = this._getCustomIndex(current);
|
|
605
|
+
const _currentDataIndex = this._getDataIndex(_currentIndex);
|
|
606
|
+
const _nextIndex = this._getCustomIndex(next);
|
|
607
|
+
const _nextDataIndex = this._getDataIndex(_nextIndex);
|
|
608
|
+
const animations = [];
|
|
609
|
+
|
|
610
|
+
// Keep animations in sync when looping
|
|
611
|
+
if (this._enableLoop()) {
|
|
612
|
+
for (let i = 0; i < itemsLength; i += 1) {
|
|
613
|
+
if (this._getDataIndex(i) === _currentDataIndex && interpolators[i]) {
|
|
614
|
+
animations.push(this._getSlideAnimation(i, 0));
|
|
615
|
+
} else if (this._getDataIndex(i) === _nextDataIndex && interpolators[i]) {
|
|
616
|
+
animations.push(this._getSlideAnimation(i, 1));
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
} else {
|
|
620
|
+
if (interpolators[current]) {
|
|
621
|
+
animations.push(this._getSlideAnimation(current, 0));
|
|
622
|
+
}
|
|
623
|
+
if (interpolators[next]) {
|
|
624
|
+
animations.push(this._getSlideAnimation(next, 1));
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
Animated.parallel(animations, { stopTogether: false }).start();
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
_hackActiveSlideAnimation(index, goTo, force = false) {
|
|
632
|
+
const { data } = this.props;
|
|
633
|
+
|
|
634
|
+
if (!this._mounted || !this._carouselRef || !this._positions[index] || (!force && this._enableLoop())) {
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
const offset = this._positions[index] && this._positions[index].start;
|
|
639
|
+
|
|
640
|
+
if (!offset && offset !== 0) {
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
const itemsLength = data && data.length;
|
|
645
|
+
const direction = goTo || itemsLength === 1 ? 'start' : 'end';
|
|
646
|
+
|
|
647
|
+
this._scrollTo(offset + (direction === 'start' ? -1 : 1), false);
|
|
648
|
+
|
|
649
|
+
clearTimeout(this._hackSlideAnimationTimeout);
|
|
650
|
+
this._hackSlideAnimationTimeout = setTimeout(() => {
|
|
651
|
+
this._scrollTo(offset, false);
|
|
652
|
+
}, 50); // works randomly when set to '0'
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
_lockScroll() {
|
|
656
|
+
const { lockScrollTimeoutDuration } = this.props;
|
|
657
|
+
clearTimeout(this._lockScrollTimeout);
|
|
658
|
+
this._lockScrollTimeout = setTimeout(() => {
|
|
659
|
+
this._releaseScroll();
|
|
660
|
+
}, lockScrollTimeoutDuration);
|
|
661
|
+
this._setScrollEnabled(false);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
_releaseScroll() {
|
|
665
|
+
clearTimeout(this._lockScrollTimeout);
|
|
666
|
+
this._setScrollEnabled(true);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
_repositionScroll(index) {
|
|
670
|
+
const { data, loopClonesPerSide } = this.props;
|
|
671
|
+
const dataLength = data && data.length;
|
|
672
|
+
|
|
673
|
+
if (!this._enableLoop() || !dataLength
|
|
674
|
+
|| (index >= loopClonesPerSide && index < dataLength + loopClonesPerSide)) {
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
let repositionTo = index;
|
|
679
|
+
|
|
680
|
+
if (index >= dataLength + loopClonesPerSide) {
|
|
681
|
+
repositionTo = index - dataLength;
|
|
682
|
+
} else if (index < loopClonesPerSide) {
|
|
683
|
+
repositionTo = index + dataLength;
|
|
684
|
+
}
|
|
685
|
+
this._snapToItem(repositionTo, false, false, false, false);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
_scrollTo(offset, animated = true) {
|
|
689
|
+
const { vertical } = this.props;
|
|
690
|
+
const wrappedRef = this._getWrappedRef();
|
|
691
|
+
|
|
692
|
+
if (!this._mounted || !wrappedRef) {
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const specificOptions = this._needsScrollView() ? {
|
|
697
|
+
x: vertical ? 0 : offset,
|
|
698
|
+
y: vertical ? offset : 0
|
|
699
|
+
} : {
|
|
700
|
+
offset
|
|
701
|
+
};
|
|
702
|
+
const options = {
|
|
703
|
+
...specificOptions,
|
|
704
|
+
animated
|
|
705
|
+
};
|
|
706
|
+
|
|
707
|
+
setTimeout(() => {
|
|
708
|
+
if (this._needsScrollView()) {
|
|
709
|
+
wrappedRef.scrollTo(options);
|
|
710
|
+
} else {
|
|
711
|
+
wrappedRef.scrollToOffset(options);
|
|
712
|
+
}
|
|
713
|
+
}, (!animated && this._animated) ? 200 : 0);
|
|
714
|
+
|
|
715
|
+
this._animated = animated;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
_onScroll(event) {
|
|
719
|
+
const { callbackOffsetMargin, enableMomentum, onScroll } = this.props;
|
|
720
|
+
|
|
721
|
+
const scrollOffset = event ? this._getScrollOffset(event) : this._currentContentOffset;
|
|
722
|
+
const nextActiveItem = this._getActiveItem(scrollOffset);
|
|
723
|
+
const itemReached = nextActiveItem === this._itemToSnapTo;
|
|
724
|
+
const scrollConditions = scrollOffset >= this._scrollOffsetRef - callbackOffsetMargin
|
|
725
|
+
&& scrollOffset <= this._scrollOffsetRef + callbackOffsetMargin;
|
|
726
|
+
|
|
727
|
+
this._currentContentOffset = scrollOffset;
|
|
728
|
+
this._onScrollTriggered = true;
|
|
729
|
+
this._lastScrollDate = Date.now();
|
|
730
|
+
|
|
731
|
+
if (this._activeItem !== nextActiveItem && this._shouldUseCustomAnimation()) {
|
|
732
|
+
this._playCustomSlideAnimation(this._activeItem, nextActiveItem);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
if (enableMomentum) {
|
|
736
|
+
clearTimeout(this._snapNoMomentumTimeout);
|
|
737
|
+
|
|
738
|
+
if (this._activeItem !== nextActiveItem) {
|
|
739
|
+
this._activeItem = nextActiveItem;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
if (itemReached) {
|
|
743
|
+
if (this._canFireBeforeCallback) {
|
|
744
|
+
this._onBeforeSnap(this._getDataIndex(nextActiveItem));
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
if (scrollConditions && this._canFireCallback) {
|
|
748
|
+
this._onSnap(this._getDataIndex(nextActiveItem));
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
} else if (this._activeItem !== nextActiveItem && itemReached) {
|
|
752
|
+
if (this._canFireBeforeCallback) {
|
|
753
|
+
this._onBeforeSnap(this._getDataIndex(nextActiveItem));
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
if (scrollConditions) {
|
|
757
|
+
this._activeItem = nextActiveItem;
|
|
758
|
+
|
|
759
|
+
if (this._canLockScroll()) {
|
|
760
|
+
this._releaseScroll();
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
if (this._canFireCallback) {
|
|
764
|
+
this._onSnap(this._getDataIndex(nextActiveItem));
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
if (nextActiveItem === this._itemToSnapTo
|
|
769
|
+
&& scrollOffset === this._scrollOffsetRef) {
|
|
770
|
+
this._repositionScroll(nextActiveItem);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
if (typeof onScroll === 'function' && event) {
|
|
774
|
+
onScroll(event);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
_onStartShouldSetResponderCapture(event) {
|
|
779
|
+
const { onStartShouldSetResponderCapture } = this.props;
|
|
780
|
+
|
|
781
|
+
if (onStartShouldSetResponderCapture) {
|
|
782
|
+
onStartShouldSetResponderCapture(event);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
return this._getScrollEnabled();
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
_onTouchStart() {
|
|
789
|
+
const { onTouchStart } = this.props;
|
|
790
|
+
|
|
791
|
+
// `onTouchStart` is fired even when `scrollEnabled` is set to `false`
|
|
792
|
+
if (this._getScrollEnabled() !== false && this._autoplaying) {
|
|
793
|
+
this.stopAutoplay();
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
if (onTouchStart) {
|
|
797
|
+
onTouchStart();
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
_onTouchEnd() {
|
|
802
|
+
const { onTouchEnd, autoplay } = this.props;
|
|
803
|
+
|
|
804
|
+
if (this._getScrollEnabled() !== false && autoplay && !this._autoplaying) {
|
|
805
|
+
// This event is buggy on Android, so a fallback is provided in _onScrollEnd()
|
|
806
|
+
this.startAutoplay();
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
if (onTouchEnd) {
|
|
810
|
+
onTouchEnd();
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// Used when `enableSnap` is ENABLED
|
|
815
|
+
_onScrollBeginDrag(event) {
|
|
816
|
+
const { onScrollBeginDrag } = this.props;
|
|
817
|
+
|
|
818
|
+
if (!this._getScrollEnabled()) {
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
this._scrollStartOffset = this._getScrollOffset(event);
|
|
823
|
+
this._scrollStartActive = this._getActiveItem(this._scrollStartOffset);
|
|
824
|
+
this._ignoreNextMomentum = false;
|
|
825
|
+
// this._canFireCallback = false;
|
|
826
|
+
|
|
827
|
+
if (onScrollBeginDrag) {
|
|
828
|
+
onScrollBeginDrag(event);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// Used when `enableMomentum` is DISABLED
|
|
833
|
+
_onScrollEndDrag(event) {
|
|
834
|
+
const { onScrollEndDrag } = this.props;
|
|
835
|
+
|
|
836
|
+
if (this._carouselRef) {
|
|
837
|
+
if (this._onScrollEnd) this._onScrollEnd();
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
if (onScrollEndDrag) {
|
|
841
|
+
onScrollEndDrag(event);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// Used when `enableMomentum` is ENABLED
|
|
846
|
+
_onMomentumScrollEnd(event) {
|
|
847
|
+
const { onMomentumScrollEnd } = this.props;
|
|
848
|
+
|
|
849
|
+
if (this._carouselRef) {
|
|
850
|
+
if (this._onScrollEnd) this._onScrollEnd();
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
if (onMomentumScrollEnd) {
|
|
854
|
+
onMomentumScrollEnd(event);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
_onScrollEnd() {
|
|
859
|
+
const { autoplay, autoplayDelay, enableSnap } = this.props;
|
|
860
|
+
|
|
861
|
+
if (this._ignoreNextMomentum) {
|
|
862
|
+
// iOS fix
|
|
863
|
+
this._ignoreNextMomentum = false;
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
this._scrollEndOffset = this._currentContentOffset;
|
|
868
|
+
this._scrollEndActive = this._getActiveItem(this._scrollEndOffset);
|
|
869
|
+
|
|
870
|
+
if (enableSnap) {
|
|
871
|
+
this._snapScroll(this._scrollEndOffset - this._scrollStartOffset);
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// The touchEnd event is buggy on Android, so this will serve as a fallback whenever needed
|
|
875
|
+
// https://github.com/facebook/react-native/issues/9439
|
|
876
|
+
if (autoplay && !this._autoplaying) {
|
|
877
|
+
clearTimeout(this._enableAutoplayTimeout);
|
|
878
|
+
this._enableAutoplayTimeout = setTimeout(() => {
|
|
879
|
+
this.startAutoplay();
|
|
880
|
+
}, autoplayDelay + 50);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// Due to a bug, this event is only fired on iOS
|
|
885
|
+
// https://github.com/facebook/react-native/issues/6791
|
|
886
|
+
// it's fine since we're only fixing an iOS bug in it, so ...
|
|
887
|
+
_onTouchRelease() {
|
|
888
|
+
const { enableMomentum } = this.props;
|
|
889
|
+
|
|
890
|
+
if (enableMomentum && IS_IOS) {
|
|
891
|
+
clearTimeout(this._snapNoMomentumTimeout);
|
|
892
|
+
this._snapNoMomentumTimeout = setTimeout(() => {
|
|
893
|
+
this._snapToItem(this._activeItem);
|
|
894
|
+
}, 100);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
_onLayout(event) {
|
|
899
|
+
const { onLayout } = this.props;
|
|
900
|
+
|
|
901
|
+
// Prevent unneeded actions during the first 'onLayout' (triggered on init)
|
|
902
|
+
if (this._onLayoutInitDone) {
|
|
903
|
+
this._initPositionsAndInterpolators();
|
|
904
|
+
this._snapToItem(this._activeItem, false, false, false, false);
|
|
905
|
+
} else {
|
|
906
|
+
this._onLayoutInitDone = true;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
if (onLayout) {
|
|
910
|
+
onLayout(event);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
_snapScroll(delta) {
|
|
915
|
+
const { swipeThreshold } = this.props;
|
|
916
|
+
|
|
917
|
+
// When using momentum and releasing the touch with
|
|
918
|
+
// no velocity, scrollEndActive will be undefined (iOS)
|
|
919
|
+
if (!this._scrollEndActive && this._scrollEndActive !== 0 && IS_IOS) {
|
|
920
|
+
this._scrollEndActive = this._scrollStartActive;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
if (this._scrollStartActive !== this._scrollEndActive) {
|
|
924
|
+
// Snap to the new active item
|
|
925
|
+
this._snapToItem(this._scrollEndActive);
|
|
926
|
+
} else {
|
|
927
|
+
// Snap depending on delta
|
|
928
|
+
if (delta > 0) {
|
|
929
|
+
if (delta > swipeThreshold) {
|
|
930
|
+
this._snapToItem(this._scrollStartActive + 1);
|
|
931
|
+
} else {
|
|
932
|
+
this._snapToItem(this._scrollEndActive);
|
|
933
|
+
}
|
|
934
|
+
} else if (delta < 0) {
|
|
935
|
+
if (delta < -swipeThreshold) {
|
|
936
|
+
this._snapToItem(this._scrollStartActive - 1);
|
|
937
|
+
} else {
|
|
938
|
+
this._snapToItem(this._scrollEndActive);
|
|
939
|
+
}
|
|
940
|
+
} else {
|
|
941
|
+
// Snap to current
|
|
942
|
+
this._snapToItem(this._scrollEndActive);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
_snapToItem(index, animated = true, fireCallback = true, initial = false, lockScroll = true) {
|
|
948
|
+
const { enableMomentum, onSnapToItem, onBeforeSnapToItem } = this.props;
|
|
949
|
+
const itemsLength = this._getCustomDataLength();
|
|
950
|
+
const wrappedRef = this._getWrappedRef();
|
|
951
|
+
|
|
952
|
+
if (!itemsLength || !wrappedRef) {
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
if (!index || index < 0) {
|
|
957
|
+
index = 0;
|
|
958
|
+
} else if (itemsLength > 0 && index >= itemsLength) {
|
|
959
|
+
index = itemsLength - 1;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
if (index !== this._previousActiveItem) {
|
|
963
|
+
this._previousActiveItem = index;
|
|
964
|
+
|
|
965
|
+
// Placed here to allow overscrolling for edges items
|
|
966
|
+
if (lockScroll && this._canLockScroll()) {
|
|
967
|
+
this._lockScroll();
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
if (fireCallback) {
|
|
971
|
+
if (onBeforeSnapToItem) {
|
|
972
|
+
this._canFireBeforeCallback = true;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
if (onSnapToItem) {
|
|
976
|
+
this._canFireCallback = true;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
this._itemToSnapTo = index;
|
|
982
|
+
this._scrollOffsetRef = this._positions[index] && this._positions[index].start;
|
|
983
|
+
this._onScrollTriggered = false;
|
|
984
|
+
|
|
985
|
+
if (!this._scrollOffsetRef && this._scrollOffsetRef !== 0) {
|
|
986
|
+
return;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
this._scrollTo(this._scrollOffsetRef, animated);
|
|
990
|
+
|
|
991
|
+
if (enableMomentum) {
|
|
992
|
+
// iOS fix, check the note in the constructor
|
|
993
|
+
if (IS_IOS && !initial) {
|
|
994
|
+
this._ignoreNextMomentum = true;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
// When momentum is enabled and the user is overscrolling or swiping very quickly,
|
|
998
|
+
// 'onScroll' is not going to be triggered for edge items. Then callback won't be
|
|
999
|
+
// fired and loop won't work since the scrollview is not going to be repositioned.
|
|
1000
|
+
// As a workaround, '_onScroll()' will be called manually for these items if a given
|
|
1001
|
+
// condition hasn't been met after a small delay.
|
|
1002
|
+
// WARNING: this is ok only when relying on 'momentumScrollEnd', not with 'scrollEndDrag'
|
|
1003
|
+
if (index === 0 || index === itemsLength - 1) {
|
|
1004
|
+
clearTimeout(this._edgeItemTimeout);
|
|
1005
|
+
this._edgeItemTimeout = setTimeout(() => {
|
|
1006
|
+
if (!initial && index === this._activeItem && !this._onScrollTriggered) {
|
|
1007
|
+
this._onScroll();
|
|
1008
|
+
}
|
|
1009
|
+
}, 250);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
_onBeforeSnap(index) {
|
|
1015
|
+
const { onBeforeSnapToItem } = this.props;
|
|
1016
|
+
|
|
1017
|
+
if (!this._carouselRef) {
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
this._canFireBeforeCallback = false;
|
|
1022
|
+
if (onBeforeSnapToItem) onBeforeSnapToItem(index);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
_onSnap(index) {
|
|
1026
|
+
const { onSnapToItem } = this.props;
|
|
1027
|
+
|
|
1028
|
+
if (!this._carouselRef) {
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
this._canFireCallback = false;
|
|
1033
|
+
if (onSnapToItem) onSnapToItem(index);
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
startAutoplay() {
|
|
1037
|
+
const { autoplayInterval, autoplayDelay } = this.props;
|
|
1038
|
+
|
|
1039
|
+
if (this._autoplaying) {
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
clearTimeout(this._autoplayTimeout);
|
|
1044
|
+
this._autoplayTimeout = setTimeout(() => {
|
|
1045
|
+
this._autoplaying = true;
|
|
1046
|
+
this._autoplayInterval = setInterval(() => {
|
|
1047
|
+
if (this._autoplaying) {
|
|
1048
|
+
this.snapToNext();
|
|
1049
|
+
}
|
|
1050
|
+
}, autoplayInterval);
|
|
1051
|
+
}, autoplayDelay);
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
stopAutoplay() {
|
|
1055
|
+
this._autoplaying = false;
|
|
1056
|
+
clearInterval(this._autoplayInterval);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
snapToItem(index, animated = true, fireCallback = true) {
|
|
1060
|
+
if (!index || index < 0) {
|
|
1061
|
+
index = 0;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
const positionIndex = this._getPositionIndex(index);
|
|
1065
|
+
|
|
1066
|
+
if (positionIndex === this._activeItem) {
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
this._snapToItem(positionIndex, animated, fireCallback);
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
snapToNext(animated = true, fireCallback = true) {
|
|
1074
|
+
const itemsLength = this._getCustomDataLength();
|
|
1075
|
+
|
|
1076
|
+
let newIndex = this._activeItem + 1;
|
|
1077
|
+
if (newIndex > itemsLength - 1) {
|
|
1078
|
+
if (!this._enableLoop()) {
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
newIndex = 0;
|
|
1082
|
+
}
|
|
1083
|
+
this._snapToItem(newIndex, animated, fireCallback);
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
snapToPrev(animated = true, fireCallback = true) {
|
|
1087
|
+
const itemsLength = this._getCustomDataLength();
|
|
1088
|
+
|
|
1089
|
+
let newIndex = this._activeItem - 1;
|
|
1090
|
+
if (newIndex < 0) {
|
|
1091
|
+
if (!this._enableLoop()) {
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
newIndex = itemsLength - 1;
|
|
1095
|
+
}
|
|
1096
|
+
this._snapToItem(newIndex, animated, fireCallback);
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
// https://github.com/facebook/react-native/issues/1831#issuecomment-231069668
|
|
1100
|
+
triggerRenderingHack(offset) {
|
|
1101
|
+
// Avoid messing with user scroll
|
|
1102
|
+
if (Date.now() - this._lastScrollDate < 500) {
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
const scrollPosition = this._currentContentOffset;
|
|
1107
|
+
if (!scrollPosition && scrollPosition !== 0) {
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
const scrollOffset = offset || (scrollPosition === 0 ? 1 : -1);
|
|
1112
|
+
this._scrollTo(scrollPosition + scrollOffset, false);
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
_getSlideInterpolatedStyle(index, animatedValue) {
|
|
1116
|
+
const { layoutCardOffset, slideInterpolatedStyle } = this.props;
|
|
1117
|
+
|
|
1118
|
+
if (slideInterpolatedStyle) {
|
|
1119
|
+
return slideInterpolatedStyle(index, animatedValue, this.props);
|
|
1120
|
+
} if (this._shouldUseTinderLayout()) {
|
|
1121
|
+
return tinderAnimatedStyles(index, animatedValue, this.props, layoutCardOffset);
|
|
1122
|
+
} if (this._shouldUseStackLayout()) {
|
|
1123
|
+
return stackAnimatedStyles(index, animatedValue, this.props, layoutCardOffset);
|
|
1124
|
+
} if (this._shouldUseShiftLayout()) {
|
|
1125
|
+
return shiftAnimatedStyles(index, animatedValue, this.props);
|
|
1126
|
+
}
|
|
1127
|
+
return defaultAnimatedStyles(index, animatedValue, this.props);
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
_renderItem({ item, index }) {
|
|
1131
|
+
const { interpolators } = this.state;
|
|
1132
|
+
const {
|
|
1133
|
+
hasParallaxImages,
|
|
1134
|
+
itemWidth,
|
|
1135
|
+
itemHeight,
|
|
1136
|
+
keyExtractor,
|
|
1137
|
+
renderItem,
|
|
1138
|
+
sliderHeight,
|
|
1139
|
+
sliderWidth,
|
|
1140
|
+
slideStyle,
|
|
1141
|
+
vertical,
|
|
1142
|
+
isCustomScrollWidth
|
|
1143
|
+
} = this.props;
|
|
1144
|
+
|
|
1145
|
+
const animatedValue = interpolators && interpolators[index];
|
|
1146
|
+
|
|
1147
|
+
if (!animatedValue && animatedValue !== 0) {
|
|
1148
|
+
return null;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
const animate = this._shouldAnimateSlides();
|
|
1152
|
+
const ComponentView = animate ? Animated.View : View;
|
|
1153
|
+
const animatedStyle = animate ? this._getSlideInterpolatedStyle(index, animatedValue) : {};
|
|
1154
|
+
|
|
1155
|
+
const parallaxProps = hasParallaxImages ? {
|
|
1156
|
+
scrollPosition: this._scrollPos,
|
|
1157
|
+
carouselRef: this._carouselRef,
|
|
1158
|
+
vertical,
|
|
1159
|
+
sliderWidth,
|
|
1160
|
+
sliderHeight,
|
|
1161
|
+
itemWidth,
|
|
1162
|
+
itemHeight
|
|
1163
|
+
} : undefined;
|
|
1164
|
+
|
|
1165
|
+
const specificProps = this._needsScrollView() ? {
|
|
1166
|
+
key: keyExtractor ? keyExtractor(item, index) : this._getKeyExtractor(item, index)
|
|
1167
|
+
} : {};
|
|
1168
|
+
const mainDimension = isCustomScrollWidth ? {} : { width: itemWidth };
|
|
1169
|
+
return (
|
|
1170
|
+
<ComponentView
|
|
1171
|
+
style={[mainDimension, slideStyle, animatedStyle]}
|
|
1172
|
+
pointerEvents="box-none"
|
|
1173
|
+
{...specificProps}
|
|
1174
|
+
>
|
|
1175
|
+
{renderItem({
|
|
1176
|
+
item, index, realIndex: this._getDataIndex(index), activeIndex: this._getDataIndex(this._activeItem)
|
|
1177
|
+
}, parallaxProps)}
|
|
1178
|
+
</ComponentView>
|
|
1179
|
+
);
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
_getComponentOverridableProps() {
|
|
1183
|
+
const {
|
|
1184
|
+
enableMomentum,
|
|
1185
|
+
itemWidth,
|
|
1186
|
+
itemHeight,
|
|
1187
|
+
loopClonesPerSide,
|
|
1188
|
+
sliderWidth,
|
|
1189
|
+
sliderHeight,
|
|
1190
|
+
vertical
|
|
1191
|
+
} = this.props;
|
|
1192
|
+
|
|
1193
|
+
const visibleItems = Math.ceil(vertical
|
|
1194
|
+
? sliderHeight / itemHeight
|
|
1195
|
+
: sliderWidth / itemWidth) + 1;
|
|
1196
|
+
const initialNumPerSide = this._enableLoop() ? loopClonesPerSide : 2;
|
|
1197
|
+
const initialNumToRender = visibleItems + (initialNumPerSide * 2);
|
|
1198
|
+
const maxToRenderPerBatch = 1 + (initialNumToRender * 2);
|
|
1199
|
+
const windowSize = maxToRenderPerBatch;
|
|
1200
|
+
|
|
1201
|
+
const specificProps = !this._needsScrollView() ? {
|
|
1202
|
+
initialNumToRender,
|
|
1203
|
+
maxToRenderPerBatch,
|
|
1204
|
+
windowSize
|
|
1205
|
+
// updateCellsBatchingPeriod
|
|
1206
|
+
} : {};
|
|
1207
|
+
|
|
1208
|
+
return {
|
|
1209
|
+
decelerationRate: enableMomentum ? 0.9 : 'fast',
|
|
1210
|
+
showsHorizontalScrollIndicator: false,
|
|
1211
|
+
showsVerticalScrollIndicator: false,
|
|
1212
|
+
overScrollMode: 'never',
|
|
1213
|
+
automaticallyAdjustContentInsets: false,
|
|
1214
|
+
directionalLockEnabled: true,
|
|
1215
|
+
pinchGestureEnabled: false,
|
|
1216
|
+
scrollsToTop: false,
|
|
1217
|
+
removeClippedSubviews: !this._needsScrollView(),
|
|
1218
|
+
inverted: this._needsRTLAdaptations(),
|
|
1219
|
+
// renderToHardwareTextureAndroid: true,
|
|
1220
|
+
...specificProps
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
_getComponentStaticProps() {
|
|
1225
|
+
const { hideCarousel } = this.state;
|
|
1226
|
+
const {
|
|
1227
|
+
containerCustomStyle,
|
|
1228
|
+
contentContainerCustomStyle,
|
|
1229
|
+
keyExtractor,
|
|
1230
|
+
sliderWidth,
|
|
1231
|
+
sliderHeight,
|
|
1232
|
+
style,
|
|
1233
|
+
vertical
|
|
1234
|
+
} = this.props;
|
|
1235
|
+
|
|
1236
|
+
const containerStyle = [
|
|
1237
|
+
containerCustomStyle || style || {},
|
|
1238
|
+
hideCarousel ? { opacity: 0 } : {},
|
|
1239
|
+
vertical
|
|
1240
|
+
? { height: sliderHeight, flexDirection: 'column' }
|
|
1241
|
+
// LTR hack; see https://github.com/facebook/react-native/issues/11960
|
|
1242
|
+
// and https://github.com/facebook/react-native/issues/13100#issuecomment-328986423
|
|
1243
|
+
: { width: sliderWidth, flexDirection: this._needsRTLAdaptations() ? 'row-reverse' : 'row' }
|
|
1244
|
+
];
|
|
1245
|
+
const contentContainerStyle = [
|
|
1246
|
+
vertical ? {
|
|
1247
|
+
paddingTop: this._getContainerInnerMargin(),
|
|
1248
|
+
paddingBottom: this._getContainerInnerMargin(true)
|
|
1249
|
+
} : {
|
|
1250
|
+
paddingLeft: this._getContainerInnerMargin(),
|
|
1251
|
+
paddingRight: this._getContainerInnerMargin(true)
|
|
1252
|
+
},
|
|
1253
|
+
contentContainerCustomStyle || {}
|
|
1254
|
+
];
|
|
1255
|
+
|
|
1256
|
+
const specificProps = !this._needsScrollView() ? {
|
|
1257
|
+
// extraData: this.state,
|
|
1258
|
+
renderItem: this._renderItem,
|
|
1259
|
+
numColumns: 1,
|
|
1260
|
+
getItemLayout: undefined, // see #193
|
|
1261
|
+
initialScrollIndex: undefined, // see #193
|
|
1262
|
+
keyExtractor: keyExtractor || this._getKeyExtractor
|
|
1263
|
+
} : {};
|
|
1264
|
+
return {
|
|
1265
|
+
ref: (c) => this._carouselRef = c,
|
|
1266
|
+
data: this._getCustomData(),
|
|
1267
|
+
style: containerStyle,
|
|
1268
|
+
contentContainerStyle,
|
|
1269
|
+
horizontal: !vertical,
|
|
1270
|
+
scrollEventThrottle: 1,
|
|
1271
|
+
onScroll: this._onScrollHandler,
|
|
1272
|
+
onScrollBeginDrag: this._onScrollBeginDrag,
|
|
1273
|
+
onScrollEndDrag: this._onScrollEndDrag,
|
|
1274
|
+
onMomentumScrollEnd: this._onMomentumScrollEnd,
|
|
1275
|
+
onResponderRelease: this._onTouchRelease,
|
|
1276
|
+
onStartShouldSetResponderCapture: this._onStartShouldSetResponderCapture,
|
|
1277
|
+
onTouchStart: this._onTouchStart,
|
|
1278
|
+
onTouchEnd: this._onScrollEnd,
|
|
1279
|
+
onLayout: this._onLayout,
|
|
1280
|
+
...specificProps
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
render() {
|
|
1285
|
+
const { data, renderItem, useScrollView } = this.props;
|
|
1286
|
+
|
|
1287
|
+
if (!data || !renderItem) {
|
|
1288
|
+
return null;
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
const props = {
|
|
1292
|
+
...this._getComponentOverridableProps(),
|
|
1293
|
+
...this.props,
|
|
1294
|
+
...this._getComponentStaticProps()
|
|
1295
|
+
};
|
|
1296
|
+
|
|
1297
|
+
const ScrollViewComponent = typeof useScrollView === 'function' ? useScrollView : AnimatedScrollView;
|
|
1298
|
+
|
|
1299
|
+
return this._needsScrollView() ? (
|
|
1300
|
+
<ScrollViewComponent {...props}>
|
|
1301
|
+
{
|
|
1302
|
+
this._getCustomData().map((item, index) => this._renderItem({
|
|
1303
|
+
item, index, realIndex: this._getDataIndex(index), activeIndex: this._getDataIndex(this._activeItem)
|
|
1304
|
+
}))
|
|
1305
|
+
}
|
|
1306
|
+
</ScrollViewComponent>
|
|
1307
|
+
) : (
|
|
1308
|
+
<AnimatedFlatList {...props} />
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
Carousel.propTypes = {
|
|
1314
|
+
data: PropTypes.array.isRequired,
|
|
1315
|
+
renderItem: PropTypes.func.isRequired,
|
|
1316
|
+
itemWidth: PropTypes.number, // required for horizontal carousel
|
|
1317
|
+
itemHeight: PropTypes.number, // required for vertical carousel
|
|
1318
|
+
sliderWidth: PropTypes.number, // required for horizontal carousel
|
|
1319
|
+
sliderHeight: PropTypes.number, // required for vertical carousel
|
|
1320
|
+
activeAnimationType: PropTypes.string,
|
|
1321
|
+
activeAnimationOptions: PropTypes.object,
|
|
1322
|
+
activeSlideAlignment: PropTypes.oneOf(['center', 'end', 'start']),
|
|
1323
|
+
activeSlideOffset: PropTypes.number,
|
|
1324
|
+
apparitionDelay: PropTypes.number,
|
|
1325
|
+
autoplay: PropTypes.bool,
|
|
1326
|
+
autoplayDelay: PropTypes.number,
|
|
1327
|
+
autoplayInterval: PropTypes.number,
|
|
1328
|
+
callbackOffsetMargin: PropTypes.number,
|
|
1329
|
+
containerCustomStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
|
1330
|
+
contentContainerCustomStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
|
1331
|
+
enableMomentum: PropTypes.bool,
|
|
1332
|
+
enableSnap: PropTypes.bool,
|
|
1333
|
+
firstItem: PropTypes.number,
|
|
1334
|
+
hasParallaxImages: PropTypes.bool,
|
|
1335
|
+
inactiveSlideOpacity: PropTypes.number,
|
|
1336
|
+
inactiveSlideScale: PropTypes.number,
|
|
1337
|
+
inactiveSlideShift: PropTypes.number,
|
|
1338
|
+
layout: PropTypes.oneOf(['default', 'stack', 'tinder']),
|
|
1339
|
+
layoutCardOffset: PropTypes.number,
|
|
1340
|
+
lockScrollTimeoutDuration: PropTypes.number,
|
|
1341
|
+
lockScrollWhileSnapping: PropTypes.bool,
|
|
1342
|
+
loop: PropTypes.bool,
|
|
1343
|
+
loopClonesPerSide: PropTypes.number,
|
|
1344
|
+
scrollEnabled: PropTypes.bool,
|
|
1345
|
+
scrollInterpolator: PropTypes.func,
|
|
1346
|
+
slideInterpolatedStyle: PropTypes.func,
|
|
1347
|
+
slideStyle: PropTypes.object,
|
|
1348
|
+
shouldOptimizeUpdates: PropTypes.bool,
|
|
1349
|
+
swipeThreshold: PropTypes.number,
|
|
1350
|
+
useScrollView: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
|
|
1351
|
+
vertical: PropTypes.bool,
|
|
1352
|
+
showsPagination: PropTypes.bool,
|
|
1353
|
+
isCustomScrollWidth: PropTypes.bool,
|
|
1354
|
+
onBeforeSnapToItem: PropTypes.func,
|
|
1355
|
+
onSnapToItem: PropTypes.func,
|
|
1356
|
+
};
|
|
1357
|
+
|
|
1358
|
+
Carousel.defaultProps = {
|
|
1359
|
+
activeAnimationType: 'timing',
|
|
1360
|
+
activeAnimationOptions: null,
|
|
1361
|
+
activeSlideAlignment: 'center',
|
|
1362
|
+
activeSlideOffset: 20,
|
|
1363
|
+
apparitionDelay: 0,
|
|
1364
|
+
autoplay: false,
|
|
1365
|
+
autoplayDelay: 1000,
|
|
1366
|
+
autoplayInterval: 3000,
|
|
1367
|
+
callbackOffsetMargin: 5,
|
|
1368
|
+
containerCustomStyle: {},
|
|
1369
|
+
contentContainerCustomStyle: {},
|
|
1370
|
+
enableMomentum: false,
|
|
1371
|
+
enableSnap: true,
|
|
1372
|
+
firstItem: 0,
|
|
1373
|
+
hasParallaxImages: false,
|
|
1374
|
+
inactiveSlideOpacity: 0.7,
|
|
1375
|
+
inactiveSlideScale: 0.9,
|
|
1376
|
+
inactiveSlideShift: 0,
|
|
1377
|
+
layout: 'default',
|
|
1378
|
+
lockScrollTimeoutDuration: 1000,
|
|
1379
|
+
lockScrollWhileSnapping: false,
|
|
1380
|
+
loop: false,
|
|
1381
|
+
loopClonesPerSide: 3,
|
|
1382
|
+
scrollEnabled: true,
|
|
1383
|
+
slideStyle: {},
|
|
1384
|
+
shouldOptimizeUpdates: true,
|
|
1385
|
+
swipeThreshold: 20,
|
|
1386
|
+
useScrollView: !AnimatedFlatList,
|
|
1387
|
+
vertical: false,
|
|
1388
|
+
showsPagination: true,
|
|
1389
|
+
isCustomScrollWidth: false,
|
|
1390
|
+
};
|