-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Animation #55
Comments
Animation is in my TODO list. |
Perhaps I could help with it? |
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),
} |
Hello @DUBERT, What is AnimatedImplementation? Thanks! |
It's React-Native's built in Animation library |
@DUBERT Is there any possibility to provide a code example of your solution? Is your approach quite equal to the Svg's |
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. Good luck. Don't know if this will help you. |
Alright - that were my thoughts how you solved this as well @DUBERT. I should probably go ahead with |
can you post the values that you're trying to animate? |
@DUBERT how did you make it to work? |
@flaviotobi do you have your source code on a repo somewhere that I can take a look? |
Thanks for the reply =D This code was tested in iOS, using : Animation working with ART: § Animation not working with SVG: |
Would love also some help here. I am trying to animate a path to create an animated pie chart... But right now I am not able to get the animated to work with it, unless I use a separate setInterval and forceUpdate() which I am sure = bad! So here is what I have right now and hopefully someone can help me a tad with this :) thank you.
|
Were you ever able to get an // var AnimatedCircle = Animated.createAnimatedComponent(Circle); <-- Done before.
<AnimatedCircle cx="250" cy="250" r={this.state.circleRadius} fill="black" /> With the following animation on mount: // this.state.circleRadius = 50 <-- Starting value
Animated.spring(
this.state.circleRadius,
{ toValue: 100, friction: 3 }
).start(); And getting the following error: |
Some SVG elements are animatable but others aren't. SVG is animatable and I think G may be as well but Path isn't.
If you want to do anything more complex then I recommend ART. |
It appears that |
@TheDirtyCalvinist Could you elaborate, please? |
By setting a listener on the animation that calculates a new path and calls |
Hey @TheDirtyCalvinist, how would you interpolate a d path? |
It would depend on the animation you are trying to achieve. |
@TheDirtyCalvinist In my case, I have a piechart and when I highlight a slice, the radius gets bigger, so I'd like to animate the path and make it grow smoothly. At this point, I am not sure, if the best approach is to animate the path or even the radius. |
@edo1493, I figured out how to make animations work. The process of generating the intermediate paths is called tweening and there is actually a library that lets you do it given two paths: art (https://www.npmjs.com/package/art). I adapted the code from this demo: https://medium.com/the-react-native-log/animated-charts-in-react-native-using-d3-and-art-21cd9ccf6c58 |
@keksipurkki I don't use ART, cause it doesn't support click events. ;) |
@edo1493, Yeah, but take a look at the code, it uses react native SVG for rendering and ART for tweening. I have implemented a clickable SVG pie chart ;-P AFAIK, the tweening functionality could be incorporated into react native svg. It's pure computation with no dependencies on a particular DOM implementation. |
@keksipurkki Yes, I know that blog post really well. I just re-adapted the whole thing without ART. I am using the onClick events to highlight the slice and make it bigger, it would be nice to have an Animation when the slice gets bigger. |
@edo1493 See my edited comment above. |
I tried the tweening too in the past couple of months, but it was breaking things for me. Adding an eventListener as @TheDirtyCalvinist was mentioning (also here: http://stackoverflow.com/questions/39094349/how-to-make-svg-animation-with-animated-in-react-native) seemed a smoother solution. However, I am not sure how to interpolate my next path, which I am getting from componentWillReceiveProps. |
@edo1493 Yup. For me the problem is currently that orientation change screws up the chart. |
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 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: And this is being rendered on a very complex component where using |
I try keksipurkki's solution, it works well. |
I am trying to animate a slice of a piechart, in this way:
Do you guys have any tips? Nothing is moving here. I just want a smooth animation when a new path comes in. I have chosen spring with some friction, just to give it a go, it's not the animation that I want. If I can animate it in any way first, it would be great. |
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 |
It'd be nice if the information found in this issue was transformed into documentation. I have not found any other documentation regarding how to animate SVG parts. In someone is looking at interpolating colours, I've managed to make it work. Here is a snippet which is has to be mixed with the examples found above: import extractProps from 'react-native-svg/lib/extract/extractProps';
...
const colour = new Animated.Value(0);
colour.addListener(v => {
const c = colour.interpolate({
inputRange: [0, 1],
outputRange: ['black', 'red']
});
// Make sure that the ref was acquired.
if (this.myRef) {
// Convert the interpolation to a value, and assign to prop name.
const props = {
fill: c.__getValue()
}
// Conver the properties to native properties.
const nativeProps = extractProps(props, this.myRef);
// Finally send the properties to the object.
this.myRef.setNativeProps(nativeProps);
}
}); As @ethantran mentioned, some props need to be converted to their native equivalents. However, a colour interpolation first needs to be converted to a value or the |
@ethantran Well done! Very Nice! 👏👏👏 I didn't even know using D3 was doable. Will be using your examples for sure. 🤜🤛 |
@FMCorz Thanks for the inspiration. This can be even easier if you just want to set the fill-color:
and rendering:
|
@ethantran Hi I am new to react native and I'm trying to build This Example in react native. Basically it's a line chart with real-time data. Would you mind sharing some thoughts? Much appreciated! |
@DUBERT how do we animate a pie chart so that each pie of the chart renders in a circular way. |
Study this library and try it out https://github.com/JesperLekland/react-native-svg-charts |
Have tried these too. Actually I also need the pies to be touchable. Using it caused a lot of bugs while integrating touchables though the docs support that the library has it. |
Wrapping the path component in a new class will help us achieve functionality for adding a delay for successive mappings.. I did so to animate my pie chart such that each of its pie are visible one after the other after a delay. Thanks for all the help I got from here. :-) |
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?
The text was updated successfully, but these errors were encountered: