Skip to content

Instantly share code, notes, and snippets.

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

  • Save Drzaln/26cbf55f817c86c5d88cc21bf28afb74 to your computer and use it in GitHub Desktop.

Select an option

Save Drzaln/26cbf55f817c86c5d88cc21bf28afb74 to your computer and use it in GitHub Desktop.
Pulse badge component
import React, {useRef, useEffect} from 'react';
import {View, StyleSheet} from 'react-native';
import Animated, {
useSharedValue,
useAnimatedStyle,
withTiming,
withRepeat,
Easing,
withDelay,
} from 'react-native-reanimated';
interface PulseBadgeProps {
size?: number;
color?: string;
duration?: number;
outerCircle?: number;
}
const PulseBadge: React.FC<PulseBadgeProps> = ({
size = 100,
color = 'red',
duration = 1500,
outerCircle = 4,
}) => {
const animations = useRef(
Array.from({length: outerCircle}, () => useSharedValue(0)),
).current;
useEffect(() => {
animations.forEach((animation, index) => {
animation.value = withRepeat(
withDelay(
(index * duration) / outerCircle,
withTiming(1, {
duration: duration,
easing: Easing.inOut(Easing.ease),
}),
),
-1,
false,
);
});
}, [animations, duration, outerCircle]);
const createAnimatedStyle = (animation: Animated.SharedValue<number>) =>
useAnimatedStyle(() => {
return {
transform: [
{
scale: animation.value * 2.5,
},
],
opacity: 1 - animation.value,
};
});
return (
<View style={[styles.container, {width: size * 2, height: size * 2}]}>
{animations.map((animation, index) => (
<Animated.View
key={index}
style={[
styles.circle,
createAnimatedStyle(animation),
{
width: size * 2,
height: size * 2,
borderRadius: size,
backgroundColor: color,
},
]}
/>
))}
<View
style={[
styles.innerCircle,
{
width: size,
height: size,
borderRadius: size / 2,
backgroundColor: color,
},
]}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
alignItems: 'center',
justifyContent: 'center',
},
circle: {
position: 'absolute',
},
innerCircle: {
position: 'absolute',
zIndex: 1,
},
});
export default PulseBadge;
// How to use it
// <PulseBadge size={10} color="red" duration={2000} />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment