Ширина анимации <Rect /> в реагировать-нативно-SVG
У меня есть простая анимация интерполяции для <Rect />
элемент, однако я не вижу изменений в моем пользовательском интерфейсе, как будто ширина остается 0.
Я вручную добавил свое конечное значение в компонент как width={149.12}
и он отображал его правильно, поэтому я немного запутался, почему он не получает то же значение из анимации?
react-native@0.57.1
react-native-svg@7.03
Ориентация на iOS 12
Вот полная реализация, в сущности полоса маны и здоровья, которые принимают текущее значение и общее значение, то есть 50 и 100, должны отображать половину ширины для прямоугольника. (В примере используется машинопись, но при необходимости ответ может быть простым js)
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)
}
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
}).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
Связанная библиотека: https://github.com/react-native-community/react-native-svg
2 ответа
Это было изначально невозможно с react-native-svg
, но решение в настоящее время разрабатывается, и вы можете следить за прогрессом здесь
https://github.com/react-native-community/react-native-svg/issues/803
Попробуй использовать lottie-react-native
https://github.com/react-community/lottie-react-native
Это, на мой взгляд, лучший инструмент для работы с анимацией в реагировать на натив.