簡體   English   中英

如何聆聽 react-native-reanimated 中的價值變化?

[英]How to listen to value change in react-native-reanimated?

我用react-native-svgreact-native Animated創建了一個簡單的動畫。

這工作做得很好,

但是現在我切換到react-native-reanimated因為我在他們的網站上看到 reanimated 比react-native Animated快。

但是在這里我遇到了一個問題,那就是我找不到函數addListener來監聽值的變化。

來自react-native Animated代碼:

const circleRadius = new Animated.value(100);

circleRadius.addListener( circleRadius => {
       circleSVG.current.setNativeProps({ cx: circleRadius.value.toString() });
});

如何在react-native-reanimated實現上面的addListener函數

您可以使用Animated.call實現類似的行為。 是一個關於這個主題的不錯的教程。

編輯:

例如,要收聽circleRadius變化,您可以使用以下代碼:

  import { call, useCode } from 'react-native-reanimated'

  useCode(() => {
    return call([circleRadius], (circleRadius) => {
      console.log(circleRadius)
    })
  }, [circleRadius])

它做你想要的嗎?

import React, { FC, useRef } from 'react';
import { StyleSheet, TextInput, View } from 'react-native';
import Svg, { G, Circle } from 'react-native-svg';
import Animated, { call, Easing, interpolate, useCode } from 'react-native-reanimated';
import { timing } from 'react-native-redash';

interface DonutChartProps {
  percentage: number;
  radius?: number;
  strokeWidth?: number;
  duration?: number;
  color?: string;
  delay?: number;
  textColor?: string;
  max?: number;
}

const AnimatedCircle = Animated.createAnimatedComponent(Circle);
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);

const DonutChart: FC<DonutChartProps> = ({
  percentage,
  radius = 40,
  strokeWidth = 10,
  duration = 500,
  color = 'tomato',
  textColor,
  max = 100,
}) => {
  const inputRef = useRef<TextInput>(null);

  const halfCircle = radius + strokeWidth;
  const circumference = 2 * Math.PI * radius;
  const maxPercentage = (100 * percentage) / max;

  const animation = timing({
    from: 0,
    to: 1,
    duration,
    easing: Easing.inOut(Easing.linear),
  });

  const strokeDashoffset = interpolate(animation, {
    inputRange: [0, 1],
    outputRange: [circumference, circumference - (maxPercentage * circumference) / 100],
  });

  const textValue = interpolate(animation, {
    inputRange: [0, 1],
    outputRange: [0, Math.round(percentage)],
  });

  useCode(
    () => [
      call([textValue], ([textValue]) => {
        if (inputRef.current) {
          inputRef.current.setNativeProps({
            text: `${Math.round(textValue)}`,
          });
        }
      }),
    ],
    [textValue]
  );

  return (
    <View>
      <Svg width={radius * 2} height={radius * 2} viewBox={`0 0 ${halfCircle * 2} ${halfCircle * 2}`}>
        <G rotation="-90" origin={`${halfCircle}, ${halfCircle}`}>
          <Circle
            cx="50%"
            cy="50%"
            stroke={color}
            strokeWidth={strokeWidth}
            r={radius}
            fill="transparent"
            strokeOpacity={0.2}
          />
          <AnimatedCircle
            cx="50%"
            cy="50%"
            stroke={color}
            strokeWidth={strokeWidth}
            r={radius}
            fill="transparent"
            strokeDasharray={circumference}
            strokeDashoffset={strokeDashoffset}
            strokeLinecap="round"
          />
        </G>
      </Svg>
      <AnimatedTextInput
        ref={inputRef}
        underlineColorAndroid="transparent"
        editable={false}
        defaultValue="0"
        style={[
          StyleSheet.absoluteFillObject,
          { fontSize: radius / 2, color: textColor ?? color, fontWeight: '900', textAlign: 'center' },
        ]}
      />
    </View>
  );
};

export default DonutChart;

Reanimated 旨在成為一個聲明式 API,允許您運行更高級的動畫,從而在本機線程上運行復雜的邏輯。

沒有實現類似addListener的原因是因為它需要在本機和 JS 線程之間發送不必要的消息。 因此,與其使用偵聽器和setNativeProps來更新圓的cx屬性, setNativeProps使用AnimatedNode

const circleRadius = new Animated.value(100);

circleRadius.addListener( circleRadius => {
       circleSVG.current.setNativeProps({ cx: circleRadius.value.toString() });
});

import { Circle } from 'react-native-svg';

// must make Circle compatible with Animated Values
const AnimatedCircle = Animated.createAnimatedComponent(Circle);

// then within your svg
<AnimatedCircle 
  // ... add other props
cx={circleRadius}
/>

我已創建了一個簡單的動畫Animatedreact-nativereact-native-svg

這樣可以很好地完成工作,

但是現在我切換到了react-native-reanimated cuz,因為我在他們的網站上閱讀到reanimated的速度比Animated from react-native快。

但是在這里我遇到了一個問題,那就是我找不到函數addListener來監聽值的變化。

來自react-native Animated代碼:

const circleRadius = new Animated.value(100);

circleRadius.addListener( circleRadius => {
       circleSVG.current.setNativeProps({ cx: circleRadius.value.toString() });
});

如何在react-native-reanimated實現上述addListener函數

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM