Skip to content

Instantly share code, notes, and snippets.

@piaskowyk
Last active February 17, 2025 06:08
Show Gist options
  • Save piaskowyk/8ffebaaf12565a0ed26a38a010ee62fc to your computer and use it in GitHub Desktop.
Save piaskowyk/8ffebaaf12565a0ed26a38a010ee62fc to your computer and use it in GitHub Desktop.
import React, { useState } from 'react';
import { Pressable, Text } from 'react-native';
import Animated, { css } from 'react-native-reanimated';
export default function ParticleButton() {
const [pressed, setPressed] = useState(false);
const [showParticles, setShowParticles] = useState(false);
return (
<Pressable
onPressIn={() => setPressed(true)}
onPressOut={() => setPressed(false)}
onPress={() => setShowParticles(!showParticles)}
style={{ marginTop: 30 }}
>
<Animated.View
style={[
styles.button,
pressed ? styles.animationDown : styles.animationUp,
showParticles ? { backgroundColor: 'rgb(43, 192, 92)' } : { backgroundColor: 'rgb(227, 57, 57)' },
]}
>
<Text style={styles.text}>
{showParticles ? '🎉' : '+'}
</Text>
</Animated.View>
<Animated.View style={[
styles.buttonBackground,
showParticles ? { backgroundColor: 'rgb(22, 137, 41)' } : { backgroundColor: 'rgb(172, 41, 41)' },
]} />
{[
{ x: -40, y: -40 },
{ x: 40, y: -70 },
{ x: 120, y: -40 },
{ x: 160, y: 40 },
{ x: 120, y: 120 },
{ x: 40, y: 160 },
{ x: -40, y: 120 },
{ x: -80, y: 40 },
].map((position, index) => {
return <Particle key={index} x={position.x} y={position.y} state={showParticles} />;
})}
</Pressable>
);
}
function Particle({ x, y, state }: { x: number, y: number, state: boolean }) {
return (
<Animated.View
style={[
styles.particle,
{ transform: [{ translateX: x }, { translateY: y }]},
state ? styles.particleDown : styles.particleUp,
]}
/>
);
}
const styles = css.create({
button: {
transitionProperty: 'all',
transitionDuration: 200,
borderRadius: '100%',
width: 100,
height: 100,
justifyContent: 'center',
alignItems: 'center',
},
buttonBackground: {
transitionProperty: 'all',
transitionDuration: 200,
borderRadius: '100%',
width: 100,
height: 100,
transform: [{ translateY: -90 }],
zIndex: -1,
},
text: {
color: 'white',
fontSize: 50,
textAlign: 'center',
fontWeight: 'bold',
},
particle: {
backgroundColor: 'rgb(7, 205, 69)',
borderRadius: '100%',
width: 20,
height: 20,
zIndex: -2,
position: 'absolute',
},
animationDown: {
animationDuration: 150,
animationTimingFunction: 'easeIn',
animationFillMode: 'forwards',
animationName: {
'0%': { transform: [{ translateY: 0 }] },
'100%': { transform: [{ translateY: 7 }] },
},
},
animationUp: {
animationDuration: 150,
animationTimingFunction: 'easeOut',
animationFillMode: 'forwards',
animationName: {
'0%': { transform: [{ translateY: 7 }] },
'100%': { transform: [{ translateY: 0 }] },
},
},
particleDown: {
animationDuration: 600,
animationTimingFunction: 'easeOut',
animationFillMode: 'both',
animationName: {
'0%': { transform: [{ translateY: 50 }, { translateX: 40 }], opacity: 1 },
'30%': { opacity: 1 },
'100%': { opacity: 0 },
},
},
particleUp: {
opacity: 0,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment