简体   繁体   English

在react-native-svg中设置<Rect />的宽度

[英]Animating width of <Rect /> in react-native-svg

I have simple animation interpolation going on for <Rect /> element, however I see no changes on my ui, as if width is staying 0. 我为<Rect />元素进行了简单的动画插值,但是我看到我的ui没有变化,好像宽度保持为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? 我手动将我的结束值添加到组件中width={149.12}并且它正确显示,因此我现在有点困惑为什么它没有从动画中获取相同的值?

react-native@0.57.1 react-native@0.57.1

react-native-svg@7.03 react-native-svg@7.03

Targeting iOS 12 针对iOS 12

Here is full implementation, in essence a mana and health bar that take in current value and total value ie 50 and 100 should display half width for the rect. 这里是完整的实现,本质上是一个法术力和健康条,它接收当前值和总值,即50和100应显示rect的半宽。 (Example uses typescript, but answer can be in plain js if needed) (示例使用typescript,但如果需要,答案可以是普通的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

Related library: https://github.com/react-native-community/react-native-svg 相关库: https//github.com/react-native-community/react-native-svg

This was not initially possible with react-native-svg , but solution is currently being worked on and you can follow progress here 这最初不可能与react-native-svg ,但目前正在开发解决方案,您可以在此处跟进进度

https://github.com/react-native-community/react-native-svg/issues/803 https://github.com/react-native-community/react-native-svg/issues/803

Try to use lottie-react-native 尝试使用lottie-react-native

https://github.com/react-community/lottie-react-native https://github.com/react-community/lottie-react-native

It is, in my opinion, best tool to work with animations in react native. 在我看来,它是在本机中使用动画的最佳工具。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM