首页 > 解决方案 > React-native-reanimated 2:如何更新 Text 以响应 PanGestureHandler?

问题描述

这是我的组件。这是一个简单PanGestureHandler的一些svg。

import React from 'react'
import { StyleSheet, View, Text } from 'react-native'
import Svg, { Circle, Line } from 'react-native-svg'
import Layout from '../constants/Layout'
import {
  PanGestureHandler,
  TapGestureHandler
} from 'react-native-gesture-handler'
import Animated, {
  useSharedValue,
  useAnimatedGestureHandler,
  useAnimatedProps,
  withTiming,
  Easing
} from 'react-native-reanimated'

const AnimatedCircle = Animated.createAnimatedComponent(Circle)

const chartWidth = Layout.window.width
const chartHeight = chartWidth / 2.6
const timing = 200

export default function Chart () {
  const x = useSharedValue(chartWidth / 2)
  const y = useSharedValue(chartHeight / 2)
  // const [val, setVal] = React.useState('happy')
  const gestureHandler = useAnimatedGestureHandler({
    onActive: event => {
      x.value = event.x
      y.value = event.y
    }
  })

  const animatedCircleProps = useAnimatedProps(() => ({
    cx: x.value,
    cy: y.value
  }))

  return (
    <View style={styles.container}>
      <Text>Some Text</Text>
      <View style={styles.chartWrapper}>
        <TapGestureHandler
          onHandlerStateChange={event => {
            x.value = withTiming(event.nativeEvent.x, {
              duration: timing,
              easing: Easing.ease
            })
            y.value = withTiming(event.nativeEvent.y, {
              duration: timing,
              easing: Easing.ease
            })
          }}
        >
          <Animated.View style={styles.box}>
            <PanGestureHandler onGestureEvent={gestureHandler}>
              <Animated.View style={styles.box}>
                <Svg
                  width={chartWidth + 10}
                  height={chartHeight + 10}
                  viewBox={`0 0 ${chartWidth} ${chartHeight}`}
                  fill='none'
                >
                  <AnimatedCircle
                    animatedProps={animatedCircleProps}
                    r='7'
                    fill='white'
                  />
                  {Array(5)
                    .fill(1)
                    .map((_, index) => (
                      <Line
                        key={index}
                        x2={chartWidth}
                        y2={(chartHeight * index) / 4}
                        y1={(chartHeight * index) / 4}
                        stroke='rgba(255,255,255,0.4)'
                      />
                    ))}
                </Svg>
              </Animated.View>
            </PanGestureHandler>
          </Animated.View>
        </TapGestureHandler>
      </View>
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'column'
  },
  headline: {
    fontSize: 36
  },
  chartWrapper: {
    width: chartWidth + 10,
    height: chartHeight + 10
  },
  box: {}
})

<Text>Some Text</Text>什么时候更新怎么办x > 100

标签: react-nativereact-native-reanimatedreact-native-gesture-handlerreact-native-reanimated-v2

解决方案


1.创建一个 SharedValue

const animatedText = useSharedValue('Some Text')
    

2. 当手势事件完成且 x > 100 时更改 SharedValue

const gestureHandler = useAnimatedGestureHandler({
  onStart: () => { ... },
  onActive: () => { ... },
  onEnd: () => { ... },
  onFinish: (event) => {
    if (event.x > 100) animatedText.value = 'New Text'
  }    
})

3.使用 react-native-redash 包中的 ReText

<ReText text={animatedText} />

如果您不想使用 react-native-redash,请在此处查看它的构建方式:https ://github.com/wcandillon/react-native-redash/blob/fd0b0ddb3b4c10ae88cf1f8a95890c7c5eb3c475/src/ReText.tsx


推荐阅读