Skip to content

Instantly share code, notes, and snippets.

@benomatis
Last active January 26, 2021 14:35
Show Gist options
  • Save benomatis/08ad6577ff6b7f62141b489ed1eed17e to your computer and use it in GitHub Desktop.
Save benomatis/08ad6577ff6b7f62141b489ed1eed17e to your computer and use it in GitHub Desktop.
React Native Two (2) Lines Hamburger Cross Animated, Functional Component With Hooks
/**
* Hamburger Cross animation with 2 lines only
* Functional component with hooks
* Borrowed from https://github.com/GeekyAnts/react-native-hamburger
*/
import React, { useState, useEffect } from 'react'
import { Animated, TouchableWithoutFeedback } from 'react-native'
const Hamburger = ({ active, color, onPress = () => {} }) => {
const [internalActive, setInternalActive] = useState(false)
useEffect(() => {
const timeout = setTimeout(() => {
setInternalActive(!active)
animate()
}, 0)
return () => clearTimeout(timeout)
})
let topBar,
bottomBar,
bottomBarMargin,
containerAnim,
topBarMargin,
marginLeft,
width
const animate = () => {
if (!internalActive) {
Animated.spring(topBar, {
toValue: 1,
useNativeDriver: false
}).start()
Animated.spring(bottomBar, {
toValue: 1,
useNativeDriver: false
}).start()
Animated.spring(bottomBarMargin, {
toValue: -2,
useNativeDriver: false
}).start()
} else {
Animated.spring(topBar, {
toValue: 0,
useNativeDriver: false
}).start()
Animated.spring(bottomBar, {
toValue: 0,
useNativeDriver: false
}).start()
Animated.spring(bottomBarMargin, {
toValue: 4,
useNativeDriver: false
}).start()
}
}
if (internalActive) {
topBar = topBar || new Animated.Value(1)
bottomBar = bottomBar || new Animated.Value(1)
bottomBarMargin = bottomBarMargin || new Animated.Value(-2)
}
containerAnim = containerAnim || new Animated.Value(0)
topBar = topBar || new Animated.Value(0)
bottomBar = bottomBar || new Animated.Value(0)
bottomBarMargin = bottomBarMargin || new Animated.Value(4)
topBarMargin = topBarMargin || new Animated.Value(0)
marginLeft = marginLeft || new Animated.Value(0)
width = width || new Animated.Value(25)
const styles = {
wrapper: {
width: 35,
justifyContent: 'center',
alignItems: 'center',
height: 35,
transform: [
{
rotate: containerAnim.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg']
})
}
]
},
topBar: {
height: 2,
marginLeft: marginLeft,
width: width,
marginBottom: topBarMargin,
backgroundColor: color ? color : 'black',
transform: [
{
rotate: topBar.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '-45deg']
})
}
]
},
bottomBar: {
height: 2,
marginLeft: marginLeft,
width: width,
backgroundColor: color ? color : 'black',
marginTop: bottomBarMargin,
transform: [
{
rotate: bottomBar.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '45deg']
})
}
]
}
}
return (
<TouchableWithoutFeedback
onPress={() => {
onPress()
animate()
}}>
<Animated.View style={styles.wrapper}>
<Animated.View style={styles.topBar} />
<Animated.View style={styles.bottomBar} />
</Animated.View>
</TouchableWithoutFeedback>
)
}
export default Hamburger
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment