Skip to content

Commit

Permalink
feat: Replace Animation Library to Reanimated (#77)
Browse files Browse the repository at this point in the history
* feat: Replace Animation Library to Reanimated
---------

Co-authored-by: Ovidiu Cristescu <[email protected]>
  • Loading branch information
goheroes and LunatiqueCoder authored Sep 24, 2023
1 parent 283c83c commit 31fb528
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 146 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"dependencies": {},
"peerDependencies": {
"react-native": ">=0.46.0",
"react-native-video": ">=2.0.0"
"react-native-video": ">=2.0.0",
"react-native-reanimated": "^2.12.0"
},
"devDependencies": {
"@react-native-community/eslint-config": "^3.0.1",
Expand All @@ -42,6 +43,7 @@
"react-native": "npm:[email protected]",
"react-native-builder-bob": "^0.18.2",
"react-native-video": "^5.2.0",
"react-native-reanimated": "^2.12.0",
"release-it": "^15.6.0",
"typescript": "^4.6.2"
},
Expand Down
4 changes: 2 additions & 2 deletions src/VideoPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ export const VideoPlayer = (props: VideoPlayerProps) => {
};

const {animations, hideControlAnimation, showControlAnimation} =
useAnimations(loading, controlAnimationTiming);
useAnimations(controlAnimationTiming);

const {clearControlTimeout, resetControlTimeout, setControlTimeout} =
useControlTimeout({
Expand Down Expand Up @@ -412,7 +412,7 @@ export const VideoPlayer = (props: VideoPlayerProps) => {
source={source}
/>
{loading ? (
<Loader animations={animations} />
<Loader />
) : (
<>
<Error error={error} />
Expand Down
8 changes: 3 additions & 5 deletions src/components/BottomControls.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, {Dispatch, SetStateAction} from 'react';
import {
Animated,
ImageBackground,
SafeAreaView,
StyleSheet,
GestureResponderHandlers,
} from 'react-native';
import Animated from 'react-native-reanimated';
import {Timer} from './Timer';
import {Title} from './Title';
import {NullControl} from './NullControl';
Expand Down Expand Up @@ -105,10 +105,8 @@ export const BottomControls = ({
<Animated.View
style={[
_styles.bottom,
{
opacity: animations.controlsOpacity,
marginBottom: animations.bottomControl.marginBottom,
},
animations.controlsOpacity,
animations.bottomControl,
]}>
<ImageBackground
source={require('../assets/img/bottom-vignette.png')}
Expand Down
34 changes: 9 additions & 25 deletions src/components/Loader/Loader.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
import React from 'react';
import {Animated, View} from 'react-native';
import {View, ActivityIndicator} from 'react-native';
import {styles} from './styles';
import type {VideoAnimations} from '../../types';

interface LoaderProps {
animations: VideoAnimations;
}
interface LoaderProps {}

export const Loader = ({animations}: LoaderProps) => (
<View style={styles.container}>
<Animated.Image
source={require('../../assets/img/loader-icon.png')}
style={[
styles.icon,
{
transform: [
{
rotate: animations.loader.rotate.interpolate({
inputRange: [0, 360],
outputRange: ['0deg', '360deg'],
}),
},
],
},
]}
/>
</View>
);
export const Loader = ({}: LoaderProps) => {
return (
<View style={styles.container}>
<ActivityIndicator />
</View>
);
};
12 changes: 3 additions & 9 deletions src/components/Overlay.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import React from 'react';
import {Animated, StyleSheet} from 'react-native';
import {StyleSheet} from 'react-native';
import Animated from 'react-native-reanimated';
import type {VideoAnimations} from '../types';

export const Overlay = ({animations}: {animations: VideoAnimations}) => {
return (
<Animated.View
style={[
_styles.overlay,
{
opacity: animations.controlsOpacity,
},
]}
/>
<Animated.View style={[_styles.overlay, animations.controlsOpacity]} />
);
};

Expand Down
6 changes: 3 additions & 3 deletions src/components/PlayPause/PlayPause.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {createRef} from 'react';
import {Animated, Image, Platform, TouchableHighlight} from 'react-native';
import {Image, Platform, TouchableHighlight} from 'react-native';
import Animated from 'react-native-reanimated';
import {Control} from '../Control';
import {NullControl} from '../NullControl';
import type {VideoAnimations} from '../../types';
Expand Down Expand Up @@ -38,7 +39,6 @@ export const PlayPause = ({
let source = paused ? play : pause;

const animatedStyles = {
opacity: animations.controlsOpacity,
zIndex: showControls ? 99999 : 0,
};

Expand All @@ -49,7 +49,7 @@ export const PlayPause = ({
return (
<Animated.View
pointerEvents={'box-none'}
style={[styles.container, animatedStyles]}>
style={[styles.container, animatedStyles, animations.controlsOpacity]}>
{!disableSeekButtons ? (
<Control
disabled={!showControls}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Timer/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {StyleSheet} from 'react-native';

export const styles = StyleSheet.create({
timer: {
width: 160,
maxWidth: 160,
},
timerText: {
backgroundColor: 'transparent',
Expand Down
2 changes: 1 addition & 1 deletion src/components/Title.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {StyleSheet} from 'react-native';
const _styles = StyleSheet.create({
title: {
alignItems: 'center',
flex: 0.6,
flex: 1,
flexDirection: 'column',
padding: 0,
},
Expand Down
8 changes: 3 additions & 5 deletions src/components/TopControls.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, {memo} from 'react';
import {
Animated,
ImageBackground,
SafeAreaView,
StyleSheet,
View,
GestureResponderHandlers,
} from 'react-native';
import Animated from 'react-native-reanimated';
import {Volume} from './Volume';
import {Back} from './Back';
import {NullControl} from './NullControl';
Expand Down Expand Up @@ -64,10 +64,8 @@ export const TopControls = memo(
<Animated.View
style={[
_styles.top,
{
opacity: animations.controlsOpacity,
marginTop: animations.topControl.marginTop,
},
animations.controlsOpacity,
animations.topControl,
]}>
<ImageBackground
source={require('../assets/img/top-vignette.png')}
Expand Down
125 changes: 42 additions & 83 deletions src/hooks/useAnimations.ts
Original file line number Diff line number Diff line change
@@ -1,97 +1,56 @@
import {useEffect, useRef} from 'react';
import {Animated, Easing} from 'react-native';
import {
useSharedValue,
withTiming,
useAnimatedStyle,
} from 'react-native-reanimated';

export const useAnimations = (
loading: boolean,
controlAnimationTiming: number,
) => {
const bottomControlMarginBottom = useRef(new Animated.Value(0)).current;
const controlsOpacity = useRef(new Animated.Value(1)).current;
const topControlMarginTop = useRef(new Animated.Value(0)).current;
const videoOpacity = useRef(new Animated.Value(-100)).current;
const loaderRotateAnim = useRef(new Animated.Value(0)).current;
export const useAnimations = (controlAnimationTiming: number) => {
const bottomControlMarginBottom = useSharedValue(0);
const controlsOpacity = useSharedValue(1);
const topControlMarginTop = useSharedValue(0);

const animations = {
bottomControl: {
marginBottom: bottomControlMarginBottom,
},
topControl: {
marginTop: topControlMarginTop,
},
video: {
opacity: videoOpacity,
},
loader: {
rotate: loaderRotateAnim,
MAX_VALUE: 360,
},
controlsOpacity,
bottomControl: useAnimatedStyle(() => {
return {
transform: [{translateY: bottomControlMarginBottom.value}],
};
}),
topControl: useAnimatedStyle(() => {
return {
transform: [{translateY: topControlMarginTop.value}],
};
}),
controlsOpacity: useAnimatedStyle(() => {
return {
opacity: controlsOpacity.value,
};
}),
};

const hideControlAnimation = () => {
Animated.parallel([
Animated.timing(animations.controlsOpacity, {
toValue: 0,
duration: controlAnimationTiming,
useNativeDriver: false,
}),
Animated.timing(animations.topControl.marginTop, {
toValue: -100,
duration: controlAnimationTiming,
useNativeDriver: false,
}),
Animated.timing(animations.bottomControl.marginBottom, {
toValue: -100,
duration: controlAnimationTiming,
useNativeDriver: false,
}),
]).start();
bottomControlMarginBottom.value = withTiming(100, {
duration: controlAnimationTiming,
});
topControlMarginTop.value = withTiming(-100, {
duration: controlAnimationTiming,
});
controlsOpacity.value = withTiming(0, {
duration: controlAnimationTiming,
});
};

const showControlAnimation = () => {
Animated.parallel([
Animated.timing(animations.controlsOpacity, {
toValue: 1,
duration: controlAnimationTiming,
useNativeDriver: false,
}),
Animated.timing(animations.topControl.marginTop, {
toValue: 0,
duration: controlAnimationTiming,
useNativeDriver: false,
}),
Animated.timing(animations.bottomControl.marginBottom, {
toValue: 0,
duration: controlAnimationTiming,
useNativeDriver: false,
}),
]).start();
bottomControlMarginBottom.value = withTiming(0, {
duration: controlAnimationTiming,
});
topControlMarginTop.value = withTiming(0, {
duration: controlAnimationTiming,
});
controlsOpacity.value = withTiming(1, {
duration: controlAnimationTiming,
});
};

useEffect(() => {
if (loading) {
const loadAnimation = () => {
if (loading) {
Animated.sequence([
Animated.timing(animations.loader.rotate, {
toValue: animations.loader.MAX_VALUE,
duration: 1500,
easing: Easing.linear,
useNativeDriver: false,
}),
Animated.timing(animations.loader.rotate, {
toValue: 0,
duration: 0,
easing: Easing.linear,
useNativeDriver: false,
}),
]).start(loadAnimation);
}
};
loadAnimation();
}
}, [animations.loader.MAX_VALUE, animations.loader.rotate, loading]);

return {
animations,
hideControlAnimation,
Expand Down
16 changes: 5 additions & 11 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import type {RefObject} from 'react';
import type {Animated, ViewStyle, StyleProp} from 'react-native';
import type {ViewStyle, StyleProp} from 'react-native';
import type {StyleProps} from 'react-native-reanimated';
import type VideoResource from 'react-native-video';
import type {VideoProperties} from 'react-native-video';

export interface VideoAnimations {
bottomControl: {marginBottom: Animated.Value};
topControl: {marginTop: Animated.Value};
video: {
opacity: Animated.Value;
};
loader: {
rotate: Animated.Value;
MAX_VALUE: number;
};
controlsOpacity: Animated.Value;
bottomControl: StyleProps;
topControl: StyleProps;
controlsOpacity: StyleProps;
}

export interface VideoPlayerProps extends VideoProperties {
Expand Down

0 comments on commit 31fb528

Please sign in to comment.