Skip to content

Instantly share code, notes, and snippets.

@vadimkorr
Last active April 10, 2019 07:09
Show Gist options
  • Save vadimkorr/c03c15e5bba8e42e281faf53fa3acbb3 to your computer and use it in GitHub Desktop.
Save vadimkorr/c03c15e5bba8e42e281faf53fa3acbb3 to your computer and use it in GitHub Desktop.
Implementation with animations
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