forked from vergnet/application-amicale
Improved mascot style management
This commit is contained in:
parent
de41a57930
commit
0ed3122dcf
6 changed files with 119 additions and 102 deletions
|
@ -3,9 +3,10 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import * as Animatable from "react-native-animatable";
|
import * as Animatable from "react-native-animatable";
|
||||||
import {Image, TouchableWithoutFeedback, View} from "react-native";
|
import {Image, TouchableWithoutFeedback, View} from "react-native";
|
||||||
|
import type {ViewStyle} from "react-native/Libraries/StyleSheet/StyleSheet";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
size: number,
|
style?: ViewStyle,
|
||||||
emotion: number,
|
emotion: number,
|
||||||
animated: boolean,
|
animated: boolean,
|
||||||
entryAnimation: Animatable.AnimatableProperties | null,
|
entryAnimation: Animatable.AnimatableProperties | null,
|
||||||
|
@ -116,9 +117,10 @@ class Mascot extends React.Component<Props, State> {
|
||||||
|
|
||||||
if (this.props.onPress == null) {
|
if (this.props.onPress == null) {
|
||||||
this.onPress = (viewRef: AnimatableViewRef) => {
|
this.onPress = (viewRef: AnimatableViewRef) => {
|
||||||
if (viewRef.current != null) {
|
let ref = viewRef.current;
|
||||||
|
if (ref != null) {
|
||||||
this.setState({currentEmotion: MASCOT_STYLE.LOVE});
|
this.setState({currentEmotion: MASCOT_STYLE.LOVE});
|
||||||
viewRef.current.rubberBand(1500).then(() => {
|
ref.rubberBand(1500).then(() => {
|
||||||
this.setState({currentEmotion: this.initialEmotion});
|
this.setState({currentEmotion: this.initialEmotion});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -130,9 +132,10 @@ class Mascot extends React.Component<Props, State> {
|
||||||
|
|
||||||
if (this.props.onLongPress == null) {
|
if (this.props.onLongPress == null) {
|
||||||
this.onLongPress = (viewRef: AnimatableViewRef) => {
|
this.onLongPress = (viewRef: AnimatableViewRef) => {
|
||||||
if (viewRef.current != null) {
|
let ref = viewRef.current;
|
||||||
|
if (ref != null) {
|
||||||
this.setState({currentEmotion: MASCOT_STYLE.ANGRY});
|
this.setState({currentEmotion: MASCOT_STYLE.ANGRY});
|
||||||
viewRef.current.tada(1000).then(() => {
|
ref.tada(1000).then(() => {
|
||||||
this.setState({currentEmotion: this.initialEmotion});
|
this.setState({currentEmotion: this.initialEmotion});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -153,8 +156,8 @@ class Mascot extends React.Component<Props, State> {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: "15%",
|
top: "15%",
|
||||||
left: 0,
|
left: 0,
|
||||||
width: this.props.size,
|
width: "100%",
|
||||||
height: this.props.size,
|
height: "100%",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
@ -168,8 +171,8 @@ class Mascot extends React.Component<Props, State> {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: "15%",
|
top: "15%",
|
||||||
left: isRight ? "-11%" : "11%",
|
left: isRight ? "-11%" : "11%",
|
||||||
width: this.props.size,
|
width: "100%",
|
||||||
height: this.props.size,
|
height: "100%",
|
||||||
transform: [{rotateY: rotation}]
|
transform: [{rotateY: rotation}]
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -181,8 +184,8 @@ class Mascot extends React.Component<Props, State> {
|
||||||
key={"container"}
|
key={"container"}
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
width: this.props.size,
|
width: "100%",
|
||||||
height: this.props.size,
|
height: "100%",
|
||||||
}}/>);
|
}}/>);
|
||||||
if (emotion === MASCOT_STYLE.CUTE) {
|
if (emotion === MASCOT_STYLE.CUTE) {
|
||||||
final.push(this.getEye(EYE_STYLE.CUTE, true));
|
final.push(this.getEye(EYE_STYLE.CUTE, true));
|
||||||
|
@ -217,14 +220,13 @@ class Mascot extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const size = this.props.size;
|
|
||||||
const entryAnimation = this.props.animated ? this.props.entryAnimation : null;
|
const entryAnimation = this.props.animated ? this.props.entryAnimation : null;
|
||||||
const loopAnimation = this.props.animated ? this.props.loopAnimation : null;
|
const loopAnimation = this.props.animated ? this.props.loopAnimation : null;
|
||||||
return (
|
return (
|
||||||
<Animatable.View
|
<Animatable.View
|
||||||
style={{
|
style={{
|
||||||
width: size,
|
aspectRatio: 1,
|
||||||
height: size,
|
...this.props.style
|
||||||
}}
|
}}
|
||||||
{...entryAnimation}
|
{...entryAnimation}
|
||||||
>
|
>
|
||||||
|
@ -241,8 +243,8 @@ class Mascot extends React.Component<Props, State> {
|
||||||
<Image
|
<Image
|
||||||
source={MASCOT_IMAGE}
|
source={MASCOT_IMAGE}
|
||||||
style={{
|
style={{
|
||||||
width: size,
|
width: "100%",
|
||||||
height: size,
|
height:"100%",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{this.getEyes(this.state.currentEmotion)}
|
{this.getEyes(this.state.currentEmotion)}
|
||||||
|
|
|
@ -160,7 +160,7 @@ class MascotPopup extends React.Component<Props, State> {
|
||||||
duration={this.props.visible ? 1500 : 200}
|
duration={this.props.visible ? 1500 : 200}
|
||||||
>
|
>
|
||||||
<Mascot
|
<Mascot
|
||||||
size={this.mascotSize}
|
style={{width: this.mascotSize}}
|
||||||
animated={true}
|
animated={true}
|
||||||
emotion={this.props.emotion}
|
emotion={this.props.emotion}
|
||||||
/>
|
/>
|
||||||
|
@ -241,6 +241,7 @@ class MascotPopup extends React.Component<Props, State> {
|
||||||
}}>
|
}}>
|
||||||
<View style={{
|
<View style={{
|
||||||
marginTop: -80,
|
marginTop: -80,
|
||||||
|
width: "100%"
|
||||||
}}>
|
}}>
|
||||||
{this.getMascot()}
|
{this.getMascot()}
|
||||||
{this.getSpeechBubble()}
|
{this.getSpeechBubble()}
|
||||||
|
|
|
@ -146,20 +146,27 @@ export default class CustomIntroSlider extends React.Component<Props, State> {
|
||||||
</View>
|
</View>
|
||||||
<Animatable.View
|
<Animatable.View
|
||||||
animation={"fadeIn"}>
|
animation={"fadeIn"}>
|
||||||
{index !== 0 && index !== this.introSlides.length -1
|
{index !== 0 && index !== this.introSlides.length - 1
|
||||||
? <Animatable.View
|
?
|
||||||
animation={"pulse"}
|
<Mascot
|
||||||
iterationCount={"infinite"}
|
|
||||||
duration={2000}
|
|
||||||
style={{
|
style={{
|
||||||
marginLeft: 30,
|
marginLeft: 30,
|
||||||
marginBottom: 0,
|
marginBottom: 0,
|
||||||
width: 100,
|
width: 100,
|
||||||
marginTop: -30,
|
marginTop: -30,
|
||||||
}}>
|
}}
|
||||||
<Mascot emotion={item.mascotStyle} size={100}/>
|
emotion={item.mascotStyle}
|
||||||
</Animatable.View> : null}
|
animated={true}
|
||||||
|
entryAnimation={{
|
||||||
|
animation: "slideInLeft",
|
||||||
|
duration: 500
|
||||||
|
}}
|
||||||
|
loopAnimation={{
|
||||||
|
animation: "pulse",
|
||||||
|
iterationCount: "infinite",
|
||||||
|
duration: 2000,
|
||||||
|
}}
|
||||||
|
/> : null}
|
||||||
<View style={{
|
<View style={{
|
||||||
marginLeft: 50,
|
marginLeft: 50,
|
||||||
width: 0,
|
width: 0,
|
||||||
|
@ -204,10 +211,11 @@ export default class CustomIntroSlider extends React.Component<Props, State> {
|
||||||
getEndView = () => {
|
getEndView = () => {
|
||||||
return (
|
return (
|
||||||
<View style={{flex: 1}}>
|
<View style={{flex: 1}}>
|
||||||
<View
|
|
||||||
style={styles.center}>
|
|
||||||
<Mascot
|
<Mascot
|
||||||
size={250}
|
style={{
|
||||||
|
...styles.center,
|
||||||
|
height: "80%"
|
||||||
|
}}
|
||||||
emotion={MASCOT_STYLE.COOL}
|
emotion={MASCOT_STYLE.COOL}
|
||||||
animated={true}
|
animated={true}
|
||||||
entryAnimation={{
|
entryAnimation={{
|
||||||
|
@ -221,17 +229,17 @@ export default class CustomIntroSlider extends React.Component<Props, State> {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getWelcomeView = () => {
|
getWelcomeView = () => {
|
||||||
return (
|
return (
|
||||||
<View style={{flex: 1}}>
|
<View style={{flex: 1}}>
|
||||||
<View
|
|
||||||
style={styles.center}>
|
|
||||||
<Mascot
|
<Mascot
|
||||||
size={250}
|
style={{
|
||||||
|
...styles.center,
|
||||||
|
height: "80%"
|
||||||
|
}}
|
||||||
emotion={MASCOT_STYLE.NORMAL}
|
emotion={MASCOT_STYLE.NORMAL}
|
||||||
animated={true}
|
animated={true}
|
||||||
entryAnimation={{
|
entryAnimation={{
|
||||||
|
@ -259,17 +267,14 @@ export default class CustomIntroSlider extends React.Component<Props, State> {
|
||||||
|
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: 210,
|
bottom: 30,
|
||||||
left: 160,
|
right: "20%",
|
||||||
width: 50,
|
width: 50,
|
||||||
height: 50,
|
height: 50,
|
||||||
}}>
|
}}>
|
||||||
<MaterialCommunityIcons
|
<MaterialCommunityIcons
|
||||||
style={{
|
style={{
|
||||||
marginLeft: "auto",
|
...styles.center,
|
||||||
marginRight: "auto",
|
|
||||||
marginTop: "auto",
|
|
||||||
marginBottom: "auto",
|
|
||||||
transform: [{rotateZ: "70deg"}],
|
transform: [{rotateZ: "70deg"}],
|
||||||
}}
|
}}
|
||||||
name={"undo"}
|
name={"undo"}
|
||||||
|
@ -277,7 +282,6 @@ export default class CustomIntroSlider extends React.Component<Props, State> {
|
||||||
size={40}/>
|
size={40}/>
|
||||||
</Animatable.View>
|
</Animatable.View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,5 +407,5 @@ const styles = StyleSheet.create({
|
||||||
marginBottom: 'auto',
|
marginBottom: 'auto',
|
||||||
marginRight: 'auto',
|
marginRight: 'auto',
|
||||||
marginLeft: 'auto',
|
marginLeft: 'auto',
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -117,8 +117,10 @@ function HomeStackComponent(initialRoute: string | null, defaultData: { [key: st
|
||||||
},
|
},
|
||||||
headerTitle: (props) => <View style={{flexDirection: "row"}}>
|
headerTitle: (props) => <View style={{flexDirection: "row"}}>
|
||||||
<Mascot
|
<Mascot
|
||||||
|
style={{
|
||||||
|
width: 50
|
||||||
|
}}
|
||||||
emotion={MASCOT_STYLE.RANDOM}
|
emotion={MASCOT_STYLE.RANDOM}
|
||||||
size={50}
|
|
||||||
animated={true}
|
animated={true}
|
||||||
entryAnimation={{
|
entryAnimation={{
|
||||||
animation: "bounceIn",
|
animation: "bounceIn",
|
||||||
|
|
|
@ -158,9 +158,12 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
<Card style={styles.card}>
|
<Card style={styles.card}>
|
||||||
<Card.Title
|
<Card.Title
|
||||||
title={i18n.t("screens.profile.welcomeTitle", {name: this.data.first_name})}
|
title={i18n.t("screens.profile.welcomeTitle", {name: this.data.first_name})}
|
||||||
left={() => <Mascot
|
left={() =>
|
||||||
|
<Mascot
|
||||||
|
style={{
|
||||||
|
width: 60
|
||||||
|
}}
|
||||||
emotion={MASCOT_STYLE.COOL}
|
emotion={MASCOT_STYLE.COOL}
|
||||||
size={60}
|
|
||||||
animated={true}
|
animated={true}
|
||||||
entryAnimation={{
|
entryAnimation={{
|
||||||
animation: "bounceIn",
|
animation: "bounceIn",
|
||||||
|
|
|
@ -6,7 +6,7 @@ import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
import {Button, Headline, withTheme} from "react-native-paper";
|
import {Button, Headline, withTheme} from "react-native-paper";
|
||||||
import {View} from "react-native";
|
import {View} from "react-native";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import {MASCOT_STYLE} from "../../../components/Mascot/Mascot";
|
import Mascot, {MASCOT_STYLE} from "../../../components/Mascot/Mascot";
|
||||||
import MascotPopup from "../../../components/Mascot/MascotPopup";
|
import MascotPopup from "../../../components/Mascot/MascotPopup";
|
||||||
import AsyncStorageManager from "../../../managers/AsyncStorageManager";
|
import AsyncStorageManager from "../../../managers/AsyncStorageManager";
|
||||||
|
|
||||||
|
@ -36,6 +36,11 @@ class GameStartScreen extends React.Component<Props, State> {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={{flex: 1}}>
|
<View style={{flex: 1}}>
|
||||||
|
<Mascot emotion={MASCOT_STYLE.NORMAL} style={{
|
||||||
|
width: "50%",
|
||||||
|
marginLeft: "auto",
|
||||||
|
marginRight: "auto",
|
||||||
|
}}/>
|
||||||
<Headline style={{textAlign: "center"}}>Coucou</Headline>
|
<Headline style={{textAlign: "center"}}>Coucou</Headline>
|
||||||
<Button
|
<Button
|
||||||
mode={"contained"}
|
mode={"contained"}
|
||||||
|
|
Loading…
Reference in a new issue