react-native - 围绕另一个圆圈制作一个圆圈的动画
问题描述
我正在使用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;
}
任何帮助表示赞赏。
解决方案
如以下文章中所述,在以下示例中进行了演示,并从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); }
}
Transforms
在react-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
您需要将 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>
);
}
}