Created
August 7, 2022 02:09
-
-
Save tanner-west/6f051a2fe6504c2f0acb451c220fbabe to your computer and use it in GitHub Desktop.
This file contains hidden or 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 React, {useState} from 'react'; | |
import {View, SafeAreaView, ScrollView, Text, StatusBar} from 'react-native'; | |
import {MotiView} from 'moti'; | |
import { | |
useAnimatedProps, | |
useDerivedValue, | |
withTiming, | |
interpolateColor, | |
} from 'react-native-reanimated'; | |
import {TouchableOpacity} from 'react-native-gesture-handler'; | |
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; | |
const initialValues = [ | |
{ | |
label: 'Stocks', | |
subLabel: 'Small Cap', | |
value: 20, | |
}, | |
{ | |
label: 'Stocks', | |
subLabel: 'Large Cap', | |
value: 10, | |
}, | |
{label: 'Bonds', value: 20}, | |
]; | |
const MotiBars = () => { | |
const [values, setValues] = useState(initialValues); | |
const containerHeight = 400; | |
const updateHeight = (index: number, value: number) => { | |
const newHeights = [...values]; | |
newHeights[index] = {...newHeights[index], value: value}; | |
setValues(newHeights); | |
}; | |
const percentageAllocated = Math.round( | |
(values[0].value + values[1].value + values[2].value) / 1, | |
); | |
const percentageAllocatedDerived = useDerivedValue( | |
() => (values[0].value + values[1].value + values[2].value) / 1, | |
); | |
const backgroundColor = useDerivedValue(() => { | |
return interpolateColor( | |
percentageAllocatedDerived.value, | |
[50, 75, 100, 125, 150], | |
['#FF605C', '#FFBD44', '#00CA4E', '#FFBD44', '#FF605C'], | |
); | |
}); | |
const animatedProps = useAnimatedProps(() => { | |
return { | |
backgroundColor: withTiming(backgroundColor.value, {duration: 500}), | |
}; | |
}); | |
return ( | |
<SafeAreaView style={{flex: 1, backgroundColor: '#17021A'}}> | |
<StatusBar barStyle={"light-content"}/> | |
<ScrollView style={{flex: 1, flexDirection: 'column', padding: 10}}> | |
<View style={{marginBottom: 20}}> | |
<Text style={{color: 'white', fontSize: 20, marginBottom: 10}}> | |
Total allocated: {percentageAllocated}% | |
</Text> | |
<MotiView | |
animate={{ | |
opacity: percentageAllocated === 100 ? 1 : 0, | |
scaleY: percentageAllocated === 100 ? 1 : 0, | |
}}> | |
<Text style={{color: 'white', fontWeight: 'bold', fontSize: 24}}> | |
Your funds are 100% allocated! | |
</Text> | |
</MotiView> | |
</View> | |
<View | |
style={{ | |
flexDirection: 'row', | |
justifyContent: 'space-around', | |
}}> | |
{values.map((v, i) => ( | |
<View key={i} style={{flex: 1, height: containerHeight}}> | |
<Text | |
style={{ | |
color: 'white', | |
fontWeight: 'bold', | |
fontSize: 20, | |
textAlign: 'center', | |
}}> | |
{v.label} | |
</Text> | |
<Text | |
style={{ | |
color: 'white', | |
marginBottom: 5, | |
fontSize: 20, | |
textAlign: 'center', | |
}}> | |
{v.subLabel} | |
</Text> | |
<View | |
style={{ | |
flex: 1, | |
backgroundColor: '#383838', | |
height: '100%', | |
flexDirection: 'column', | |
justifyContent: 'flex-end', | |
margin: 5, | |
borderTopLeftRadius: 10, | |
borderTopRightRadius: 10, | |
}}> | |
<MotiView | |
from={{height: 0}} | |
style={{ | |
borderTopLeftRadius: 10, | |
borderTopRightRadius: 10, | |
zIndex: 1, | |
}} | |
animate={{ | |
height: (values[i].value / 100) * containerHeight * 0.8, | |
}} | |
animatedProps={animatedProps} | |
transition={{type: 'timing', duration: 400}}></MotiView> | |
</View> | |
<View | |
key={i} | |
style={{ | |
flexDirection: 'column', | |
justifyContent: 'center', | |
alignItems: 'center', | |
overflow: 'visible', | |
}}> | |
<Text | |
style={{color: 'white', marginVertical: 10, fontSize: 20}}> | |
{v.value}% | |
</Text> | |
<TouchableOpacity | |
onPress={() => updateHeight(i, values[i].value + 5)}> | |
<MaterialCommunityIcons | |
name={'plus-circle-outline'} | |
color={'white'} | |
size={48} | |
/> | |
</TouchableOpacity> | |
<TouchableOpacity | |
onPress={() => updateHeight(i, values[i].value - 5)}> | |
<MaterialCommunityIcons | |
name={'minus-circle-outline'} | |
color={'white'} | |
size={48} | |
/> | |
</TouchableOpacity> | |
</View> | |
</View> | |
))} | |
</View> | |
<View | |
style={{ | |
flexDirection: 'row', | |
justifyContent: 'space-around', | |
}}></View> | |
</ScrollView> | |
</SafeAreaView> | |
); | |
}; | |
export default MotiBars; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment