在 react-native-reanimated 中继续循环动画
Keep looping an animation in react-native-reanimated
我对 react-native
中的动画完全陌生,我正在尝试使用 react-native-reanimated
库创建动画脉动按钮。
动画概念对我来说还不是很清楚,但是通过修改别人的代码,我已经非常接近我想要创建的东西了。
我想让这个脉动的动画连续不断。目前,它脉动然后停止。我会很感激一些帮助。我包括了代码和点心,供您查看 运行 示例。请记住,我只是修改了别人的代码,所以我确信这段代码中有些东西是不必要的。我在使用此按钮时正在学习。
这里有 link 点心: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
}
});
使此动画循环的一种快速方法是将阻尼设置为 0。这将使 spring 动画无限期地播放。
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 Native Animations 中的 loop,它应该允许您设置边框半径。
另一种通过重新激活 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
我对 react-native
中的动画完全陌生,我正在尝试使用 react-native-reanimated
库创建动画脉动按钮。
动画概念对我来说还不是很清楚,但是通过修改别人的代码,我已经非常接近我想要创建的东西了。
我想让这个脉动的动画连续不断。目前,它脉动然后停止。我会很感激一些帮助。我包括了代码和点心,供您查看 运行 示例。请记住,我只是修改了别人的代码,所以我确信这段代码中有些东西是不必要的。我在使用此按钮时正在学习。
这里有 link 点心: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
}
});
使此动画循环的一种快速方法是将阻尼设置为 0。这将使 spring 动画无限期地播放。
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 Native Animations 中的 loop,它应该允许您设置边框半径。
另一种通过重新激活 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