1

I don't know more about react-native animation. I read about these questions

react native circle transform translate animation

Circling motion animation in React Native

but I don't find any solution that works with the image.

example that I wan't to create in my mobile application

enter image description here

Please help me to create this type of animation.

Mitesh K
  • 694
  • 1
  • 11
  • 24

2 Answers2

3

You can use react-native-circular-progress You pass a children(fill) function as a child. It allows you to render any children's components within the circular progress.

Here is an example:

<AnimatedCircularProgress
  size={200}
  width={3}
  fill={this.state.fill}
  tintColor="#00e0ff"
  backgroundColor="#3d5875">
  {
    (fill) => (
      <Image source={...} style={...} />
    )
  }
</AnimatedCircularProgress>
Nooruddin Lakhani
  • 7,507
  • 2
  • 19
  • 39
2

Using react-native-svg and react-native-animated, this is a circular-progressive bar, counting from 1 to 100. You can remove the part of the code with the Text-component and use the Image-component. This should work for whatever use case you're considering. However, this is a typescript-code; but would fit for javascript codebases as well. Just know what to edit.

import React, { useEffect, useRef, useState } from 'react'
import { StyleSheet, Text, View, Dimensions, Animated } from 'react-native'

import Svg, { Circle } from "react-native-svg";
import colors from '../assets/colors';

const CIRCULAR_CIRCUMFERENCE = 270;
const CIRCLE_RADIUS = String(CIRCULAR_CIRCUMFERENCE/(2*Math.PI));

interface Props {
    
};

const AnimatedCircle = Animated.createAnimatedComponent(Circle);
const CircularProgressBar = (props: Props) => {
    const { width, height } = Dimensions.get("window");
    const stringifiedWidth = String(width/7); 
    const stringifiedHeight = String(height/20); 
    const [progressValue, setProgressValue] = useState(0)

   
    const progress = new Animated.Value(1);
    useEffect(() => {
        Animated.timing(progress, {
            useNativeDriver: true,
            toValue: 0,
            duration: 2000,
            delay: 200
        }).start();
        
        // The addlistener method is used here, so as to access the animation value as it counts to its stopValue: the toValue
        progress.addListener(e => setProgressValue(e.value));

        setTimeout(() => {
            progress.removeAllListeners();
        }, 40000)
    }, []);
            
    const animatedProps = (() => ({
        strokeDashoffset: CIRCULAR_CIRCUMFERENCE*progressValue
    }));
    
    return (
        <Animated.View style={styles.container}>
            <Text style={styles.counterStyle}>
                {`${Math.floor(-1*((progressValue*100)-100))}%`}
            </Text>
            <Svg style={{position: "absolute"}} height={450} width={250} viewBox="0 0 100 100">
                <Circle 
                    cx={stringifiedWidth}
                    cy={stringifiedHeight}
                    r={CIRCLE_RADIUS}
                    stroke={colors.secondary}
                    strokeWidth={10}
                />
                <AnimatedCircle 
                    cx={stringifiedWidth}
                    cy={stringifiedHeight}
                    r={CIRCLE_RADIUS}
                    stroke={colors.strokeColor}
                    strokeWidth={5}
                    strokeDasharray={CIRCULAR_CIRCUMFERENCE}
                    strokeLinecap="round"
                    {...animatedProps()}
                />
            </Svg>
        </Animated.View>
    );
};


const styles = StyleSheet.create({
    container: {
        justifyContent: "center", 
        alignItems: "center", 
        position: "absolute", 
        marginTop: 200
    },
    counterStyle: {
        textAlign: "center", 
        fontWeight: "bold", 
        fontSize: 30, 
        marginBottom: 60
    }
});

export default CircularProgressBar;

Chukwunazaekpere
  • 906
  • 1
  • 6
  • 13