Skip to content

Instantly share code, notes, and snippets.

@Drzaln
Created May 16, 2024 08:49
Show Gist options
  • Select an option

  • Save Drzaln/70139bdcd4d1fb3a77a33ee909baec4f to your computer and use it in GitHub Desktop.

Select an option

Save Drzaln/70139bdcd4d1fb3a77a33ee909baec4f to your computer and use it in GitHub Desktop.
Animate border view
import React from 'react';
import {View, StyleSheet, Pressable, LayoutChangeEvent} from 'react-native';
import Animated, {
useSharedValue,
useAnimatedStyle,
withRepeat,
withTiming,
Easing,
} from 'react-native-reanimated';
import LinearGradient from 'react-native-linear-gradient';
const AnimateBorderView = ({children, borderRadius = 12, borderWidth = 10}) => {
const rotation = useSharedValue(0);
const [viewWidth, setViewWidth] = React.useState(0);
const [viewHeight, setViewHeight] = React.useState(0);
const pickGreaterValue = (value1: number, value2: number) => {
return value1 > value2 ? value1 : value2;
};
const onLayout = (event: LayoutChangeEvent) => {
const {width, height} = event.nativeEvent.layout;
setViewWidth(pickGreaterValue(width, viewWidth));
setViewHeight(pickGreaterValue(height, viewHeight));
};
const testGreater = pickGreaterValue(viewHeight, viewWidth);
// Set up the rotation animation
React.useEffect(() => {
rotation.value = withRepeat(
withTiming(360, {
duration: 2000,
easing: Easing.linear,
}),
-1,
);
}, [rotation]);
// Animated style for the rotating
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [{rotate: `${rotation.value}deg`}],
};
});
return (
<Pressable
style={{
height: viewHeight + borderWidth,
width: viewWidth + borderWidth,
borderRadius: borderRadius + 2,
alignItems: 'center',
justifyContent: 'center',
overflow: 'hidden',
}}>
<Animated.View
style={[
animatedStyle,
{
position: 'absolute',
height: testGreater + 100,
width: testGreater + 100,
flex: 1,
},
]}>
<View style={{flex: 1, flexDirection: 'row'}}>
{/* <View style={{backgroundColor: 'blue', flex: 1}} /> */}
<LinearGradient
colors={['#E02144', '#ffffff']}
style={{
flex: 1,
}}
/>
<View style={{backgroundColor: 'white', flex: 1}} />
</View>
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={{backgroundColor: 'white', flex: 1}} />
<LinearGradient
colors={['#ffffff', '#E02144']}
style={{
flex: 1,
}}
/>
</View>
</Animated.View>
<View
onLayout={onLayout}
style={{
height: 50,
width: 200,
backgroundColor: 'white',
borderRadius: borderRadius - 2,
}}>
{children}
</View>
</Pressable>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
flex: 1,
},
});
export default AnimateBorderView;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment