用新动画重复动画 api
Repeat animation with new animated api
React-native introduce new 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>
);
}
}
但效果不是很好。
如有任何建议,我们将不胜感激。
Animated
api 似乎暂时不支持 'looping'。
我设法在动画结束后再次启动动画。
startAnimation() {
Animated.timing(this._animatedValue, {
toValue: 100,
duration: 1000,
}).start(() => {
this.startAnimation();
});
}
期待更好的解决方案...
我用的是sequence的方法,传一个动画数组循环然后repeat这个函数
//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();
});
}
如果我自己切换动画,它会淡出 in/out,但是我将它放在底座上以模仿活动状态或热点式按钮
<TouchableOpacity>
<Animated.Image
source={activeImageSource}
style={this.state.animatedStartValue}}
/>
<Image source={nonActiveImageSource}
/>
</TouchableOpacity>
您可以设置另一个动画然后再次调用动画:
我做的一个淡入淡出文本的例子:
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();
},
@bcomerford 回答的改进版本[=11=]
//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();
}
});
}
现在 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()
尝试这样的事情:
componentDidMount() {
this.bootAnimation();
}
bootAnimation() {
this.animation = Animated.loop(
Animated.timing(this.state.progress, {
toValue: 1,
duration: 5000
})
).start();
}
不确定它是否有问题,但我使用这个:
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();
它正在创建 spring 永远不会(从技术上讲,在非常非常长的时间内)停止挥手的动画。
对于我的大多数情况来说,这就足够了。它还具有出色的性能,因为它在动画期间不需要任何 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();
它会很好地 'slow down' 直到它停止。
这是另一个使用钩子和 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();
}, []);
React-native introduce new 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>
);
}
}
但效果不是很好。
如有任何建议,我们将不胜感激。
Animated
api 似乎暂时不支持 'looping'。
我设法在动画结束后再次启动动画。
startAnimation() {
Animated.timing(this._animatedValue, {
toValue: 100,
duration: 1000,
}).start(() => {
this.startAnimation();
});
}
期待更好的解决方案...
我用的是sequence的方法,传一个动画数组循环然后repeat这个函数
//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();
});
}
如果我自己切换动画,它会淡出 in/out,但是我将它放在底座上以模仿活动状态或热点式按钮
<TouchableOpacity>
<Animated.Image
source={activeImageSource}
style={this.state.animatedStartValue}}
/>
<Image source={nonActiveImageSource}
/>
</TouchableOpacity>
您可以设置另一个动画然后再次调用动画:
我做的一个淡入淡出文本的例子:
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();
},
@bcomerford 回答的改进版本[=11=]
//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();
}
});
}
现在 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()
尝试这样的事情:
componentDidMount() {
this.bootAnimation();
}
bootAnimation() {
this.animation = Animated.loop(
Animated.timing(this.state.progress, {
toValue: 1,
duration: 5000
})
).start();
}
不确定它是否有问题,但我使用这个:
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();
它正在创建 spring 永远不会(从技术上讲,在非常非常长的时间内)停止挥手的动画。
对于我的大多数情况来说,这就足够了。它还具有出色的性能,因为它在动画期间不需要任何 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();
它会很好地 'slow down' 直到它停止。
这是另一个使用钩子和 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();
}, []);