Bouton d’action flottant avec explication du menu

Introduction
Nous allons reconstruire le bouton de paiement de l’application Starbucks. Non seulement il a un bouton flottant, mais il a 2 autres boutons flottants et une couverture de fond circulaire qui jaillit pour vous permettre de vous concentrer sur les options. Ces 2 autres boutons flottants apparaîtront lorsque l’utilisateur appuiera sur le bouton de paiement flottant avec animation. Attaché un fichier gif à partir duquel vous pouvez visualiser à quoi ressemblera l’animation lorsque nous appuierons sur le bouton de paiement flottant
Installation
Une configuration standard, bibliothèque d’icônes vectorielles réactives natives pour les icônes de boutons et une valeur animée. Cette valeur animée n’ira que de 0
pour 1
afin que nous puissions garder notre animation réversible.
import React, {useState} from 'react';
import {
StyleSheet,
Text,
View,
Animated,
TouchableWithoutFeedback,
Image,
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
function App(): JSX.Element {
const [animation] = useState(new Animated.Value(0));
return (
<View style={styles.container}/>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
export default App;
Ajouter un bouton en bas
Nous devons donc d’abord ajouter notre principal bouton d’action flottant. Nous n’animerons pas ce bouton, mais nous animerons le texte.
<View style={styles.container}>
<TouchableWithoutFeedback onPress={toggleOpen}>
<View style={[styles.button, styles.pay]}>
<Animated.Text style={[styles.label]}>Pay</Animated.Text>
<Text style={styles.payText}>$5.00</Text>
</View>
</TouchableWithoutFeedback>
</View>
Nous positionnerons notre bouton dans le coin et créerons un style réutilisable afin que tous nos boutons aient la même forme et la même taille. Cela nous permettra de les cacher derrière notre bouton puis de les animer de manière visible. Ensuite, pour rendre notre bouton vert, nous ajoutons simplement notre pay
style pour ajouter une couleur de fond.
De plus, nous positionnons notre texte de manière absolue et le rendons à l’intérieur de notre bouton. Sans rien ajouter top/left/bottom/right
valeurs, il flottera librement mais restera toujours centré.
label: {
color: "#FFF",
position: "absolute",
fontSize: 18,
backgroundColor: "transparent",
},
button: {
width: 60,
height: 60,
alignItems: "center",
justifyContent: "center",
shadowColor: "#333",
shadowOpacity: 0.1,
shadowOffset: { x: 2, y: 0 },
shadowRadius: 2,
borderRadius: 30,
position: "absolute",
bottom: 20,
right: 20,
},
payText: {
color: "#FFF",
},
pay: {
backgroundColor: "#00B15E",
},
Ajouter plus de boutons
Ajoutons maintenant nos autres boutons. Ceux-ci devront être animés, nous utilisons donc un Animated.View
et choisissez les icônes appropriées. Parce que notre button
class positionne tout au même endroit, et nous avons placé ces boutons au-dessus de notre pay
bouton dans le rendu, ils seront rendus derrière notre pay
bouton.
<View style={styles.container}>
<TouchableWithoutFeedback>
<Animated.View style={[styles.button, styles.other]}>
<Animated.Text style={[styles.label]}>Order</Animated.Text>
<Icon name="food-fork-drink" size={20} color="#555" />
</Animated.View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback>
<Animated.View style={[styles.button, styles.other]}>
<Animated.Text style={[styles.label]}>Reload</Animated.Text>
<Icon name="reload" size={20} color="#555" />
</Animated.View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={toggleOpen}>
<View style={[styles.button, styles.pay]}>
<Animated.Text style={[styles.label]}>Pay</Animated.Text>
<Text style={styles.payText}>$5.00</Text>
</View>
</TouchableWithoutFeedback>
</View>
La seule chose que nous devons faire est de spécifier leur couleur de fond.
other: {
backgroundColor: "#FFF",
}
Ajouter un arrière-plan masqué
Nous voulons un arrière-plan opaque noir animé circulaire, cependant, plutôt que de le masquer via l’opacité, nous allons simplement le traiter comme un autre bouton et le placer derrière le reste des boutons.
<View style={styles.container}>
<Animated.View style={[styles.background, bgStyle]} />
<TouchableWithoutFeedback>
<Animated.View style={[styles.button, styles.other, orderStyle]}>
<Animated.Text style={[styles.label, labelStyle]}>Order</Animated.Text>
<Icon name="food-fork-drink" size={20} color="#555" />
</Animated.View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback>
<Animated.View style={[styles.button, styles.other, reloadStyle]}>
<Animated.Text style={[styles.label, labelStyle]}>Reload</Animated.Text>
<Icon name="reload" size={20} color="#555" />
</Animated.View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={toggleOpen}>
<View style={[styles.button, styles.pay]}>
<Animated.Text style={[styles.label, labelStyle]}>Pay</Animated.Text>
<Text style={styles.payText}>$5.00</Text>
</View>
</TouchableWithoutFeedback>
</View>
- Fondamentalement le même que le style des boutons.
background: {
backgroundColor: "rgba(0,0,0,.2)",
position: "absolute",
width: 60,
height: 60,
bottom: 20,
right: 20,
borderRadius: 30,
},
Configurer l’animation sur la presse
Parce que nous n’avons pas besoin de basculer les événements de pointeur sur cette animation, nous avons juste besoin d’économiser sur l’instance, que notre menu soit ouvert ou fermé ou non. Ensuite, décidez d’animer pour 0
ou 1
. Cela produira une animation réversible qui peut également être interrompue à tout moment.
let _open: boolean;
const toggleOpen = () => {
if (_open) {
Animated.timing(animation, {
toValue: 0,
duration: 300,
useNativeDriver: false,
}).start();
} else {
Animated.timing(animation, {
toValue: 1,
duration: 300,
useNativeDriver: false,
}).start();
}
_open = !_open;
};
- Notre bouton de rechargement sera le plus proche, nous le compenserons donc de
-70
nous donnant un rembourrage du bouton de paiement. Notre bouton de commande sera le dernier bouton, nous avons donc juste besoin de le compenser par-140
il contournera donc le bouton de rechargement et aura également un rembourrage.
De plus, nous passerons dans notre 0<=>1
valeur animée à l’échelle pour qu’elle bouge et grandisse en même temps.
const reloadInterpolate = animation.interpolate({
inputRange: [0, 1],
outputRange: [0, -70],
});
const orderInterpolate = animation.interpolate({
inputRange: [0, 1],
outputRange: [0, -140],
});
const reloadStyle = {
transform: [
{
scale: animation
},
{
translateY: reloadInterpolate,
},
],
};
const orderStyle = {
transform: [
{
scale: animation
},
{
translateY: orderInterpolate,
},
],
};
Animer les étiquettes
Les animations d’étiquettes sont les plus difficiles des animations. Ils commencent cachés au centre de chaque bouton individuel. Cependant, nous ne voulons pas que le texte apparaisse sur nos icônes et sorte. Cela aurait l’air mauvais.
Cependant, ce que nous pouvons faire, c’est le garder caché et continuer à animer son emplacement. Ensuite, une fois que nous savons qu’il a effacé les boutons de tout chevauchement, nous le fondrons. Le texte sera toujours décalé de -30
et animer à un décalage de -90
mais pour accomplir notre fondu enchaîné, nous le ferons après la fin de notre animation 80%
complet. Nous allons donc créer une falaise à ce stade, puis la fondre rapidement en 1
pendant le dernier 20%
de l’animation.
Nous voulons également que toutes nos étiquettes fassent la même chose afin de pouvoir transmettre le même style d’étiquette à toutes nos étiquettes.
const labelPositionInterpolate = animation.interpolate({
inputRange: [0, 1],
outputRange: [-30, -90],
});
const opacityInterpolate = animation.interpolate({
inputRange: [0, 0.8, 1],
outputRange: [0, 0, 1],
});
const labelStyle = {
opacity: opacityInterpolate,
transform: [
{
translateX: labelPositionInterpolate,
},
],
};
Animer l’arrière-plan
Enfin, notre arrière-plan animé n’est qu’une échelle de notre petite boîte. Il s’agit d’un nombre arbitraire sélectionné, cependant, vous pouvez utiliser les mathématiques pour calculer combien de fois l’arrière-plan doit être mis à l’échelle avant de couvrir toute la vue. J’ai choisi un nombre assez grand pour couvrir l’écran, puis certains.
const scaleInterpolate = animation.interpolate({
inputRange: [0, 1],
outputRange: [0, 30],
});
const bgStyle = {
transform: [
{
scale: scaleInterpolate,
},
],
};
Vous pouvez télécharger le code à partir de ce lien GitHub https://github.com/amanmanhas/FloatingActionButton/blob/main/App.tsx
Merci d’avoir lu ce blog
Source link