Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6212

React Native Animated works only in one way?

$
0
0

I tried to create a text input with floating placeholder on it, changing background, shadows etc. Input has 3 states - when it's empty, when it's not empty and when it's focused.

You can see how these inputs should work on my website (works only on desktops): https://www.treemotion.org/sign-in

Here you can see, how it's working now on my phone: https://www.icloud.com/photos/#0lqAi71mJLyev50Bdz_BmEmfA

Everything is smooth and works well, but when I type something or delete it and blur the input, animation doesn't work - it just "switches" between two states of animation.

TextField.tsx:

import React, { useState } from 'react'import { TextInput, Animated, StyleSheet, View } from 'react-native'const styles = StyleSheet.create({    TextFieldWrapper: {      borderRadius: 4,       position: 'relative',       marginTop: 20,      width: 280,      shadowOffset: { width: 0, height: 0},      shadowColor: '#000000',      shadowRadius: 10,      elevation: 5,    },    TextField: {      width: 280,      paddingTop: 30,      paddingLeft: 10,      paddingRight: 10,      paddingBottom: 10,      fontSize: 18,      fontWeight: 'bold',      borderRadius: 4    },    TextFieldLabel: {      position: 'absolute',      left: 10    }  })const TextField: React.FC<{ secureText: boolean, placeholder: string }> = ({secureText, placeholder}) => {    const [value, setValue] = useState<string>('')    const inputFocusAnimation = new Animated.Value(0)    const inputContentAnimation = new Animated.Value(0)    const emailLabelMarginTop = inputContentAnimation.interpolate({        inputRange: [0, 1],        outputRange: [20, 10]    })    const emailLabelFontSize = inputContentAnimation.interpolate({        inputRange: [0, 1],        outputRange: [18, 14]    })    const textFieldBackground = inputFocusAnimation.interpolate({        inputRange: [0, 1],        outputRange: ['rgba(242,242,242,1)', 'rgba(255,255,255,1)']    })    const textFieldShadow = inputFocusAnimation.interpolate({        inputRange: [0, 1],        outputRange: [0, .2]    })    function handleFocus() {        Animated.timing(            inputFocusAnimation,            {                toValue: 1,                duration: 300            }        ).start()        if(!value) {            Animated.timing(                inputContentAnimation,                {                    toValue: 1,                    duration: 300                }            ).start()        }    }    function handleBlur() {        Animated.timing(            inputFocusAnimation,            {                toValue: 0,                duration: 300            }        ).start()        if(!value) {            Animated.timing(                inputContentAnimation,                {                    toValue: 0,                    duration: 300                }            ).start()        }    }    return (<Animated.View style={{...styles.TextFieldWrapper, backgroundColor: textFieldBackground, shadowOpacity: textFieldShadow}}><TextInput secureTextEntry={secureText} style={styles.TextField} placeholder='' onFocus={() => handleFocus()} onBlur={() => handleBlur()} onChangeText={(e: string) => setValue(e)}></TextInput><Animated.Text style={{...styles.TextFieldLabel, top: emailLabelMarginTop, fontSize: emailLabelFontSize}}>{placeholder}</Animated.Text></Animated.View>    )}export default TextField

I've also tried to "manage" these animations inside useEffect like this:

useEffect(() => {    ...  }, [focus, value])    

But I couldn't make it work well, so I decided to stay with first option. Any ideas?


Viewing all articles
Browse latest Browse all 6212

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>