Skip to content

Commit

Permalink
Merge pull request #147 from archriss/refactor
Browse files Browse the repository at this point in the history
Callback refactoring and miscellaneous updates
  • Loading branch information
Benoît Delmaire authored Sep 13, 2017
2 parents 6bb15c8 + a6982ef commit ac2e144
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 288 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
## v3.2.0
* Refactor callback handling. **Make sure to use the new prop `callbackOffsetMargin` if you experience missed callbacks.**
* Make item's scale and opacity animation follow scroll value (thanks [@hammadj](https://github.com/hammadj))
* `Pagination` component: make dots tappable with new props `tappableDots` and `carouselRef` (see the [example](https://github.com/archriss/react-native-snap-carousel/blob/master/example/src/index.js))
* Fix state and scroll issues when the currently active item is being dynamically removed
* Improve snap feeling when momentum is disabled (default)
* Add prop `callbackOffsetMargin`
* Remove props `animationFunc`, `animationOptions`, `scrollEndDragDebounceValue`, `snapOnAndroid`, and `useNativeOnScroll`

## v3.1.0
* `Pagination` component: add new props for advanced customization

## v3.0.0
###WARNING
### WARNING
* **Do not use this version as some temporary code was pushed to `npm` by mistake. Make sure to use version `3.1.0` instead.**
### Breaking changes
* Plugin is now built on top of `FlatList`, which allows for huge performance optimizations. From now on, items must be rendered using props `data` and `renderItem`.
Expand Down
29 changes: 21 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,15 @@ Prop | Description | Type | Default

Prop | Description | Type | Default
------ | ------ | ------ | ------
`activeSlideOffset` | From slider's center, minimum slide distance to be scrolled before being set to active | Number | `25`
`activeSlideOffset` | From slider's center, minimum slide distance to be scrolled before being set to active. | Number | `20`
`apparitionDelay` | `FlatList`'s init is a real mess, with lots of unneeded flickers and slides movement. This prop controls the delay during which the carousel will be hidden when mounted. | Number | `250`
`callbackOffsetMargin` | Scroll events might not be triggered often enough to get a precise measure and, therefore, to provide a reliable callback. This usually is an Android issue, which might be linked to the version of React Native you're using (see ["Unreliable callbacks"](#unreliable-callbacks)). To work around this, you can define a small margin that will increase the "sweet spot"'s width. The default value should cover most cases, but **you will want to increase it if you experience missed callbacks**. | Number | `5`
`enableMomentum` | See [momentum](#momentum) | Boolean | `false`
`enableSnap` | If enabled, releasing the touch will scroll to the center of the nearest/active item | Boolean | `true`
`firstItem` | Index of the first item to display | Number | `0`
`hasParallaxImages` | Whether the carousel contains `<ParallaxImage />` components or not. Required for specific data to be passed to children. | Boolean | `false`
`scrollEndDragDebounceValue` | **When momentum is disabled**, this prop defines the timeframe during which multiple callback calls should be "grouped" into a single one. This debounce also helps smoothing the snap effect 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
`shouldOptimizeUpdates` | Whether to implement a `shouldComponentUpdate` strategy to minimize updates | Boolean | `true`
`snapOnAndroid` | Snapping on android is sometimes choppy, especially when swiping quickly, so you can disable it | Boolean | `true`
`swipeThreshold` | Delta x when swiping to trigger the snap | Number | `20`
`useNativeOnScroll` | Move `onScroll` events to the native thread in order to prevent the tiny lag associated with RN's JS bridge. **Activate this if you have a `transform` and/or `opacity` animation that needs to follow carousel's scroll position closely**. More info in [this post](https://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html). Note that it will be activated if `hasParallaxImages` is set to `true` and/or if `scrollEventThrottle` is set to less than `16`. | Boolean | `false`
`vertical` | Layout slides vertically instead of horizontally | Boolean | `false`

### Autoplay
Expand All @@ -190,8 +188,6 @@ Prop | Description | Type | Default
Prop | Description | Type | Default
------ | ------ | ------ | ------
`activeSlideAlignment` | Determine active slide's alignment relative to the carousel. Possible values are: `'start'`, `'center'` and `'end'`. | String | `'center'`
`animationFunc` | Animated animation to use; you must provide the name of the method. Note that it will only be applied to the scale animation since opacity's animation type will always be set to `timing` (no one wants the opacity to 'bounce' around) | String | `timing`
`animationOptions` | Animation options to be merged with the default ones. Can be used without `animationFunc`. Note that opacity's easing will be kept linear. | Object | `{ duration: 600, easing: Easing.elastic(1) }`
`containerCustomStyle` | Optional styles for Scrollview's global wrapper | View Style Object | `{}`
`contentContainerCustomStyle` | Optional styles for Scrollview's items container | View Style Object | `{}`
`inactiveSlideOpacity` | Value of the opacity effect applied to inactive slides | Number | `0.7`
Expand Down Expand Up @@ -321,6 +317,14 @@ const styles = Stylesheet.create({
<Carousel sliderWidth={sliderWidth} itemWidth={itemWidth} />
```
### Carousel's stretched height
Since `<Carousel />` is, ultimately, based on `<ScrollView />`, it inherits [its default styles](https://github.com/facebook/react-native/blob/master/Libraries/Components/ScrollView/ScrollView.js#L864) and particularly `{ flexGrow: 1 }`. This means that, by default, **the carousel container will stretch to fill up all available space**.
If this is not what you're after, you can prevent this behavior by passing `{ flexGrow: 0 }` to prop `containerCustomStyle`.
Alternatively, you can either use this prop to pass a custom height to the container, or wrap the carousel in a `<View />` with a fixed height.
### Understanding styles
Here is a screenshot that should help you understand how each of the above variables is used.
Expand Down Expand Up @@ -400,6 +404,10 @@ export class MyCarousel extends Component {
[This plugin](https://github.com/shichongrui/react-native-on-layout) can also prove useful.
### Native-powered animations
Scroll events have been moved to the native thread in order to prevent the tiny lag associated with React Native's JavaScript bridge. This is really useful when displaying a `transform` and/or `opacity` animation that needs to follow carousel's scroll position closely. You can find more info in [this post from Facebook](https://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html).
## Known issues
### React Native version
Expand Down Expand Up @@ -427,9 +435,13 @@ We're trying to work around these issues, but the result is not always as smooth
### Unreliable callbacks
When `enableMomentum` is disabled, providing a reliable callback is really tricky since no `scrollEnd` event has been exposed yet for the `ScrollView` component. We can only rely on the `scrollEndDrag` event, which comes with a huge bunch of issues. See [#34](https://github.com/archriss/react-native-snap-carousel/issues/34) for more information.
When `enableMomentum` is disabled (default behavior), providing a reliable callback is really tricky since no `scrollEnd` event has been exposed yet for the `ScrollView` component. We can only rely on the `scrollEndDrag` event, which comes with a huge bunch of issues. See [#34](https://github.com/archriss/react-native-snap-carousel/issues/34) for more information.
Version 2.3.0 tackled these issues with all sorts of flags and hacks. But you could still be facing the following one: **when you build a debug version of your app without enabling JS remote debugging, timers may desynchronize and cause a complete callback mess**. Try to either enable remote debugging or build a production version of your app, and everything should get back to normal.
Callback handling has been completely revamped in version 3.2.0, in a less hacky and more reliable way. There is one issue though: callbacks now rely on scroll events. Usually, this is not a problem since the plugin features a native-powered scroll. **But there has been [a regression in React Native 0.46.x](https://github.com/facebook/react-native/issues/15769), that has been fixed in version 0.48.2.**
Version 2.3.0 tackled these issues with a bunch of flags and hacks. But you could still be facing the following one: **when you build a debug version of your app without enabling JS remote debugging**, timers will desynchronize and callbacks will be a complete mess. Try to either enable remote debugging or build a production version of your app, and everything should get back to normal.
If you're using an in-between version, you're in for some trouble since events won't be fired frequently enough (particularly on Android). **We've added a prop `callbackOffsetMargin` to help with this situation.**
### Error with Jest
Expand All @@ -447,6 +459,7 @@ As such, this feature should be considered experimental since it might break wit
## TODO
- [ ] Implement a custom `PanResponder` for better control over carousel's callbacks and overall feeling
- [ ] Implement 'loop' mode
- [ ] Handle changing major props on-the-fly
- [ ] Handle autoplay properly when updating children's length
Expand Down
4 changes: 2 additions & 2 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
},
"dependencies": {
"react": "16.0.0-alpha.12",
"react-native": "~0.47.2",
"react-native": "~0.48.3",
"react-native-linear-gradient": "^2.3.0",
"react-native-snap-carousel": "file:../"
},
"devDependencies": {
"babel-preset-react-native": "3.0.1"
"babel-preset-react-native": "3.0.2"
}
}
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-snap-carousel",
"version": "3.1.0",
"version": "3.2.0",
"description": "Swiper component for React Native with previews, snapping effect, parallax images, performant handling of huge numbers of items, and RTL support. Compatible with Android & iOS.",
"main": "src/index.js",
"repository": {
Expand Down Expand Up @@ -31,7 +31,6 @@
"author": "Archriss <[email protected]> (github.com/archriss)",
"license": "ISC",
"dependencies": {
"lodash.debounce": "4.0.8",
"prop-types": "^15.5.10",
"react-addons-shallow-compare": "15.6.0"
},
Expand Down
Loading

0 comments on commit ac2e144

Please sign in to comment.