首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SVG本机再生2(基于路由更改的动画SVG)

SVG本机再生2(基于路由更改的动画SVG)
EN

Stack Overflow用户
提问于 2021-12-30 20:38:54
回答 1查看 1.8K关注 0票数 0

我有一个Svg作为底部TabBar的图标。在路由更改时,将当前state.index与路由index进行比较。实质上是布尔状态isFocused的结果被传递给Svg。

我试图动画的Svg基于这个状态,不能得到简单的操作完成使用恢复。我最确定的是,填充的值没有在useAnimatedProps钩子中被更新,但是我缺乏对恢复具有深刻知识的经验。如有任何帮助,将不胜感激。

代码语言:javascript
复制
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>
  );
};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-31 09:06:50

更常见的方法是使用“进度变量”作为共享值。

代码语言:javascript
复制
const fillProgress = useSharedValue(isFocused? 1 : 0);

您将使用这个进度变量来生成animatedProps。请注意使用interpolateColor得到实际的内插颜色。

代码语言:javascript
复制
const animatedProps = useAnimatedProps(() => {
    const fillValue = interpolateColor(fillProgress.value, [0, 1], ["transparent", "red"]);  
    return {
        fill: fillValue
    }
});

您必须返回一个具有您想要动画的属性的对象。例如,如果您想要动画填充和不透明度,您将返回带有适当值的{fill: "", opacity: -1},而不是""-1。最后,你必须使实际的元素,你想动画动画。在本例中,您想要动画化Circle,而不是Svg,因此必须是一个动画对象。

代码语言:javascript
复制
const AnimatedCircle = Animated.createAnimatedComponent(Circle);

然后,您可以使用useEffect和相应的动画来检测焦点。

代码语言:javascript
复制
useEffect(() => {
    fillProgress.value = withTiming(isFocused? 1 : 0);
}, [isFocused]);

记住设置fillProgress的初始值,就像在withTiming函数中一样。

总之,您必须对使用动画属性的元素进行动画化,并且应该使用上面提到的进度变量。

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

代码语言:javascript
复制
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>
    );
};
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70536457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档