Проблемы с цветом оттенка React native

#javascript #reactjs #react-native #expo #react-animated

Вопрос:

Я очень новичок в родной реакции и столкнулся с проблемой, которая возникает, когда я хочу анимировать цвет оттенка изображения. Я ожидаю, что цвет будет постепенно меняться с течением времени, как анимированный.Время должно быть выбрано, но вместо этого он делает только первый кадр анимации, а затем зависает. Однако по какой-то причине, когда я просто меняю «Цвет оттенка» на «Цвет фона», анимация работает нормально.

Вот мой код:

 import React from 'react';
import { useState } from 'react';
import { Text, View, TouchableHighlight, Dimensions, Component, Image, Animated } from 'react-native';
import PropTypes from 'prop-types';

function RGBtoCSS(rgb) {
    return "rgb("   rgb[0]   ","   rgb[1]   ","   rgb[2]   ")";
}

class MyImage extends React.Component {
    constructor(props) {
        super(props);
        this.anim = new Animated.Value(0);
        this.animate();
    }

    animate() {
        this.props.onPress();

        Animated.timing(
            this.anim,
            {
                toValue: 1,
                duration: 500,
                useNativeDriver: false
            }
        ).start();
    }

    render() {
        var style = {
            width: 500,
            height: 500,
            resizeMode: 'stretch'
        };

        var col = this.anim.interpolate(
        {
            inputRange: [0, 1],
            outputRange: [RGBtoCSS([0, 0, 0]), RGBtoCSS([140, 74, 140])]
        });

        return (
            <Animated.Image source={this.props.img} style={{ ...style, tintColor: col }} />
        );
    }
}
MyImage.propTypes = { img: PropTypes.string.isRequired, onPress: PropTypes.func.isRequired, spacing: PropTypes.number.isRequired };

export default function App() {
    return (
        <View style={{
            flex: 1,
            backgroundColor: RGBtoCSS([255, 255, 255])
        }}>
            <MyImage img={{ uri: 'https://img.icons8.com/color/452/google-logo.png' }} onPress={() => { }} spacing={0} />
        </View>
    );
}
 

(демо доступно по адресу https://snack.expo.dev/v0GeiLbOP)

Комментарии:

1. Похоже tintColor , это не поддается оживлению.

2. есть ли оживляемая альтернатива?

3. вы пытались зарегистрировать RGBtoCSS функцию, чтобы увидеть, какие значения вычисляются? Возможно, interpolate это не очень хорошо работает с вашей функцией.

4. это прекрасно работает с фоновым цветом, так что я не думаю, что в этом проблема

5. и я уже пробовал это

Ответ №1:

Я нашел обходной путь для этого. Вы можете сложить два <Animated.Image> изображения друг на друга, причем 1-е изображение имеет окончательный цвет, а 2-е изображение-начальный цвет. Затем вы можете использовать opacity для создания эффекта затухания между этими двумя изображениями, который также хорошо работает interpolate .

 import React from 'react';
import { useState } from 'react';
import { Text, View, TouchableHighlight, Dimensions, Component, Image, Animated } from 'react-native';
import PropTypes from 'prop-types';

function RGBtoCSS(rgb) {
    return "rgb("   rgb[0]   ","   rgb[1]   ","   rgb[2]  ")";
}

class MyImage extends React.Component {
    constructor(props) {
        super(props);
        this.anim = new Animated.Value(0);
        this.animate();
    }

    animate() {
        this.props.onPress();
        console.log(this.anim)

        Animated.timing(
            this.anim,
            {
                toValue: 1,
                duration: 500,
                useNativeDriver: false
            }
        ).start();
    }

    render() {
        var style = {
            width: 500,
            height: 500,
            resizeMode: 'stretch'
        };

        var col = this.anim.interpolate(
        {
            inputRange: [0, 1], 
            outputRange: [1, 0]
        });


    
        return (
          <View>
            <Animated.Image source={this.props.img} style={{ ...style,tintColor: RGBtoCSS([140, 74, 140]) }} />
            <Animated.Image source={this.props.img} style={{ ...style, opacity:col, transform:[{translateY:"-100%"}],  tintColor: RGBtoCSS([0, 0, 0]) }} />
            </View>
        );
    }

}
MyImage.propTypes = { img: PropTypes.string.isRequired, onPress: PropTypes.func.isRequired, spacing: PropTypes.number.isRequired };

export default function App() {
    return (
        <View style={{
            flex: 1,
            backgroundColor: RGBtoCSS([255, 255, 255])
        }}>
            <MyImage img={{ uri: 'https://img.icons8.com/color/452/google-logo.png' }} onPress={() => { }} spacing={0} />
        </View>
    );
}
 

Закуска — https://snack.expo.dev/ZYulbKh3g