围绕另一个圆使一个圆动起来

时间:2019-04-13 16:44:17

标签: react-native react-native-svg

我正在使用react-native-svg。 我想在另一个大圆圈周围设置一个小圆圈。这个问题类似于this one。 动画与时间无关,与任何手势无关。旋转应以预定义的延迟(以秒为单位)完成,并且应尽可能平滑。是否可以使用react-native-svg做到这一点?

为了完整起见,我不得不说还有其他每秒钟绘制一次的小圆圈。这已经通过每秒改变状态来工作。但是我当然不会通过改变状态来制作动画,对吗?

这是我到目前为止在render()中拥有的JSX代码:

<Svg style={{ alignContent: 'center' }}
  height="200"
  width="200">
  <Circle 
    cx="100"
    cy="100"
    r="56"
    stroke="black"
    strokeWidth="2"
    strokeOpacity="1"
    fillOpacity="0" 
  />
  { 
    /* Bubules (little circles) goes here*/                                                            
    this.bubbles() 
  }
</Svg>

和打字稿Bubbles()方法:

bubbles(): React.ReactNode {
    var elements = [];
    for (let tuple of this.state.lorenzPlotData) {
        let color = tuple === this.state.lorenzPlotData.tail ? "red" : "black";
        // We need to normalize data 
        elements.push(<Circle key={tuple[0]} cx={this.normalizePlot(tuple[1])} cy={this.normalizePlot(tuple[2])} r="4" fill={color} fillOpacity="1" />);
    }
    return elements;
}

任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:3)

in the following article所述,在following example中进行了演示,并在Nishant Nair中提出了建议,您需要使用transform属性来使svg围绕另一个对象旋转。

CSS动画示例

包含了代码in line 51 of file transition-circle-keyframes.css,并且每个transform上都使用@keyframes移动对象。

@-webkit-keyframes orbit {
    from {  -webkit-transform: rotate(0deg) translateX(400px) rotate(0deg); }
    to   {  -webkit-transform: rotate(360deg) translateX(400px) rotate(-360deg); }
}

Transformsreact-native

  

transform

     

transform接受一组转换对象。每个对象都指定将要转换为键的属性,以及在转换中使用的值。对象不应合并。每个对象使用一个键/值对。

     

旋转变换需要一个字符串,以便可以以度(deg)或弧度(rad)表示变换。例如:

相应的from字段应设置为

transform([{ rotateX: '0deg' }, { translateX: 400}, { rotateX: '0deg' }])

“收件人”字段应设置为

transform([{ rotateX: '360deg' }, { translateX: 400}, { rotateX: '-360deg' }])

触发动画

您可以使用Animated api随时间更改state。 在每个keyframe上,您都需要将View transform属性从rotateX: '0deg'更改为rotateX: '360deg'。您可以将SVG作为rotateInView组件的子代传递:

render() {
  return (
    <rotateInView>
      <Svg />
    </rotateInView>
  );
}

rotateInView组件会将transform保存为状态,Animated.timing()函数将触发状态更新

  

在rotateInView构造函数中,名为Animated.Value的新rotateAnim被初始化为状态的一部分。视图上的transform属性映射到该动画值。在幕后,提取数值并将其用于设置变换属性。

     

安装组件时,不透明度设置为[{ rotateX: '0deg' }, { translateX: 400}, { rotateX: '0deg' }]。然后,在rotateAnim动画值上开始一个缓动动画,当值动画化为最终值时,它将在每一帧上更新其所有从属映射(在这种情况下,仅是transform属性)的[{ rotateX: '360deg' }, { translateX: 400}, { rotateX: '-360deg' }]

     

这是一种优化的方法,比调用setState和重新渲染要快。   由于整个配置都是声明性的,因此我们将能够实现进一步的优化,以对配置进行序列化,并在高优先级线程上运行动画。

import React from 'react';
import { Animated, Text, View } from 'react-native';
class rotateInView extends React.Component {
  state = {
    rotateAnim: new Animated.Value(transform([{ rotateX: '0deg' }, { translateX: 400}, { rotateX: '0deg' }])),
  }

  componentDidMount() {
    Animated.timing(                  // Animate over time
      this.state.rotateAnim,            // The animated value to drive
      {
        toValue: transoform([{ rotateX: '360deg' }, { translateX: 400}, { rotateX: '-360deg' }]), // change to the new value
        duration: 10000,              // Make it take a while
      }
    ).start();                        // Starts the animation
  }

  render() {
    let { rotateAnim } = this.state;

    return (
      <Animated.View                 // Special animatable View
        style={{
          ...this.props.style,
          transform: rotateAnim,         
        }}
      >
        {this.props.children}
      </Animated.View>
    );
  }
}