[Rect] width not being animated via createAnimatedComponent and interpolate
See original GitHub issueI have simple animation interpolation going on for <Rect />
element, however I see no changes on my ui, as if width is staying 0.
I manually added my end value to the component as width={149.12}
and it displayed it correctly, hence I am a bit confused now to why it is not picking up same value from animation?
react-native@0.57.1 react-native-svg@7.0.3 iOS
Here is full implementation, in essence a mana and health bar that take in current value and total value i.e. 50 and 100 should display half width for the rect. (Example uses typescript)
import * as React from 'react'
import { Animated } from 'react-native'
import Svg, { Defs, LinearGradient, Rect, Stop } from 'react-native-svg'
import { deviceWidth } from '../services/Device'
const barWidth = deviceWidth * 0.3454
const barHeight = barWidth * 0.093
const AnimatedRect = Animated.createAnimatedComponent(Rect)
/**
* Types
*/
export interface IProps {
variant: 'MANA' | 'HEALTH'
currentValue: number
totalValue: number
}
export interface IState {
width: Animated.Value
}
/**
* Component
*/
class HealthManaBar extends React.Component<IProps, IState> {
state = {
width: new Animated.Value(0)
}
rectangleRef = React.createRef()
componentDidMount() {
const { currentValue, totalValue } = this.props
this.animate(currentValue, totalValue)
}
componentDidUpdate({ currentValue, totalValue }: IProps) {
this.animate(currentValue, totalValue)
}
animate = (current: number, total: number) =>
Animated.timing(this.state.width, {
toValue: current !== 0 ? current / total : 0,
duration: 400,
useNativeDriver: false
}).start()
render() {
const { variant } = this.props
const { width } = this.state
return (
<Svg width={barWidth} height={barHeight}>
<Defs>
<LinearGradient
id={`HeathManaBar-gradient-${variant}`}
x1="0"
y1="0"
x2="0"
y2={barHeight}
>
<Stop
offset="0"
stopColor={variant === 'HEALTH' ? '#EC561B' : '#00ACE1'}
stopOpacity="1"
/>
<Stop
offset="0.5"
stopColor={variant === 'HEALTH' ? '#8D1B00' : '#003FAA'}
stopOpacity="1"
/>
<Stop
offset="1"
stopColor={variant === 'HEALTH' ? '#9F3606' : '#007C97'}
stopOpacity="1"
/>
</LinearGradient>
</Defs>
<AnimatedRect
x="0"
y="0"
rx="3"
ry="3"
width={width.interpolate({
inputRange: [0, 1],
outputRange: [0, barWidth]
})}
height={barHeight}
fill={`url(#HeathManaBar-gradient-${variant})`}
/>
</Svg>
)
}
}
export default HealthManaBar
NOTE: this is based on following example https://github.com/msand/SVGPodTest/blob/a74a600818e496efaa78298291b63107295064bf/App.js#L14-L57
Only difference I see is that it uses strings '0'
and '50'
, which I also tried, but got react native error saying that NSString can't be converted to Yoga Value
. However, when I pass width to my <Rect />
as an integer it works correctly, so I assume this shouldn’t matter as much in v7?
Issue Analytics
- State:
- Created 5 years ago
- Comments:30 (1 by maintainers)
Top GitHub Comments
Now with support for useNativeDriver with transform styles using the same syntax as for react-native views: https://github.com/react-native-community/react-native-svg/commit/fb4e877c2b23b4c52971c16d42c305d9f28a9eb5
@msand The updates you just posted are super exciting. Looking forward to try it out with expo in the near future.
@IljaDaderko Good to see you here 🙋🏼♂️