4

I have an Animated.View in React Native which I am animating the width of.

const pollRef = useRef(new Animated.Value(0)).current;

const resultWidth = ((votes/totalVotes)*100).toFixed(0)  // GET A PERCENTAGE VALUE

const AnimateResult = () => {
    Animated.timing(pollRef, {
        toValue: resultWidth,
        duration: 3000,
        useNativeDriver: false
    }).start();
};

useEffect(() => {
    AnimateResult()
},[])

<Animated.View 
    style={{
        position: 'absolute',
        top: 0,
        left: 0,
        height: '100%',
        width: pollRef,
        backgroundColor: '#155A8B',
    }}
/>

The value of resultWidth (and therefore pollRef) is 100. The width of the element is animating fine, apart from it's correctly treating the 100 as an absolute value and animating the width to 100 pixels, whereas I would like to express it as a percentage. Whatever syntax I use in the style object I can't seem to do it.

I have tried things like:

style={{
    ...
    width: "'"+pollRef+"%'"
    ...
}}

and

style={{
    ...
    width: `${pollRef}%`,
    ...
}}

But neither worked. I have also noticed that there seems to be whitespace around the variable - if I console log:

console.log('pollRef:',pollRef,'X')

the output is:

pollRef: 0 X

which may make adding a percentage sign to the end a little more difficult.

Any help very much appreciated.

Ray Purchase
  • 681
  • 1
  • 11
  • 37
  • If you are using `react-native-reanimated` library which I highly recommend to use, changing your static types to `useSharedValue` will resolve your issue with the animation and you have more flexibility while trying to work around animations – Emad Baqeri Apr 14 '22 at 06:29
  • 1
    Two things: If you concatenate in console.log() with commas, then whitespaces are automatically inserted between each argument. If your input is sensitive to that, use + instead. Second: You shouldn't use the extra single quotation marks. The variable is already a string after adding "%". – Fabian Sievert Apr 14 '22 at 11:13

2 Answers2

8

I think https://stackoverflow.com/a/48741068/12637199 answers your question.

You need to use interpolate to transform numbers to strings.

You can just have:

const animation = new Animated.Value(0);
const inputRange = [0, 100];
const outputRange = ["0%", "100%"]

const animatedWidth = animation.interpolate({inputRange, outputRange});

And then use it like this:

width: animatedWidth,
lmasneri
  • 589
  • 7
  • 17
0
const handlePress=()=>{
        Animated.parallel([
            Animated.timing(current, {
                toValue:1,
                duration:400,
                useNativeDriver:false,
            }),
        Animated.timing(progress, {
            toValue:index+1,
            duration:400,
            useNativeDriver:false
        })
        ]).start(()=>{
            setIndex(index+1);
            current.setValue(0);

            if(index+1>=5){
                setTimeout(()=>{
                    setRunning(0)
                }, 500)
            }

        })
}
const {width} = Dimensions.get("window");
const currentAnim=current.interpolate({
    inputRange:[0, 1],
    outputRange:[0, -width]
});

const nextAnim=current.interpolate({
    inputRange:[0, 1],
    outputRange:[width, 0]
});

const progressAnim=progress.interpolate({
    inputRange:[0, questions.length],
    outputRange:["20%", "100%"],
});

const barWidth={
    width:progressAnim
}

const translate={
    transform:[
        {translateX:currentAnim}
    ]
}
const translateNext={
    transform:[
        {translateX:nextAnim}
    ]
}
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 14 '22 at 07:25