Skip to content

Instantly share code, notes, and snippets.

@tanner-west
Created August 7, 2022 02:09
Show Gist options
  • Save tanner-west/6f051a2fe6504c2f0acb451c220fbabe to your computer and use it in GitHub Desktop.
Save tanner-west/6f051a2fe6504c2f0acb451c220fbabe to your computer and use it in GitHub Desktop.
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