rn-video-slider
Version:
A dedicated progress slider for video players in React-native.
184 lines (146 loc) • 10.4 kB
Markdown
# rn-video-slider
A dedicated progress slider for video player's custom user interfaces
in React-Native. It can also be used in audio players because why not? 😎
<img src="https://github.com/armata99/assets/blob/master/rn-video-slider/main.gif" alt="Demonstration">
<img src="https://github.com/armata99/assets/blob/master/rn-video-slider/buffer.gif" alt="Buffer Demonstration">
<img src="https://github.com/armata99/assets/blob/master/rn-video-slider/bubble.gif" alt="Bubble Demonstration">
## Why this module?
- superior performance thanks to Reanimated library
- clean and simple implementation that makes it easy to extend
- integrated buffer indicator for online streams
- fully written in Typescript
- easiest way to use
- RTL support
## Installation
This module uses `react-native-reanimated` and `react-native-gesture-handler` as
peer dependencies. make sure You have installed them correctly. You may also install
`react-native-video`. Check out these links to proceed their installation process:
- [reanimated installation](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started#installation)
- [gesture-handler installation](https://docs.swmansion.com/react-native-gesture-handler/docs/fundamentals/installation)
- [video installation](https://react-native-video.github.io/react-native-video/installation)
Once you are done with above, add the main package with one of below commands:
### using npm
```sh
npm i rn-video-slider
```
### using yarn
```sh
yarn add rn-video-slider
```
That will be it.
## Usage
```typescript jsx
import {Dimensions} from "react-native";
import Slider, {SliderRef} from "rn-video-slider";
const ControlSet = () => {
const sliderRef = React.createRef<SliderRef>();
//call below function in video progress callback
//sliderRef.current?.setProgress(0.5);
const _onSlide = (value: number) => {
//seek your video with value
};
//this simply means 80% of screen's width
const sliderWdith = Dimensions.get('window').width * 0.8;
return (
<Slider
ref={sliderRef}
width={sliderWdith}
onSlide={_onSlide}
/>
)
}
```
**Note:** You can see the Component in action by cloning this
repo and building its test app. Just head over to `testapp`
directory, install the dependencies and run it on Android or IOS.
## Slider Properties
Here is the list of properties that you can set or override.
| Name | Type | Required | Default Value | Description |
|:---------------------:|:---------------------:|:--------:|:---------------------:|----------------------------------------------------------------------------------------------------------------------|
| width | number | Yes | undefined | width of slider track |
| height | number | No | 3 | height of slider track |
| thumbSize | number | No | 12 | diameter of sliding thumb |
| thumbColor | string | No | #FFFFFF | color of sliding thumb |
| thumbStyle | ViewStyle | No | undefined | style override for thumb view. It has higher priority than thumbSize and thumbColor. |
| progressColor | string | No | #FFFFFF | color of progress indicator |
| bufferProgressColor | string | No | rgba(255,255,255,0.5) | color of buffer progress indicator |
| trackColor | string | No | rgba(255,255,255,0.2) | color of underlying view |
| rootStyle | ViewStyle | No | undefined | style addon for root view |
| isRTL | boolean | No | I18nManager.isRTL | overrides direction of movement. setting to "true" makes the slider animate from right to left. |
| tapActive | boolean | No | true | activates tap gesture. when set to "true", onSlide function fires on receiving single taps. |
| initialProgress | number | No | 0 | sets the initial progress value. |
| bufferInitialProgress | number | No | 0 | sets the initial buffer progress value. |
| bubbleContainerStyle | ViewStyle | No | 0 | style object that overrides default style of bubble container view which is absolutely positioned inside thumb view. |
| bubbleVisibility | 'always' \| 'onTouch' | No | No | determines when bubble should be displayed | determines when bubble should show up |
**Note:** Root view has a default padding equal to 10.
Override it in root style if you need to.
**Note2:** You can disable thumb shadow by passing appropriate thumbStyle. (`elevation: 0, shadowOpacity: 0`)
## Event properties
Here is the list of events that slider fires.
| Name | Params | Description |
|:-------------:|:------:|---------------------------------------------------------------------------------------------------------------------------------------------|
| onSlide | value | Called when the slider is being moved via a pan or tap gesture. It passes a "value" which is a number that changes from 0 to 1. |
| onSlideStart | value | Called when one of tapping or sliding gestures start. It passes the current progress as "value". |
| onSlideFinish | value | Called when one of tapping or sliding gestures finish. It passes the current progress as "value". |
| renderBubble | value | Called when thumb is being held via touch gesture. It passes the current progress as "value". Use it to render hovering bubble above thumb. |
## Reference Methods
Here is the list of methods that can be called via reference.
| Name | Params | Description |
|:-----------------:|:------:|----------------------------------------------------|
| setProgress | value | Animates main progress slider based on given value |
| setColdProgress | value | Sets main progress level without any animation |
| setBufferProgress | value | Sets progress level of the buffer indicator |
**Note:** progress values are a float from 0 to 1
## How To Render Hovering Bubble
You can either use the built-in bubble component or render your own. Read below to proceed with the built-in one.
### Example
```typescript jsx
import {Dimensions} from "react-native";
//1. import the bubble
import Slider, {Bubble} from "rn-video-slider";
const Example = () => {
const sliderWdith = Dimensions.get('window').width * 0.8;
//2. make a rendering function for it.
// head over to `testapp/src/conveter.ts` to see the `progressToVideoTime` function
const _renderBubble = (progress: number) => {
return <Bubble text={progressToVideoTime(progress, videoLength.current)} />;
};
//3. use it
return (
<Slider
width={sliderWdith}
renderBubble={_renderBubble}
/>
)
}
```
### Bubble Properties
| Name | Type | Required | Default Value | Description |
|:-----------:|:-----------:|:--------:|:-------------:|----------------------------------------------------------------------------------------------------------|
| `rootStyle` | `ViewStyle` | No | `undefined` | Custom style object for the bubble's root view |
| `text` | `string` | Yes | `undefined` | Text to display at center of bubble (Usually it's video time for corresponding to the current progress.) |
| `textStyle` | `TextStyle` | No | `undefined` | Custom style object for the bubble's text element |
## TODO list
- [x] ~~add hovering bubble feature~~
- [x] ~~add in-code docs~~
- [x] ~~ensure fabric support~~
- [x] ~~more and better demo gifs~~
- [x] ~~cleanups and refactors~~
- [x] ~~bump test-app dependencies up~~
- [x] ~~write a better example~~
- [x] ~~fix delay between thumb and track while sliding fast~~
- [x] ~~implement tap to seek feature~~
- [x] ~~replace the deprecated `useAnimatedGestureHandler` with newer API~~
- [x] ~~add style prop for root view~~
## Contributions
If you have any idea to improve or fix something, open an issue and state
it in details. You will always be welcomed.
## Compatability
- `react-native-reanimated`: `2.x`, `3.x`
- `react-native-gesture-handler`: `2.x`
## Acknowledgement
The idea behind this is from `react-native-reanimated-slider`.
Since the mentioned module is written with Reanimated v1 API, and hasn't
been updated for a long time, I decided to remake it.
## License
[MIT License](https://opensource.org/licenses/MIT)