I'm attempting to animate the fill color of some custom paths. Doing so via normal props isn't performant enough, so I'm trying to use requestAnimationFrame and setNativeProps
this.state.fillColor = this.state.opacityAnim.interpolate({
inputRange: [0, 0.20, 0.40, 0.80, 1],
outputRange: ['rgb(147, 189, 186)', 'rgb(235, 154, 64)', 'rgb(226, 117, 58)', 'rgb(220, 85, 52)', 'rgb(220, 85, 52)'],
})
I have this interpolation running nicely, and I can do this without error (but it's too slow):
<Svg>
<Path
ref={c => this._path = c}
d={pos.path}
fill={this.state.fillColor.__getAnimatedValue()}
/>
</Svg>
What I can't do however is this. This fails:
animate() {
requestAnimationFrame(() => {
if (this._path && this.state.fillColor) {
this._path.setNativeProps({
fill: this.state.fillColor.__getAnimatedValue(),
})
}
this.animate()
})
}
I'm getting this error:

2017-05-03 13:00:59.789 [error][tid:main][RCTConvert.m:56] Error setting property 'fill' of RNSVGPath with tag #1223: JSON value 'rgba(147, 189, 186, 1)' of type NSString cannot be converted to NSArray
2017-05-03 13:00:59.792 [error][tid:main][RCTConvert+RNSVG.m:102] Error setting property 'fill' of RNSVGPath with tag #1223: Too few elements in array (expected at least 5): (null)
What might I be doing wrong? Is it possible to do this?
I also attemped to not use the __getAnimatedValue() and change the <Path/> to <AnimatedPath/> with const AnimatedPath = Animated.createAnimatedComponent(Path) but then I get this error:

I've seen some examples of people animating the path using setNativeProps, but not the fill color.
Any advice greatly appreciated, thanks!
You have to use extractBrush in lib/extract to animate the fill.
setNativeProps = (props) => {
props.propList = getPropList(props, this.prevProps);
if (props.fill) {
props.fill = extractBrush(props.fill);
}
if (props.stroke) {
props.stroke = extractBrush(props.stroke);
}
this._component && this._component.setNativeProps(props);
}
I provide more examples at #55
Hey, I had success with this thanks to @ethantran's examples. Here's a full example.
```Logo.js
import React, { PureComponent } from 'react';
import { Animated } from 'react-native';
import PropTypes from 'prop-types';
import Svg, { Path } from 'react-native-svg';
import extractBrush from 'react-native-svg/lib/extract/extractBrush';
export default class extends PureComponent {
static propTypes = {
fill: PropTypes.string,
path: PropTypes.string.isRequired,
};
static defaultProps = {
fill: 'rgba(0, 33, 71, 1)',
};
constructor(props) {
super(props);
this.lastFill = this.props.fill;
this.state = {
fillValue: new Animated.Value(0),
};
this.state.fillValue.addListener(() => {
const { fill } = this.props;
const { fillValue } = this.state;
const color = fillValue.interpolate({
inputRange: [0, 1],
outputRange: [this.lastFill, fill],
});
this.path.setNativeProps({
fill: extractBrush(color.__getAnimatedValue()),
});
});
}
animate = () => {
const { fillValue } = this.state;
Animated.timing(fillValue, {
toValue: 1,
duration: 350,
}).start(({ finished }) => {
if (finished) {
this.lastFill = this.props.fill;
this.state.fillValue.setValue(0);
}
});
};
componentDidMount() {
this.animate();
}
componentDidUpdate() {
this.animate();
}
render() {
return (
ref={ref => (this.path = ref)}
fill={this.state.lastFill}
/>
);
}
}
```
I wish I had looked for this issue before, I just posted my solution on #55. I used __getValue().
Most helpful comment
Hey, I had success with this thanks to @ethantran's examples. Here's a full example.
```Logo.js
import React, { PureComponent } from 'react';
import { Animated } from 'react-native';
import PropTypes from 'prop-types';
import Svg, { Path } from 'react-native-svg';
import extractBrush from 'react-native-svg/lib/extract/extractBrush';
export default class extends PureComponent {
static propTypes = {
fill: PropTypes.string,
path: PropTypes.string.isRequired,
};
static defaultProps = {
fill: 'rgba(0, 33, 71, 1)',
};
constructor(props) {
super(props);
this.lastFill = this.props.fill;
}
animate = () => {
const { fillValue } = this.state;
Animated.timing(fillValue, {
toValue: 1,
duration: 350,
}).start(({ finished }) => {
if (finished) {
this.lastFill = this.props.fill;
this.state.fillValue.setValue(0);
}
});
};
componentDidMount() {
this.animate();
}
componentDidUpdate() {
this.animate();
}
render() {
d={this.props.path}
return (
ref={ref => (this.path = ref)}
fill={this.state.lastFill}
/>
);
}
}
```