gpt4 book ai didi

react-native - 了解 react native 复活的执行

转载 作者:行者123 更新时间:2023-12-03 16:03:25 27 4
gpt4 key购买 nike

我是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>
);
}
}

我的问题是:

1) Why does the box only translate to the right on the initial render? What prevents the animation from repeating?

2) The onPress handler doesn't restart the animation. Why?

最佳答案

我也正在学习对本地复活的 react ,但我会尽力回答您的问题。如果有人想编辑答案,请自由编辑。

  1. Why does the box only translate to the right on the initial render? What prevents the animation from repeating?


装入组件时, translateX值为0,它将位于屏幕的中央(因为您已经说过, styles.container可能具有将其子组件居中的样式)。

并且由于您要从render方法中的 getTranslation函数进行翻译,因此当组件首次渲染时,将调用 getTranslation函数并评估一个节点块:
  • 执行block列表中的第一个节点,即cond块。它检查时钟是否正在运行。
  • 如果时钟正在运行,则什么也不做。
  • 另外,设置timing的状态和配置。请记住,state.position设置为0,并且config.toValue已经设置为300。然后开始计时。
  • 为计时功能提供了状态及其配置。
  • 它会在时间范围内更新的位置。在这里,由于已将state.position设置为0并将config.toValue设置为300,因此state.position更新为1(取决于config.duration)。
  • 同样,如果时钟在运行,它也会在下一个帧中加入要评估的回调。
  • 在阻止列表的倒数第二个节点内,它检查状态的finished值是否为1。
  • 当动画完成或更好时,当state的position的值等于config的toValue的值时,timing函数将finished的值更新为1。
  • 因此,当动画完成时,状态的position值将再次设置为0。这意味着该位置将重置为其原始位置。
  • 在最后一个节点上,状态的position返回到render方法的translation常量进行转换。

    由于时钟已开始并且动画尚未完成,因此节点块一次又一次运行。在下一帧中,state.position的值为2,之后为3,依此类推,直到state.position等于300(config.toValue)。因此,该框将从屏幕的中心移到右侧。但是,如果您将config.toValue设置为-300,则该框将从屏幕的中心移到左侧。

    最后,当动画结束时,该块的第三个节点等于true,并且state.position再次为0(在屏幕中央)。

    而且由于您还没有停止时钟(可以使用stopClock(clock)完成),因此检查clockRunning(clock)的第一个节点始终为true。同样要重复动画,您必须在动画完成后重置所有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,
    ]);

    1. The onPress handler doesn't restart the animation. Why?


    因为时钟没有停止。也因为状态和配置未重置。因此,要在按下动画时开始动画,可以用许多不同的方法来完成。我将向您展示如何使用一种方式,这种方式可能是您将对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>
    )
    }
    }

    关于react-native - 了解 react native 复活的执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53687074/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com