React-native引入了新的Animated
API,我希望制作一个循环动画,例如缩小气泡,然后按比例缩小并重复该进度。
然而我无法弄明白。我尝试过写下面的代码
class TestProject extends React.Component {
constructor(): void {
super();
this.state = {
bounceValue: new Animated.Value(0),
v: 1,
};
}
componentDidMount() {
this.state.bounceValue.setValue(1.5);
let animation = Animated.timing(this.state.bounceValue, {
toValue: this.state.v,
});
setInterval(() => {
animation.stop();
if (this.state.flag) {
this.state.v = 0.5;
this.state.bounceValue.setValue(0.5);
}
else {
this.state.v = 1.5;
this.state.bounceValue.setValue(1.5);
}
animation.start();
}, 5000);
}
render(): ReactElement {
return (
<View style={styles.imageContainer}>
<Image
style={styles.image}
source={{uri: 'http://image142-c.poco.cn/best_pocoers/20130517/91062013051716553599334223.jpg'}}
/>
<Animated.Text
style={[
styles.test,
{transform: [
{scale: this.state.bounceValue},
],}
]
}>
haha
</Animated.Text>
</View>
);
}
}
但效果不佳。
任何建议都会受到赞赏。
答案 0 :(得分:101)
现在有loop animation可用:
Animated.loop(
Animated.sequence([
Animated.timing(this.state.animatedStartValue, {
toValue: 1,
duration: 500,
delay: 1000
}),
Animated.timing(this.state.animatedStartValue, {
toValue: 0,
duration: 500
})
]),
{
iterations: 4
}
).start()
答案 1 :(得分:38)
我使用序列方法将一组动画传递给循环,然后重复该函数。
//this.state.animatedStartValue = 0;
function cycleAnimation() {
Animated.sequence([
Animated.timing(this.state.animatedStartValue, {
toValue: 1,
duration: 500,
delay: 1000
}),
Animated.timing(this.state.animatedStartValue, {
toValue: 0,
duration: 500
})
]).start(() => {
cycleAnimation();
});
}
如果我在它上面切换动画,它会淡入/淡出,但是我将它叠加在一个基础之上以模仿活动状态或热点样式按钮
<TouchableOpacity>
<Animated.Image
source={activeImageSource}
style={this.state.animatedStartValue}}
/>
<Image source={nonActiveImageSource}
/>
</TouchableOpacity>
答案 2 :(得分:18)
@bcomerford答案的改进版
//this.state.animatedStartValue = 0;
function cycleAnimation() {
Animated.sequence([
Animated.timing(this.state.animatedStartValue, {
toValue: 1,
duration: 500,
delay: 1000
}),
Animated.timing(this.state.animatedStartValue, {
toValue: 0,
duration: 500
})
]).start(event => {
if (event.finished) {
cycleAnimation();
}
});
}
答案 3 :(得分:4)
尝试这样的事情:
componentDidMount() {
this.bootAnimation();
}
bootAnimation() {
this.animation = Animated.loop(
Animated.timing(this.state.progress, {
toValue: 1,
duration: 5000
})
).start();
}
答案 4 :(得分:0)
您可以设置另一个动画,然后再次调用动画:
我做了一个淡入淡出文本的例子:
textAnimate: function() {
Animated.timing(
this.state.textOpacity,
{
toValue: 0.3,
duration: 500,
}
).start(() => {
Animated.timing(
this.state.textOpacity,
{
toValue: 1,
duration: 500,
}
).start(() => {
this.textAnimate();
});
});
},
componentDidMount: function() {
this.state.textOpacity.setValue(1)
this.textAnimate();
},
答案 5 :(得分:0)
不知道它是否很hacky,但是我用这个:
Animated.spring(this.state.rotation, {
toValue: 5,
stiffness: 220, // the higher value, the faster the animation
damping: 0.000001, // never stop wiggle wiggle wiggle
}).start();
它正在创建春天的动画,从技术上讲,它永远不会停止挥舞。
对于我的大多数情况而言,这就足够了。此外,由于在动画过程中不需要任何JS踩踏动作,因此它具有出色的性能。
如果最终您想优雅地停止它:
Animated.spring(this.state.rotation, {
toValue: 0,
stiffness: 220, // the higher value, the faster the animation
damping: 10, // never stop wiggle wiggle wiggle
}).start();
它会很好地“减速”直到停止。
答案 6 :(得分:0)
这是使用挂钩并将iterations
设置为“ infinity”的无限动画的另一个示例。避免在先前的答案中使用递归,有时在我们进行e2e测试期间会导致时髦的行为。
const rotation = React.useRef(new Animated.Value(0)).current;
function runAnimation() {
return Animated.loop(
Animated.timing(rotation, {
toValue: 1,
duration: 1200,
easing: Easing.linear,
useNativeDriver: true,
}),
{resetBeforeIteration: true, iterations: Number.MAX_SAFE_INTEGER},
);
}
React.useEffect(() => {
const animation = runAnimation();
return () => animation.stop();
}, []);