Skip to content

Commit 30405cb

Browse files
author
Benoît Delmaire
authored
Merge pull request #77 from archriss/evols
Evols and fixes
2 parents 1754783 + ea4f0d7 commit 30405cb

File tree

5 files changed

+421
-103
lines changed

5 files changed

+421
-103
lines changed

CHANGELOG.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1+
## v2.2.0
2+
* Implement vertical mode (prop `vertical`)
3+
* Make sure that current active item is properly updated when snapping
4+
* Prevent issues when 'sliderWidth' is smaller than viewport's width
5+
* Recalculate card positions on layout to handle rotation (thanks [@andrewpope](https://github.com/andrewpope)); make sure to read [this note] (https://github.com/archriss/react-native-snap-carousel#handling-device-rotation)
6+
* Refresh card positions if slider and/or item's dimensions are updated (thanks [@hoangnm](https://github.com/hoangnm))
7+
* Add props `scrollEndDragThrottleValue` and `snapCallbackDebounceValue`
8+
* Expose `View`'s `onLayout` prop
9+
* Deprecate prop `onScrollViewScroll`
10+
111
## v2.1.4
212
* Add prop `onScrollViewScroll`
313

414
## v2.1.3
515
* Default value for `showsHorizontalScrollIndicator` is now `false`
6-
* ~~Expose `ScrollView`'s `onSscroll` prop (thanks [@radko93](https://github.com/radko93))~~ (not working)
16+
* Expose `ScrollView`'s `onSscroll` prop (thanks [@radko93](https://github.com/radko93))
717

818
## v2.1.2
919
* Do not trigger `onSnapToItem` when snapping back to the same slide (thanks [@rgabs](https://github.com/rgabs))

README.md

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Pull requests are very welcome!
1313
1. [Example](#example)
1414
1. [Tips and tricks](#tips-and-tricks)
1515
1. [RTL support](#rtl-support)
16+
1. [ScrollView's limitations](#scrollviews-limitations)
1617
1. [TODO](#todo)
1718
1. [Credits](#credits)
1819

@@ -83,26 +84,31 @@ import Carousel from 'react-native-snap-carousel';
8384

8485
Prop | Description | Type | Default
8586
------ | ------ | ------ | ------
86-
**itemWidth** | Width in pixels of your slides, **must be the same for all of them** | Number | **Required**
87-
**sliderWidth** | Width in pixels of your slider | Number | **Required**
87+
**itemWidth** | Width in pixels of carousel's items, **must be the same for all of them** | Number | **Required with horizontal carousel**
88+
**itemHeight** | Height in pixels of carousel's items, **must be the same for all of them** | Number | **Required with vertical carousel**
89+
**sliderWidth** | Width in pixels of the carousel itself | Number | **Required with horizontal carousel**
90+
**sliderHeight** | Height in pixels of the carousel itself | Number | **Required with vertical carousel**
8891

8992
### Behavior
9093

9194
Prop | Description | Type | Default
9295
------ | ------ | ------ | ------
9396
activeSlideOffset | From slider's center, minimum slide distance to be scrolled before being set to active | Number | `25`
94-
enableMomentum | See [momentum](#momentum) | Boolean | `false`
95-
enableSnap | If enabled, releasing the touch will scroll to the center of the nearest/active item | Number | `true`
97+
enableMomentum | See [momentum](#momentum). **Warning: this prop can't be changed dynamically.** | Boolean | `false`
98+
enableSnap | If enabled, releasing the touch will scroll to the center of the nearest/active item. **Warning: this prop can't be changed dynamically.** | Number | `true`
9699
firstItem | Index of the first item to display | Number | `0`
97-
shouldOptimizeUpdates | whether to implement a `shouldComponentUpdate` strategy to minimize updates | Boolean | `true`
98-
snapOnAndroid | Snapping on android is kinda choppy, especially when swiping quickly so you can disable it | Boolean | `true`
100+
scrollEndDragThrottleValue | When momentum is disabled, this throttle helps smoothing slides' snapping by providing a bit of inertia when touch is released. **Note that this will delay callback's execution.** | Number | `50` for iOS, `150` for Android
101+
shouldOptimizeUpdates | Whether to implement a `shouldComponentUpdate` strategy to minimize updates | Boolean | `true`
102+
snapCallbackDebounceValue | This defines the timeframe during which multiple callback calls should be "grouped" into a single one. **Note that this will delay callback's execution.** | Number | `250`
103+
snapOnAndroid | Snapping on android is kinda choppy, especially when swiping quickly so you can disable it. **Warning: this prop can't be changed dynamically.** | Boolean | `true`
99104
swipeThreshold | Delta x when swiping to trigger the snap | Number | `20`
105+
vertical | Layout slides vertically instead of horizontally | Boolean | `false`
100106

101107
### Autoplay
102108

103109
Prop | Description | Type | Default
104110
------ | ------ | ------ | ------
105-
autoplay | Trigger autoplay on mount | Boolean | `false`
111+
autoplay | Trigger autoplay on mount. **Warning: this prop can't be changed dynamically.** | Boolean | `false`
106112
autoplayDelay | Delay before enabling autoplay on startup & after releasing the touch | Number | `5000`
107113
autoplayInterval | Delay in ms until navigating to the next item | Number | `3000`
108114

@@ -112,7 +118,8 @@ Prop | Description | Type | Default
112118
------ | ------ | ------ | ------
113119
animationFunc | Animated animation to use. Provide the name of the method | String | `timing`
114120
animationOptions | Animation options to be merged with the default ones. Can be used w/ animationFunc | Object | `{ easing: Easing.elastic(1) }`
115-
carouselHorizontalPadding | Override container's inner padding (needed for slides's centering). **Warning: be aware that overriding the default value can mess with carousel's behavior.** | Number | `(sliderWidth - itemWidth) / 2`
121+
carouselHorizontalPadding | Override container's inner horizontal padding (needed for slides's centering in a horizontal carousel). **Warning: be aware that overriding the default value can mess with carousel's behavior.** | Number | `(sliderWidth - itemWidth) / 2`
122+
carouselVerticalPadding | Override container's inner vertical padding (needed for slides's centering in a vertical carousel). **Warning: be aware that overriding the default value can mess with carousel's behavior.** | Number | `(sliderHeight - itemHeight) / 2`
116123
containerCustomStyle | Optional styles for Scrollview's global wrapper | ScrollView Style Object | `{}`
117124
contentContainerCustomStyle | Optional styles for Scrollview's items container | ScrollView Style Object | `{}`
118125
inactiveSlideOpacity | Value of the opacity effect applied to inactive slides | Number | `1`
@@ -123,16 +130,16 @@ slideStyle | Optional style for each item's container (the one whose scale and o
123130

124131
Prop | Description | Type | Default
125132
------ | ------ | ------ | ------
126-
onScrollViewScroll(event) | Callback fired while scrolling; direct equivalent of `ScrollView`'s `onScroll` | Function | `undefined`
133+
onLayout(event) | Exposed `View` callback; invoked on mount and layout changes | Function | `undefined`
134+
onScroll(event) | Exposed `ScrollView` callback; fired while scrolling | Function | `undefined`
135+
onScrollViewScroll(event) | Callback fired while scrolling (**deprecated**: use `onScroll` instead) | Function | `undefined`
127136
onSnapToItem(slideIndex) | Callback fired when navigating to an item | Function | `undefined`
128137

129138
### `ScrollView`
130139

131140
In addition to these props, you can use **any prop from the [ScrollView component](https://facebook.github.io/react-native/docs/scrollview.html)**.
132141

133-
Here are a few useful ones:`removeClippedSubviews`, `showsHorizontalScrollIndicator`, `overScrollMode` (android), `bounces` (ios), `decelerationRate` (ios), `scrollEventThrottle` (ios).
134-
135-
> Since `onScroll` is overriden by plugin's implementation, you should use prop `onScrollViewScroll` if you need a callback while scrolling.
142+
Here are a few useful ones: `removeClippedSubviews`, `showsHorizontalScrollIndicator`, `overScrollMode` (android), `bounces` (ios), `decelerationRate` (ios), `scrollEventThrottle` (ios).
136143

137144
## Methods
138145

@@ -188,7 +195,9 @@ You can find the following example in the [/example](https://github.com/archriss
188195
Since `1.5.0`, the snapping effect can now be based on momentum instead of when you're releasing your finger. It means that the component will wait until the `ScrollView` isn't moving anymore to snap. By default, the inertia isn't too high on Android. However, we had to tweak the default iOS value a bit to make sure the snapping isn't delayed for too long.
189196
You can adjust this value to your needs thanks to [this prop](https://facebook.github.io/react-native/docs/scrollview.html#decelerationrate).
190197

191-
> As a rule of thumb, **we recommend setting `enableMomentum` to `false` (default) and `decelerationRate` to `'fast'` when you are displaying only one main slide** (as in the showcase above), and to use `true` and `0.9` otherwise. This should help providing a better snap feeling.
198+
Make also sure to play with the props `scrollEndDragThrottleValue` and `snapCallbackDebounceValue`; they can help achieving a better snap feeling, especially when momentum is disabled.
199+
200+
> As a rule of thumb, **we recommend setting `enableMomentum` to `false` (default) and `decelerationRate` to `'fast'` when you are displaying only one main slide** (as in the showcase above), and to use `true` and `0.9` otherwise.
192201
193202
### Margin between slides
194203
If you need some **extra horizontal margin** between slides (besides the one resulting from the scale effect), you should add it as `paddingHorizontal` on slide's container. Make sure to take this into account when calculating item's width.
@@ -228,6 +237,48 @@ Here is a screenshot that should help you understand how each of the above varia
228237
229238
![react-native-snap-carousel info](http://i.imgur.com/PMi6aBd.jpg)
230239
240+
241+
### Handling device rotation
242+
243+
Since version 2.2.0, slides will re-center properly if you update slider and/or items's dimensions when `onLayout` is fired.
244+
245+
Here is an example of a working implementation (thanks [@andrewpope](https://github.com/archriss/react-native-snap-carousel/pull/76#issuecomment-306187425)):
246+
247+
```
248+
constructor(props) {
249+
super(props);
250+
this.state = {
251+
viewport: {
252+
width: Dimensions.get('window').width,
253+
height: Dimensions.get('window').height
254+
}
255+
};
256+
}
257+
258+
render() {
259+
return (
260+
<View
261+
onLayout={() => {
262+
this.setState({
263+
viewport: {
264+
width: Dimensions.get('window').width,
265+
height: Dimensions.get('window').height
266+
}
267+
});
268+
}}
269+
>
270+
<Carousel
271+
ref={carousel => { this.carousel = carousel; } }
272+
sliderWidth={this.state.viewport.width}
273+
itemWidth={this.state.viewport.width}
274+
...
275+
>
276+
</Carousel>
277+
</View>
278+
);
279+
}
280+
```
281+
231282
### Fullscreen slides
232283
233284
While the plugin hasn't been designed with this use case in mind, you can easily implement fullscreen slides. The following code should serve as a good starting point.
@@ -270,14 +321,23 @@ As such, this feature should be considered experimental since it might break wit
270321
271322
There is one kown issue with RTL layouts: during init, the last slide will shortly be seen. You can work around this by delaying slider's visibility with a small timer (FYI, version 0.43.0 of React Native [introduced a `display` style prop](https://github.com/facebook/react-native/commit/4d69f4b2d1cf4f2e8265fe5758f28086f1b67500) that could either be set to `flex` or `none`).
272323
324+
## ScrollView's limitations
325+
326+
Note that this plugin is built on top of React Native's `ScrollView`. Unfortunately, its implementation shows flaws that affect the plugin, the main ones being the following:
327+
- there is no `onScrollEnd` event
328+
- `scrollTo` method doesn't accept any callback
329+
- Android's `scrollTo` animation is quite brutal.
330+
331+
We're trying to work around these issues, but the result is not always as smooth as we'd want it to be. Keep that in mind and go spam [React Native's Feature Request](https://react-native.canny.io/feature-requests) ;-)
332+
273333
## TODO
274334
275335
- [ ] Implement 'loop' mode
276336
- [ ] Implement 'preload' mode
277-
- [ ] Add vertical implementation
278337
- [ ] Handle changing props on-the-fly
279-
- [ ] Handle device orientation event
280338
- [ ] Handle autoplay properly when updating children's length
339+
- [x] Add vertical implementation
340+
- [x] Handle device orientation event (see [this note] (https://github.com/archriss/react-native-snap-carousel#handling-device-rotation))
281341
- [x] Add RTL support
282342
- [x] Improve momemtum handling
283343
- [x] Improve snap on Android

0 commit comments

Comments
 (0)