Last active
April 10, 2019 07:09
-
-
Save vadimkorr/c03c15e5bba8e42e281faf53fa3acbb3 to your computer and use it in GitHub Desktop.
Implementation with animations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import PropTypes from "prop-types"; | |
import { StyleSheet, TouchableOpacity, Text, Animated } from "react-native"; | |
import { FontAwesome } from "@expo/vector-icons"; | |
const ICON_SQUARE_SIZE_PX = 100; | |
const ANIMATION_DURATION_MS = 150; | |
const NOTIFICATION_HEIGHT_PX = 120; | |
export const makeNotification = (iconName, colorPrimary, colorAccent) => { | |
class NotificationBase extends React.Component { | |
// initial value is 0 | |
animated = new Animated.Value(0); | |
componentDidMount() { | |
// start opening animation when component inserted into the tree | |
Animated.timing(this.animated, { | |
// animation ends with value 1 | |
toValue: 1, | |
duration: ANIMATION_DURATION_MS | |
}).start(); | |
} | |
onClosePress = () => { | |
const { onClosePress } = this.props; | |
if (onClosePress) { | |
// start closing animation | |
// and call 'onClosePress' after animation ends | |
Animated.timing(this.animated, { | |
// during closing we will animate to initial value | |
toValue: 0, | |
duration: ANIMATION_DURATION_MS | |
}).start(onClosePress); | |
} | |
}; | |
render() { | |
const { title, message } = this.props; | |
const animatedStyles = [ | |
{ | |
opacity: this.animated, | |
height: this.animated.interpolate({ | |
inputRange: [0, 1], | |
// it means that | |
// at 0 ms height will be 0 px | |
// at 75 ms height will be 60 px | |
// at 150 ms height will be 120 px | |
outputRange: [0, NOTIFICATION_HEIGHT_PX], | |
extrapolate: "clamp" | |
}), | |
transform: [ | |
{ | |
translateX: this.animated.interpolate({ | |
inputRange: [0, 1], | |
outputRange: [30, 0], // px | |
extrapolate: "clamp" | |
}) | |
} | |
] | |
} | |
]; | |
// only animatable components can be animated. e.g. Animated.View | |
return ( | |
<TouchableOpacity onPress={this.onClosePress}> | |
<Animated.View | |
style={[ | |
animatedStyles, | |
styles.mainContainer, | |
{ backgroundColor: colorPrimary } | |
]} | |
> | |
<FontAwesome | |
style={styles.icon} | |
name={iconName} | |
size={ICON_SQUARE_SIZE_PX} | |
color={colorAccent} | |
/> | |
<Text style={[styles.title, { color: colorAccent }]}>{title}</Text> | |
<Text style={[styles.message, { color: colorAccent }]}> | |
{message} | |
</Text> | |
</Animated.View> | |
</TouchableOpacity> | |
); | |
} | |
} | |
NotificationBase.propTypes = { | |
title: PropTypes.string.isRequired, | |
message: PropTypes.string.isRequired, | |
onClosePress: PropTypes.func | |
}; | |
return NotificationBase; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment