Created
June 20, 2020 10:14
-
-
Save Kida007/e5f5fd075516b8a24ccc256e8831b8fd to your computer and use it in GitHub Desktop.
ListItems Shared Background Animation ( Reanimated v2 )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Animated, { | |
useSharedValue, | |
withTiming, | |
useAnimatedStyle, | |
useDerivedValue, | |
Easing, | |
withSpring, | |
} from 'react-native-reanimated'; | |
import {View, Button, Dimensions, Text, TouchableOpacity} from 'react-native'; | |
import MaskedView from '@react-native-community/masked-view'; | |
import React, {useEffect, useState} from 'react'; | |
const {width} = Dimensions.get('window'); | |
const PADDING = 20; | |
const ITEM_WIDTH = (width - 3 * PADDING) / 2; | |
const ITEM_HEIGHT = ITEM_WIDTH / 1.3; | |
const colors = ['#FEE78B', '#616DFF', '#DA4167', '#57E2E5']; | |
export default function AnimatedStyleUpdateExample(props) { | |
const radius = useSharedValue(0); | |
const reverse = useSharedValue(0); | |
const [index, setIndex] = useState(0); | |
const [circleColor, setCircleColor] = useState(colors[index]); | |
const [color, setColor] = useState('#07AF6A'); | |
const config = { | |
duration: 1000, | |
easing: Easing.bezier(0.5, 0.01, 0, 1), | |
}; | |
const reverseConfig = { | |
duation: 0, | |
easing: Easing.bezier(0.5, 0.01, 0, 1), | |
}; | |
const style = useAnimatedStyle(() => { | |
const con = reverse.value ? reverseConfig : config; | |
if (reverse.value) | |
return { | |
height: 2 * radius.value, | |
width: 2 * radius.value, | |
top: -1 * radius.value, | |
left: -1 * radius.value, | |
borderRadius: radius.value, | |
}; | |
return { | |
height: withTiming(2 * radius.value, con), | |
width: withTiming(2 * radius.value, con), | |
top: withTiming(-1 * radius.value, con), | |
left: withTiming(-1 * radius.value, con), | |
borderRadius: withTiming(radius.value, con), | |
}; | |
}); | |
const animate = () => { | |
reverse.value = 0; | |
radius.value = 500; | |
setTimeout(() => { | |
setColor(circleColor); | |
reverse.value = 1; | |
radius.value = 0; | |
setCircleColor(colors[index + 1]); | |
setIndex((ix) => ix + 1); | |
}, 1000); | |
}; | |
const renderContent = () => ( | |
<View | |
style={{ | |
flex: 1, | |
backgroundColor: 'transparent', | |
flexWrap: 'wrap', | |
flexDirection: 'row', | |
}}> | |
<View | |
style={{ | |
width: ITEM_WIDTH, | |
height: ITEM_HEIGHT, | |
borderRadius: 5, | |
backgroundColor: 'black', | |
marginRight: 20, | |
marginBottom: 20, | |
}} | |
/> | |
<View | |
style={{ | |
width: ITEM_WIDTH, | |
height: ITEM_HEIGHT, | |
borderRadius: 5, | |
backgroundColor: 'black', | |
marginBottom: 20, | |
}} | |
/> | |
<View | |
style={{ | |
width: ITEM_WIDTH, | |
height: ITEM_HEIGHT, | |
borderRadius: 5, | |
backgroundColor: 'black', | |
marginRight: 20, | |
marginBottom: 20, | |
}} | |
/> | |
</View> | |
); | |
return ( | |
<View | |
style={{ | |
flex: 1, | |
padding: 20, | |
paddingTop: 64, | |
}}> | |
<MaskedView style={{flex: 1}} maskElement={renderContent()}> | |
<View style={{flex: 1, backgroundColor: color}} /> | |
<Animated.View | |
style={[ | |
{ | |
position: 'absolute', | |
top: 0, | |
left: 0, | |
backgroundColor: circleColor, | |
}, | |
style, | |
]} | |
/> | |
</MaskedView> | |
<View style={{alignSelf: 'center', padding: 50}}> | |
<Button title="Change Color" onPress={animate} /> | |
</View> | |
</View> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment