微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

react-native从背景色a到b的渐变

如何解决react-native从背景色a到b的渐变

当点击按钮时,颜色应该随着滑动动画逐渐过渡到另一种颜色。而不是立即逐渐过渡颜色切换。有什么办法可以让这个动画从颜色 a 到 b 缓慢执行?

enter image description here

这是我目前的代码


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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?