【问题标题】:What's the equivalent of react-native-svg rotation with origins using react-native animated api使用 react-native 动画 api 与原点进行 react-native-svg 旋转的等价物是什么
【发布时间】:2020-01-11 12:50:32
【问题描述】:

我有以下 svg 路径,它在每个value 状态更改成功时围绕原点旋转,其中值是一些度数值:

<Path
   transform={{
      rotation: this.state.value,
      originX: width / 2,
      originY: height / 2
   }}
   d={`M ${width * 0.5} ${height * 0.5} L${width * 0.75} ${height * 0.75}`} //the actual path does not matter 
   fill={Colors.black}
   stroke={Colors.black}
   />

我每隔约 20 毫秒在 value 上调用 setState,但这不够平滑,+ 这不是进行转换的推荐方式。 我想要实现的是使用动画 API 为旋转设置动画,以实现更平滑的旋转。

我尝试将我的value 状态设为Animated.Value。然后将Path 设为Animated.createAnimatedComponent(Path) 并调用:

Animated.timing(this.state.value, {
    toValue: newDegreesValue,
    duration: 1000,
    useNativeDriver: true
}).start();

然后我像这样渲染路径:

<Path
   style={transform:[{
      rotate: this.state.value
   }]}
   d={`M ${width * 0.5} ${height * 0.5} L${width * 0.75} ${height * 0.75}`} //the actual path does not matter 
   fill={Colors.black}
   stroke={Colors.black}
   />

这在接近之前使用状态的工作代码时根本不起作用。一个原因是动画 API 不支持的 originX、originY 值,我不知道如何替换,但我不确定这是唯一的原因,也许 rotaterotation 属性也有所不同?. 那么问题来了,不断调用 setState 的代码如何使用动画 api 实现同样的结果呢?

【问题讨论】:

    标签: react-native animation react-native-svg


    【解决方案1】:

    你需要使用插值

    
    const animation=this.state.value.interpolate({
      inputRange: [0, 360],
      outputRange: ['0deg', '360deg'],
    });
    <Path
       style={transform:[{
          rotate:animation
       }]}
    
    

    【讨论】:

    • 但是起源呢?
    • 过去我找过这样的选项,但没有找到
    【解决方案2】:

    这是我实现它的方式:

    // init the animatedComponents
    const NeedlePath = Animated.createAnimatedComponent(Path);
    const AnimatedG = Animated.createAnimatedComponent(G);
    
    // set the animation
    Animated.timing(this.state.angle, {
            toValue: 240, // degrees
            duration: 1000,
            useNativeDriver: true
        }).start();
    
    // pivotX and pivotY are the originX, originY points.
    // the width and height are calculated dynamically, so that the whole svg is a square (equal height width), and the center of it are my origins.
    render() {
        let height = this.state.height;
        let width = this.state.width;
        let [pivotX, pivotY] = [0, 0];
        if (height && width) {
            [pivotX, pivotY] = [width / 2, height / 2];
        }
       return (
            <View
                style={{ flex: 1}}
                onLayout={event => {
                    this.findDimesions(event.nativeEvent.layout); // find height and width dynamically, so that this remain a square container with same height and width
                }}
            >
                {height !== undefined && width !== undefined && (
                    <Svg height={height} width={width} style={{ alignItems: "center" }}>
                       <G transform={`translate(${pivotX}, ${pivotY})`}>
                            <AnimatedG
                                style={{
                                    transform: [
                                        {
                                            rotate: this.state.angle.interpolate({
                                                inputRange: [0, 360],
                                                outputRange: [`0deg`, `360deg`]
                                            })
                                        }
                                    ]
                                }}
                            >
                                <NeedlePath
                                    transform={`translate(-${pivotX} -${pivotY})`}
                                    d={`M ${width * 0.5} ${height * 0.5} L${width * 0.5 + width * 0.25} ${height * 0.5 + height * 0.25}`}
                                    fill={Colors.black}
                                    stroke={Colors.black}
                                />
                            </AnimatedG>
                        </G>
                    </Svg>
                )}
            </View>
        );
    }
    

    style={{ alignItems: "center" }} 对于在 android 上实现相同结果也至关重要,而不是使用 offsetAndroid 设置 translationX 和 translationY。这适用于 react-native-svg 的 v9.13.3 版本。也许在较新的版本中,由于修复了翻译问题,这会受到影响,而且我不知道这会对这里的代码产生什么影响。您可以参考here 了解更多关于 android 上需要偏移的翻译的信息

    【讨论】:

      猜你喜欢
      • 2017-05-05
      • 1970-01-01
      • 2019-08-13
      • 2022-08-19
      • 1970-01-01
      • 2020-01-19
      • 2020-04-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多