【问题标题】:Animate a Circle around another circle围绕另一个圆圈制作一个圆圈的动画
【发布时间】:2019-09-04 04:03:10
【问题描述】:

我正在使用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>

还有 typescript 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;
}

任何帮助表示赞赏。

【问题讨论】:

  • stackoverflow.com/a/18736137/9994657。这看起来很相似。试试看?
  • 我不能使用 CSS。我没有在浏览器中运行。
  • 看来代码可以转成JS了。将尝试并在此处发布。

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


【解决方案1】:

正如in the following article 解释的那样,following example 中的演示和Nishant Nair 的建议,您需要使用 transform 属性来围绕另一个对象旋转 svg

CSS 动画示例

代码包含在in line 51 of file transition-circle-keyframes.css 中,它在每个@keyframes 上使用transform 来移动对象。

@-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' }])

触发动画

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

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

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

在 rotateInView 构造函数中,一个名为 rotateAnim 的新 Animated.Value 被初始化为状态的一部分。 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>
    );
  }
}

【讨论】:

    猜你喜欢
    • 2021-06-24
    • 2019-04-25
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    相关资源
    最近更新 更多