如何解决react-native从背景色a到b的渐变
当点击按钮时,颜色应该随着滑动动画逐渐过渡到另一种颜色。而不是立即逐渐过渡颜色切换。有什么办法可以让这个动画从颜色 a 到 b 缓慢执行?
这是我目前的代码
const DriveMenuFooteranimatedButton = () => {
const {t} = useTranslation();
const {colors} = useContext(ThemeContext);
const buttonStyle = replaceAllStyles(style,colors);
const scaledButtonWidth = scale(BUTTON_WIDTH);
const opacityAnimation = useRef(new Animated.Value(0)).current;
const translateAnimation = useRef(new Animated.Value(scaledButtonWidth * -1)).current;
const colorAnimation = useRef(new Animated.Value(0)).current;
const colorAnimationInterpolation = colorAnimation.interpolate({
inputRange: [0,300],outputRange: ["#00AA91","#0A0082"]
});
const {setTrainDriveState,trainDriveState} = useContext(TrainStateContext);
const restartLabel = t("drive:menu:restart");
const pauseLabel = t("drive:menu:pause");
const startLabel = t("drive:menu:start");
console.log("trainDriveState",trainDriveState);
const onPressHandler = useCallback(
() => {
const isPlay = trainDriveState === paused || trainDriveState === start;
setTrainDriveState(isPlay ? play : paused);
},[setTrainDriveState,trainDriveState]
);
useEffect(() => {
let translateValue = scaledButtonWidth * -1;
let colorValue = 0;
if (trainDriveState === paused){
translateValue = scaledButtonWidth;
} else if (trainDriveState === play){
translateValue = 0;
colorValue = 300;
}
Animated.parallel([
Animated.timing(colorAnimation,{
tovalue: colorValue,duration: ANIMATION_DURATION,delay: 0,useNativeDriver:false
}),Animated.timing(translateAnimation,{
tovalue: translateValue,easing: Easing.inOut(Easing.ease),useNativeDriver:true
})
]).start();
return () => {
};
},[translateAnimation,trainDriveState,scaledButtonWidth,colorAnimation,opacityAnimation]);
return (
<Animated.View
style={[buttonStyle["animation-container"],{backgroundColor: colorAnimationInterpolation}]}
>
<DigiPlanButton
onPress={onPressHandler}
activeOpacity={1}
customStyle={style}
>
<Animated.View
style={[
buttonStyle["text-animation-container"],{transform: [{translateX: translateAnimation}]}
]}
>
<DigiPlanText customStyle={buttonStyle["button-text"]}>{restartLabel}</DigiPlanText>
<DigiPlanText customStyle={buttonStyle["button-text"]}>{pauseLabel}</DigiPlanText>
<DigiPlanText customStyle={buttonStyle["button-text"]}>{startLabel}</DigiPlanText>
</Animated.View>
</DigiPlanButton>
</Animated.View>
);
};
const style = {
"button-touchable": {
width: scale(BUTTON_WIDTH),paddingHorizontal: 0,overflow: "hidden",backgroundColor: "transparent"
},"text-animation-container": {
display:"flex",flexDirection: "row",textAlign: "center"
},"animation-container": {
borderRadius: 4
},"button-text": {
width: "100%",backgroundColor: "transparent",fontSize: "font-size-l",textAlign: "center",color: "primary-light"
}
};
export default DriveMenuFooteranimatedButton;
解决方法
对于那些面临类似问题的人,我设法找出了以下解决方案
(在 youtube 上用他的滑块视频向 youtube 上的 William Candillon 提供道具)
....
const AnimatedButton = () => {
const { colors } = useContext(ThemeContext);
const mainStyle = replaceAllStyles(styles,colors);
const {t} = useTranslation();
const {setTrainDriveState,trainDriveState} = useContext(TrainStateContext);
// annimation vals
const scrollViewRef = useRef();
const x = useValue(0);
const onScroll = onScrollEvent({ x });
const backgroundColor = interpolateColor(x,{
inputRange: [0,BUTTON_WIDTH,BUTTON_WIDTH * 2],outputRange: [ "#0A0082","#0A0082","#00AA91"]
});
// button labels
const restartLabel = t("drive:menu:restart");
const pauseLabel = t("drive:menu:pause");
const startLabel = t("drive:menu:start");
// scroll to label corresponding to trainDriveState
useEffect(() => {
if (scrollViewRef.current && scrollViewRef.current.getNode){
const node = scrollViewRef.current.getNode();
let labelPosition;
if (node){
if (trainDriveState === paused){
labelPosition = BUTTON_WIDTH * 2;
} else if (trainDriveState === play){
labelPosition = BUTTON_WIDTH;
} else if (trainDriveState === start){
labelPosition = 0;
}
node.scrollTo({x: labelPosition,animated: true});
}
}
},[scrollViewRef,trainDriveState]);
const handlePress = useCallback(
() => {
const isPlay = trainDriveState === paused || trainDriveState === start;
setTrainDriveState(isPlay ? play : paused);
},[setTrainDriveState,trainDriveState],);
return (
<TouchableOpacity style={mainStyle.container} onPress={handlePress} activeOpacity={1} >
<Animated.View style={[mainStyle.slider,{backgroundColor} ]}>
<Animated.ScrollView
ref={scrollViewRef}
horizontal
snapToInterval={BUTTON_WIDTH}
decelerationRate="fast"
showsHorizontalScrollIndicator={false}
scrollEventThrottle={1}
scrollToOverflowEnabled={true}
scrollEnabled={false}
// bounces={false}
{...{onScroll}}
>
<Slide label={startLabel}/>
<Slide label={pauseLabel}/>
<Slide label={restartLabel}/>
</Animated.ScrollView>
</Animated.View>
</TouchableOpacity>
);
};
const styles = {
container: {
height: BUTTON_HEIGHT,width: BUTTON_WIDTH
},slider: {
height: BUTTON_HEIGHT,width: BUTTON_WIDTH,borderRadius: scale(4)
}
};
export default AnimatedButton;
...
export const BUTTON_WIDTH = scale(272);
export const BUTTON_HEIGHT = verticalScale(48);
const Slide = ({label}) => {
return (
<View style={styles.container}>
<DigiPlanText customStyle={styles.label}>{label}</DigiPlanText>
</View>
);
};
const styles = {
container: {
borderRadius: scale(4),height: BUTTON_HEIGHT,display: "flex",alignItems: "center",justifyContent: "center"
},label: {
textAlign: "center",fontSize: "font-size-l",color: "primary-light"
}
};
export default Slide;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。