React-Native结合Reanimated 2实现SVG transform动画时G组件缩放不生效问题
问题核心原因
- react-native-svg的
G组件不支持你当前传入的transform格式:SVG元素的transform属性遵循SVG规范,要么传入标准transform字符串,要么传入符合react-native-svg适配要求的数组格式,你写的transform: { scale: [scaleX.value, scaleY.value] }不符合任何一种可识别格式,因此缩放不生效。 G组件本身没有x、y属性,你单独设置的x、y值不会产生位移效果,位移逻辑也需要整合到transform属性中。
修复方案
你需要把位移、缩放逻辑都整合到符合要求的transform数组中,修正后的代码如下:
import React, { FC } from "react"; import { G } from "react-native-svg"; import Animated, { useAnimatedProps, 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 { // 所有变换都写到transform数组中,符合react-native-svg的适配规则 transform: [ { translateX: withSpring(translateX.value, { damping: 20, stiffness: 90, }) }, { translateY: withSpring(offsetByY.value, { damping: 20, stiffness: 90, }) }, { scaleX: scaleX.value }, { scaleY: scaleY.value } ] }; }); return ( <AnimatedGroup animatedProps={props}> {data.map((candle, index) => ( <Candle key={index} width={CANDLE_WIDTH} {...{ candle, index }} domain={initialDomain} /> ))} </AnimatedGroup> ); };
如果上述数组格式的transform在你当前的react-native-svg版本下不生效,可以改为拼接SVG标准transform字符串的形式:
const props = useAnimatedProps(() => { const animatedX = withSpring(translateX.value, { damping:20, stiffness:90 }); const animatedY = withSpring(offsetByY.value, { damping:20, stiffness:90 }); return { transform: `translate(${animatedX}, ${animatedY}) scale(${scaleX.value}, ${scaleY.value})` }; });
这种方案是直接操作SVG原生支持的transform属性,不会经过View层的缩放,完全不会降低SVG内容的显示清晰度。
内容的提问来源于stack exchange,提问作者Ilya
相关产品推荐
相关产品推荐

