我对react-native中的动画完全陌生,我正在尝试使用react-native-reanimated库创建一个动态的脉动按钮。
动画的概念对我来说还不是很清楚,但通过修改其他人的代码,我非常接近我想要创建的东西。
我想让这个脉动的动画持续下去。目前,它在跳动,然后停止。如果能帮上忙我会很感激的。我包含了代码和零食,让您可以看到运行的示例。请记住,我只是修改了别人的代码,所以我确信这段代码中有一些不必要的东西。我在按这个按钮的同时也在学习。
这里有一个小吃的链接:https://snack.expo.io/@imsam67/reanimated-test
下面是代码:
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import Animated from 'react-native-reanimated';
const {
divide,
set,
cond,
startClock,
stopClock,
clockRunning,
block,
spring,
debug,
Value,
Clock,
} = Animated;
function runSpring(clock, value, dest) {
const state = {
finished: new Value(0),
velocity: new Value(0),
position: new Value(0),
time: new Value(0),
};
const config = {
toValue: new Value(0),
damping: 10,
mass: 5,
stiffness: 101.6,
overshootClamping: false,
restSpeedThreshold: 0.001,
restDisplacementThreshold: 0.001,
};
return block([
cond(clockRunning(clock), 0, [
set(state.finished, 0),
set(state.time, 0),
set(state.position, value),
set(state.velocity, -2500),
set(config.toValue, dest),
startClock(clock),
]),
spring(clock, state, config),
cond(state.finished, debug('stop clock', stopClock(clock))),
state.position,
]);
}
export default class Example extends Component {
constructor(props) {
super(props);
const clock = new Clock();
this._trans = runSpring(clock, 10, 150);
}
componentDidMount() {}
render() {
return (
<View style={styles.container}>
<Animated.View
style={[styles.circle, { borderWidth: divide(this._trans, 5) }]}>
</Animated.View>
</View>
);
}
}
const BOX_SIZE = 100;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black',
},
circle: {
backgroundColor: "white",
borderColor: "red",
borderRadius: 150,
height: 150,
width: 150
}
});发布于 2021-02-12 09:29:25
使此动画循环的快速方法是将阻尼设置为0。这将使弹簧动画无限期地运行。
const config = {
toValue: new Value(0),
damping: 0, // changed to 0
mass: 5
stiffness: 101.6,
overshootClamping: false,
restSpeedThreshold: 0.001,
restDisplacementThreshold: 0.001,
};但是,您可能希望更改borderWidth样式以除以更大的数字,以防止边界半径过大。
<Animated.View
style={[styles.circle, { borderWidth: divide(this._trans, 25) }]}>
</Animated.View>您可以找到修改后的零食here。
对于像这样的重复动画,您还可以考虑使用Lottie,它的实现要简单得多,但灵活性较差。
此外,您可以考虑使用react原生动画中的loop,这应该允许您设置边界半径。
发布于 2021-10-28 16:23:59
另一种更受控制的方法是使用重新激活的1.x.x:
const [clock] = useState(() => new Clock());
const loopingValue = useMemo(() => {
const state = {
finished: new Value(0),
position: new Value(0),
time: new Value(0),
frameTime: new Value(0),
};
const config = {
duration: new Value(2000),
toValue: new Value(1),
easing: Easing.linear,
};
const value = block([
// start right away
startClock(clock),
// process your state
timing(clock, state, config),
// when over (processed by timing at the end)
cond(state.finished, [
// we stop
stopClock(clock),
// set flag ready to be restarted
set(state.finished, 0),
// same value as the initial defined in the state creation
set(state.position, 0),
// very important to reset this ones !!! as mentioned in the doc about timing is saying
set(state.time, 0),
set(state.frameTime, 0),
// and we restart
startClock(clock),
]),
state.position,
]);
return interpolate(value, {
inputRange: [0, 0.5, 1],
outputRange: [0, 1, 0],
});
}, [clock]);这里的很多代码都是从github线程复制过来的:https://github.com/software-mansion/react-native-reanimated/issues/162
https://stackoverflow.com/questions/66164759
复制相似问题