我是新手,react-native-reanimated并试图了解它的工作原理。下面的代码在屏幕中间呈现一个框。在初始渲染中,该框向右平移 4 秒,之后其位置将重置为屏幕中间。
... imports omitted for brevity
export default class App extends React.Component {
state = {
clock: new Clock(),
translation: new Value(0),
};
onPress = () => {
startClock(this.state.clock);
};
getTranslation = (clock, translation) => {
const state = {
finished: new Value(0),
position: translation,
time: new Value(0),
frameTime: new Value(0),
};
const config = {
duration: 4000,
toValue: new Value(300),
easing: Easing.inOut(Easing.ease),
};
return block([
cond(clockRunning(clock), 0, [
set(state.finished, 0),
set(state.position, 0),
set(state.time, 0),
set(state.frameTime, 0),
startClock(clock),
]),
timing(clock, state, config),
cond(state.finished, set(state.position, 0)),
state.position,
]);
};
render() {
const translation = this.getTranslation(
this.state.clock,
this.state.translation
);
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.onPress}>
<Animated.View
style={{
transform: [
{
translateX: translation,
},
],
width: 100,
height: 100,
backgroundColor: "tomato",
}}
/>
</TouchableOpacity>
</View>
);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
1) 为什么这个框只在初始渲染时向右平移?是什么阻止动画重复?
2) onPress 处理程序不会重新启动动画。为什么?
Kak*_*kar 16
我也在学习react native reanimated,但我会尽量回答你的问题。如果有人想编辑答案,请自由编辑。
- 为什么盒子只在初始渲染时向右平移?是什么阻止动画重复?
当组件安装时,该translateX值为 0,它将位于屏幕的中心(因为正如您所说,它styles.container可能具有将其子组件居中的样式)。
并且由于您要求从getTranslationrender 方法中的函数进行翻译,因此当组件第一次渲染时,将getTranslation调用该函数并评估节点块:
block列表中的第一个节点执行,即cond块。它检查时钟是否正在运行。
timing状态和配置。请记住,state.position设置为 0 并且也config.toValue已经设置为 300。并启动时钟。state.position为 0 和config.toValue300,因此state.position将更新为 1(取决于config.duration)。finished值是否为 1。
position值等于 config 的值时toValue,timing函数将 的值更新finished为 1。position值再次设置为 0。这意味着位置重置为其原始位置。在最后一个节点上,状态position被返回给渲染方法,translation以便为变换保持不变。
由于时钟开始,动画还没有完成,节点块一次又一次地运行。意思是在下一帧,该state.position值将是 2,然后是 3,依此类推,直到state.position等于 300 ( config.toValue)。因此,该框将从屏幕的中心移到右侧。但是,如果您将 设置config.toValue为 -300,则该框将从屏幕的中心移至左侧。
最后,当动画完成时,块的第 3 个节点等于 true,并且state.positionis 再次变为 0(在屏幕中央)。
并且由于您尚未停止时钟(可以使用 完成stopClock(clock)),因此要检查的第一个节点clockRunning(clock)始终为真。同样要重复动画,您必须timing在动画完成后重置所有状态和配置。
所以你必须改变你的节点块:
return block([
cond(
clockRunning(clock),
[
debug('clock is running', clock)
],
[
debug('clock is NOT running', clock),
startClock(clock),
]
),
timing(clock, state, config),
cond(
state.finished,
[
stopClock(clock),
set(state.finished, 0),
set(state.position, 0),
set(state.time, 0),
set(state.frameTime, 0),
startClock(clock),
]
),
state.position,
]);
Run Code Online (Sandbox Code Playgroud)
- onPress 处理程序不会重新启动动画。为什么?
因为时钟没有停止。也因为状态和配置没有被重置。因此,要在按下时启动动画,可以通过多种不同的方式来完成。我将向您展示如何以其中一种方式进行操作,通过这种方式,您可能会更多地了解react-native-reanimated并react-native-gesture-handler使用纯原生动画,而无需过桥。
const getTranslation = ({clock, gestureState, translation}) => {
const state = {
finished: new Value(0),
position: translation,
time: new Value(0),
frameTime: new Value(0),
};
const config = {
duration: 2000,
toValue: new Value(150),
easing: Easing.inOut(Easing.ease),
};
return block([
cond(
clockRunning(clock),
[
debug('clock is running', clock)
],
[
debug('clock is NOT running', clock),
set(state.finished, 0),
set(state.position, 0),
set(state.time, 0),
set(state.frameTime, 0),
startClock(clock),
]
),
timing(clock, state, config),
cond(
state.finished,
stopClock(clock)
),
state.position
])
};
export default class App extends React.Component {
gestureState = new Value(-1)
clock = new Clock()
translation = cond(
eq(this.gestureState, State.ACTIVE), // when you start drag, the state will be ACTIVE
[
debug('active', this.gestureState, State.ACTIVE),
getTranslation({clock: this.clock, translation: new Value(0)})
],
[
debug('not active', this.gestureState, State.ACTIVE)
],
)
onStateChange = event([
{
nativeEvent: {
state: this.gestureState
}
}
])
render() {
return (
<View style={styles.container}>
<PanGestureHandler
onGestureChange={this.onStateChange}
onHandlerStateChange={this.onStateChange}>
<Animated.View style={[
styles.box,
{
transform: [{
translateX: this.translation
}]
}
]}/>
</PanGestureHandler>
</View>
)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6170 次 |
| 最近记录: |