非样式类型的React式动画值react native reanimated-2(SVG属性)

rqqzpn5f  于 2023-02-05  发布在  React
关注(0)|答案(1)|浏览(158)

我正在使用ReactNative-reanimated-2我想在颜色属性中使用SVG路径制作动画
我知道如何使用useAnimationStyle在样式属性中执行此操作,但如何使用SVG prpos等非样式属性执行此操作
像这样

const animatedStyleColor = useAnimatedStyle(() => {
  return {
    color: interpolate(nimatedValue.value, [0, 50], ['blue', 'red'], {
      extrapolateRight: Extrapolation.CLAMP,
    }),
  };
});

<Svg width={80} height={60} viewBox="0 0 8 4">
  <AnimatedPath
    d="M0 4l4-4 4 4"
    stroke={'blue'} //here I need to animation
    strokeWidth={3.5}
    fill="none"
    fillRule="evenodd"
    strokeLinecap="round"
    strokeLinejoin="round"
  />
</Svg>

My Demo
但那不管用怎么能让那

jgovgodb

jgovgodb1#

我发现useAnimatedProps有一个bug/问题,可以通过提供一个空的onPress函数(here's the issue)来解决:

import { Button, Text } from 'react-native';
import Animated, {
  useAnimatedStyle,
  useSharedValue,
  withTiming,
  interpolate,
  useAnimatedProps,
  useDerivedValue,
  interpolateColor,
  Extrapolation,
} from 'react-native-reanimated';
import Svg, { Path } from 'react-native-svg';

// moved out side of component to avoid recreating AnimatedPath on re-renders
const AnimatedPath = Animated.createAnimatedComponent(Path);

export default function AssetExample() {
  const animatedValue = useSharedValue(50);
  // keep track of current color and color animating to
  const targetColor = useSharedValue('#ad08ed');
  const currentColor = useSharedValue('#acc880');
  // interpolate between to colors
  const color = useDerivedValue(() => {
    return interpolateColor(
      animatedValue.value,
      [0, 50],
      [currentColor.value, targetColor.value]
    );
  });

  const changeColor = (newColor) => {
    targetColor.value = newColor;
    currentColor.value = color.value;
    animatedValue.value = withTiming(animatedValue.value > 0 ? 0 : 50, {
      duration: 1500,
    });
  };
  const animatedProps = useAnimatedProps(() => {
    return {
      stroke: color.value,
      strokeWidth: interpolate(animatedValue.value, [0, 50], [1.5, 3.5]),
    };
  });

  return (
    <>
      <Button
        onPress={() => changeColor(getRandomColor())}
        title={'Change color'}
      />
      <Svg width={100} height={100} viewBox="0 0 8 4">
        <AnimatedPath
          d="M0 4l4-4 4 4"
          strokeWidth={3.5}
          fill="none"
          fillRule="evenodd"
          strokeLinecap="round"
          strokeLinejoin="round"
          animatedProps={animatedProps}
          // found out there's a bug that is resolved by having onPress
          // https://github.com/software-mansion/react-native-reanimated/issues/3321
          onPress={() => {}}
        />
      </Svg>
    </>
  );
}

const getRandomInt = (min = 0, max = 1) => {
  const range = max - min;
  return Math.floor(Math.random() * range) + min;
};

const getRandomColor = () => {
  const rgb = [
    getRandomInt(0, 255),
    getRandomInt(0, 255),
    getRandomInt(0, 255),
  ].map((int) => int.toString(16).padStart(2, '0'));
  return '#' + rgb.join('');
};

Demo

相关问题