0

我正在使用react-native-svg。我想围绕另一个更大的圆圈制作一个小圆圈的动画。这个问题与这个问题类似。动画与任何手势无关,而是与时间相关。旋转应该在几秒钟内完成一个预定义的延迟,并且应该尽可能平滑。是否可以使用 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(): 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;
}

任何帮助表示赞赏。

4

1 回答 1

4

以下文章中所述,在以下示例中进行了演示,并从Nishant Nair建议您需要使用 transform 属性来svg围绕另一个对象旋转。

CSS动画示例

该代码包含在文件的第 51 行中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' }])

to 字段应设置为

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

触发动画

您可以使用Animatedapi来更改state时间。每次keyframe您需要将 Viewtransform属性从更改rotateX: '0deg'rotateX: '360deg'。您可以将 SVG 作为rotateInView组件的子级传递:

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

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

在 rotateInView 构造函数中,一个新的Animated.Value调用rotateAnim被初始化为状态的一部分。View 上的 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: transform([{ 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 Animated View
        style={{
          ...this.props.style,
          transform: rotateAnim,         
        }}
      >
        {this.props.children}
      </Animated.View>
    );
  }
}
于 2019-05-22T12:45:24.097 回答