我试图创建一个带有浮动占位符,更改背景,阴影等的文本输入。输入具有3种状态-空时,不空时以及焦点对准时。
您可以看到这些输入如何在我的网站上工作(仅在台式机上工作):https://www.treemotion.org/sign-in
您可以在这里通过https://www.icloud.com/photos/#0lqAi71mJLyev50Bdz_BmEmfA
在手机上查看它的工作方式。一切都很流畅,而且效果很好,但是当我键入某些内容或将其删除并模糊输入时,动画将不起作用-只能在两种动画状态之间“切换”。
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
我还试图像这样在useEffect中“管理”这些动画:
useEffect(() => {
...
}, [focus, value])
但是我无法使其正常工作,所以我决定保留第一选择。有什么想法吗?