如何使用 React-Native 和 Reanimated 2 为 svg 设置动画道具变换

Posted

技术标签:

【中文标题】如何使用 React-Native 和 Reanimated 2 为 svg 设置动画道具变换【英文标题】:How to animate prop transform for svg with React-Native and Reanimated 2 【发布时间】:2021-10-25 10:39:21 【问题描述】:
import React,  FC  from "react";
import  G  from "react-native-svg";
import Animated,  useAnimatedProps, useDerivedValue, withSpring  from "react-native-reanimated";
import  CanvasControlledValuesProps  from "./helpers/types";
import  Candle  from "./Candle";
import  CANDLE_WIDTH  from "../../constants/sizes";

const AnimatedGroup = Animated.createAnimatedComponent(G);

export const Canvas: FC<CanvasControlledValuesProps> = (
    scaleY,
    scaleX,
    translateX,
    offsetByY,
    data,
    initialDomain,
) => 
    const props = useAnimatedProps(() => 
        return 
            x: withSpring(translateX.value, 
                damping: 20,
                stiffness: 90,
            ),
            y: withSpring(offsetByY.value, 
                damping: 20,
                stiffness: 90,
            ),
            transform:  scale: [scaleX.value, scaleY.value] ,
        ;
    );

    return (
        <AnimatedGroup animatedProps=props>
            data.map((candle, index) => (
                <Candle key=index width=CANDLE_WIDTH ... candle, index  domain=initialDomain />
            ))
        </AnimatedGroup>
    );
;

美好的一天!我需要增加或减少AnimatedGroup的内容,所以我决定使用G但是有一个问题:AnimatedGroup没有应用缩放,为什么会这样?我没有使用过 Animated.View,因为 AnimatedGroup 所在的 Svg 内容的质量会丢失。

【问题讨论】:

【参考方案1】:
const style = useAnimatedStyle(() => 
    return 
        transform: [
            
                translateX: offsetByX.value,
            ,
            
                translateX: withSpring(translateX.value, springConfig),
            ,
            
                translateY: withSpring(adaptation.value.offsetByY, springConfig),
            ,
            
                scaleX: scaleX.value,
            ,
            
                scaleY: withSpring(adaptation.value.scaleY, springConfig),
            ,
        ],
    ;
);

return (
    <AnimatedGroup style=style>
        data.map((candle, index) => (
            <Candle key=index width=CANDLE_WIDTH ... candle, index  domain=initialDomain />
        ))
    </AnimatedGroup>
);

解决方案是为 Animated Group 添加动画样式。或者你可以像这样使用矩阵属性:

const props = useAnimatedProps(() => 
    return 
        x: withSpring(translateX.value, 
            damping: 20,
            stiffness: 90,
        ),
        y: withSpring(offsetByY.value, 
            damping: 20,
            stiffness: 90,
        ),
        matrix: [scaleX.value, 0, 0, scaleY.value, 0, 0],
    ;
);

你可以在这里阅读矩阵的工作https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform

【讨论】:

以上是关于如何使用 React-Native 和 Reanimated 2 为 svg 设置动画道具变换的主要内容,如果未能解决你的问题,请参考以下文章

单击使用 react-native 时如何更改图像和文本颜色?

如何将 StyleSheet.absoluteFillObject 与 ts、react-native 和 styled 组件一起使用?

如何使用 Stripe (stripe.js) 和 react-native

如何在使用 Rosetta 的 Mac 上解决“react-native”和 cocopods 的错误

如何缩小 React-Native 地图

如何使用 React-Native 和 Reanimated 2 为 svg 设置动画道具变换