Animation

Thanks for the great component!

I’m trying to implement some animation with my SVGs. I can’t get the built in library to work. I’ve been playing with react-motion and that kind of works, but the looping is messy and I don’t only want to do springs.

Any ideas?

7 thoughts on “Animation

  1. Hey, no worries. I got it working by doing this:

    import AnimatedImplementation from 'AnimatedImplementation'
    
    import Svg, {
      G,
      Path,
    } from 'react-native-svg'
    
    const A = {
      Svg: AnimatedImplementation.createAnimatedComponent(Svg),
      G: AnimatedImplementation.createAnimatedComponent(G),
      Path: AnimatedImplementation.createAnimatedComponent(Path),
    }
  2. No @Druux , I’m following the React Native animated syntax. Here is an example from my app:

    (I pulled out a lot of excess code that isn’t related to the animation)

    import React, { Component } from 'react'
    import {
      View,
    } from 'react-native'
    import RNAnimated from 'Animated'
    import AnimatedImplementation from 'AnimatedImplementation'
    
    import Svg, {
      G,
      Path,
    } from 'react-native-svg'
    
    const Animated = {
      ...RNAnimated,
      G: AnimatedImplementation.createAnimatedComponent(G),
    }
    
    
    export default class Example extends Component {
    
      constructor(props) {
        super(props)
    
        this.state = {
          B1: new Animated.Value(0),
        }
      }
    
      componentDidMount() {
        this.runAnimation()
      }
    
      runAnimation() {
        Animated.stagger(50, [
    
          this.timing('B1'),
    
        ]).start()
    
        // I had more here but just cut them out
    
      }
    
      timing(id) {
        return Animated.sequence([
          Animated.timing(
            this.state[id],
            { toValue: 1, duration: 150 }
          ),
          Animated.timing(
            this.state[id],
            { toValue: 0, duration: 150 }
          )
        ])
      }
    
      interp(id, value) {
        return this.state[id].interpolate({
          inputRange: [0, 1],
          outputRange: value,
        })
      }
    
      render() {
    
        return (
          <Svg
            height={191}
            width={259}
          >
            <Animated.G
              originX={20}
              y={this.interp('B1', [0, -12])}
              x={this.interp('B1', [0, 2])}
              scaleX={this.interp('B1', [1, .85])}
            >
              <Path d='M36.9 23.6c0-4.07-1.32-7.34-4-9.8-2.7-2.5-6.24-3.75-10.6-3.75H1.74v57.9l18.58-.02c6.3 0 11.3-1.5 15-4.48 3.67-3 5.5-7.06 5.5-12.15 0-4.15-1.12-7.43-3.38-9.84l-.42-.42c-2.27-2.15-5.55-3.55-9.84-4.2 3.27-1.34 5.72-3.13 7.36-5.34 1.6-2.22 2.4-4.85 2.4-7.9zm-21.68 8.7v-11h2.52c1.85 0 3.24.43 4.16 1.28.9.84 1.37 2.1 1.37 3.77 0 1.86-.58 3.3-1.73 4.37-1.2 1.06-2.8 1.6-4.82 1.6h-1.5zm0 10.75h4.34c2.14 0 3.92.6 5.36 1.85 1.43 1.22 2.15 2.85 2.15 4.9 0 2-.7 3.64-2.1 4.9-1.43 1.25-3.23 1.87-5.4 1.87H15.2V43.05z'/>
            </Animated.G>
    
          </Svg>
    
        )
      }
    }

    Disclaimer: I’m sure this isn’t the best way to do this. But it worked for me.
    I set up my own interpolate function so that I could pass the two values into the render. I also used IDs because I had 20 different animations going.

    Good luck. Don’t know if this will help you.

  3. By setting a listener on the animation that calculates a new path and calls this.pathComponent.setNativeProps({ d });, some semblance of an animation can be had. The Path component does not need to be wrapped in Animated.

  4. Hey All, I just wanted to follow up from my comment before.

    I did a bit more tinkering and found a very workable solution using addListener and setNativeProps. A little messy but works none-the-less and is quite performant.

    Here’s a simplified version of the solution:

    constructor(props) {
      super(props);
      
      this.state = { circleRadius: new Animated.Value(50) };
    
      this.state.circleRadius.addListener( (circleRadius) => {
        this._myCircle.setNativeProps({ r: circleRadius.value.toString() });
      });
    
      setTimeout( () => {
        Animated.spring( this.state.circleRadius, { toValue: 100, friction: 3 } ).start();
      }, 2000)
    }
    
    render() {
      return(
        <Svg height="400" width="400">
          <AnimatedCircle ref={ ref => this._myCircle = ref } cx="250" cy="250" r="50" fill="black" />
        </Svg>
      )
    }

    And the resulting animation:

    circle animation with setnativeprops

    And this is being rendered on a very complex component where using setState isn’t fluid at all.

  5. Hey guys, I managed to figure out how to animate almost every component and their props with setNativeProps. The key is to format the value correctly and I had to look at the code in https://github.com/react-native-community/react-native-svg/tree/master/lib/extract to get it right. All of the transform props had to be converted into a matrix for example. For path data, I used D3 to create paths and interpolate paths. You can see it in action at https://exp.host/@ethantran2/react-native-examples and find the messy but good enough code at https://github.com/ethantran/react-native-examples

Animation

Thanks for the great component!

I’m trying to implement some animation with my SVGs. I can’t get the built in library to work. I’ve been playing with react-motion and that kind of works, but the looping is messy and I don’t only want to do springs.

Any ideas?

6 thoughts on “Animation

  1. By setting a listener on the animation that calculates a new path and calls this.pathComponent.setNativeProps({ d });, some semblance of an animation can be had. The Path component does not need to be wrapped in Animated.

  2. Hey All, I just wanted to follow up from my comment before.

    I did a bit more tinkering and found a very workable solution using addListener and setNativeProps. A little messy but works none-the-less and is quite performant.

    Here’s a simplified version of the solution:

    constructor(props) {
      super(props);
      
      this.state = { circleRadius: new Animated.Value(50) };
    
      this.state.circleRadius.addListener( (circleRadius) => {
        this._myCircle.setNativeProps({ r: circleRadius.value.toString() });
      });
    
      setTimeout( () => {
        Animated.spring( this.state.circleRadius, { toValue: 100, friction: 3 } ).start();
      }, 2000)
    }
    
    render() {
      return(
        <Svg height="400" width="400">
          <AnimatedCircle ref={ ref => this._myCircle = ref } cx="250" cy="250" r="50" fill="black" />
        </Svg>
      )
    }

    And the resulting animation:

    circle animation with setnativeprops

    And this is being rendered on a very complex component where using setState isn’t fluid at all.

  3. Hey guys, I managed to figure out how to animate almost every component and their props with setNativeProps. The key is to format the value correctly and I had to look at the code in https://github.com/react-native-community/react-native-svg/tree/master/lib/extract to get it right. All of the transform props had to be converted into a matrix for example. For path data, I used D3 to create paths and interpolate paths. You can see it in action at https://exp.host/@ethantran2/react-native-examples and find the messy but good enough code at https://github.com/ethantran/react-native-examples