React Native Reanimated 2(根据更改的路线制作SVG动画)



我有一个react功能组件Svg用作底部选项卡栏的图标。在路由改变时,将当前state.index与路由index进行比较。将本质上是布尔状态CCD_ 4的结果传递给Svg。

我正试图基于这种状态来动画化Svg,但无法使用复活来完成简单的操作。我最确定的是,在useAnimatedProps钩子中填充的值没有更新,但我缺乏对复活有深入了解的经验。将非常感谢任何帮助

import Animated, {
useAnimatedProps,
useSharedValue,
} from 'react-native-reanimated';
import Svg, { Circle, Path } from 'react-native-svg';
const AnimatedSvg = Animated.createAnimatedComponent(Svg);
export default ({ isFocused }) => {
const fill = useSharedValue({ fill: 'transparent' });
const animatedProps = useAnimatedProps(() => {
isFocused
? (fill.value = { fill: 'red' })
: (fill.value = { fill: 'transparent' });
return fill.value;
});
return (
<AnimatedSvg
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
animatedProps={animatedProps}
stroke={'white'}
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
className="feather feather-search">
<Circle cx={11} cy={11} r={8} />
<Path d="m21 21-4.35-4.35" />
</AnimatedSvg>
);
};

更常见的方法是使用;进度变量";作为共享价值。

const fillProgress = useSharedValue(isFocused? 1 : 0);

您将使用此进度变量来生成动画道具。请注意使用interpolateColor来获得实际插值颜色。

const animatedProps = useAnimatedProps(() => {
const fillValue = interpolateColor(fillProgress.value, [0, 1], ["transparent", "red"]);  
return {
fill: fillValue
}
});

您必须返回一个具有要设置动画的特性的对象。例如,如果要设置填充和不透明度的动画,则应返回具有适当值的{fill: "", opacity: -1},而不是""-1。最后,您必须将要设置动画的实际元素设置为动画。在这种情况下,您希望为Circle设置动画,而不是为Svg设置动画,因此它必须是一个动画对象。

const AnimatedCircle = Animated.createAnimatedComponent(Circle);

然后,您可以使用useEffect检测焦点,并相应地设置动画。

useEffect(() => {
fillProgress.value = withTiming(isFocused? 1 : 0);
}, [isFocused]);

记住要像在withTiming函数中那样设置fillProgress的初始值。

总之,您必须为使用动画属性的元素设置动画,并且您应该使用如上所述的进度变量。

以下是完整的修改代码(在Android上测试(:

import Animated, {
useAnimatedProps,
useSharedValue,
} from 'react-native-reanimated';
import Svg, { Circle, Path } from 'react-native-svg';
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
export default function Icon ({ isFocused }) {
const fillProgress = useSharedValue(isFocused? 1 : 0);
const animatedProps = useAnimatedProps(() => {
const fillValue = interpolateColor(fillProgress.value, [0, 1], ["transparent", "red"]);  
return {
fill: fillValue
}
});

useEffect(() => {
fillProgress.value = withTiming(isFocused? 1 : 0);
}, [isFocused]);
return (
<Svg
width={24}
height={24}
stroke={'white'}
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
className="feather feather-search">
<AnimatedCircle animatedProps={animatedProps} cx={11} cy={11} r={8} />
<Path d="m21 21-4.35-4.35" />
</Svg>
);
};

最新更新