Javascript PanResponder捕捉动画。在第二次拖动时查看回原始位置
我已经创建了一个PanResponder来垂直移动Javascript PanResponder捕捉动画。在第二次拖动时查看回原始位置,javascript,reactjs,react-native,Javascript,Reactjs,React Native,我已经创建了一个PanResponder来垂直移动动画.View。当我从它的原始位置移动它时,它工作正常,但一旦我再次移动它,它会捕捉回其原始位置,然后相对于触摸移动 我正在将响应程序直接解包到动画.View,这会导致这种行为吗 下面是我如何定义PanResponder的: this.state = { drag: new Animated.ValueXY() }
动画.View
。当我从它的原始位置移动它时,它工作正常,但一旦我再次移动它,它会捕捉回其原始位置,然后相对于触摸移动
我正在将响应程序直接解包到动画.View
,这会导致这种行为吗
下面是我如何定义PanResponder的:
this.state = {
drag: new Animated.ValueXY()
}
this._responder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: Animated.event([null, {
dy: this.state.drag.y
}]),
onPanResponderRelease: (e, coords) => {
...
}
})
并将响应程序应用到我的动画视图中
:
<Animated.View {...this._responder.panHandlers} style={this.state.drag.getLayout()}>
// children go here
</Animated.View>
//孩子们到这里来
谢谢首先,让我们看看发生这种情况的原因:
- 您的
回调读取手势的onPanResponderMove
(delta Y),它提供自手势开始以来垂直移动的像素量。这意味着每次你开始一个新的手势,增量从0开始dy
- 另一方面,
只需将AnimatedXY#getLayout()
值映射到样式属性y
。这意味着当触摸开始时top
设置为0时,元素将反弹回其初始非偏移位置y
setOffset
保留上一次偏移位置,然后使用setValue
将初始增量重置为0。这可以在手势开始时完成,例如在onPanResponderGrant
上:
this._responder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderGrant: (evt, gestureState) => {
this.state.drag.setOffset(this.state.drag.__getValue());
this.state.drag.setValue({ x: 0, y: 0 });
},
onPanResponderMove: Animated.event([
null,
{ dy: this.state. drag.y }
])
});
如您所见,我们在这里使用的是“private”方法\uu getValue()
。通常,不建议同步读取Animated.value的值,因为动画可能会卸载到本机线程,并且该值可能不是最新的。在这里,在手势的开始,它应该是安全的
作为旁注,由于只在Y轴上移动元素,因此不一定需要使用二维
动画.ValueXY
,因为基本动画.values
就足够了。如果您重构代码以使用值,则只需调用拖动.extractOffset()
即可重置偏移量。它的作用相同,但在AnimatedXY
上似乎不可用。您只需在onPanResponderGrant
中调整偏移量,如
onPanResponderGrant: (e, gestureState) => {
this.state.drag.setOffset({x: this.state.drag.x._value, y: this.state.drag.y._value});
this.state.drag.setValue({x: 0, y: 0})
},
但也要确保在释放panResponder时展平偏移量,否则在第三次或第四次拖动时会出现一些小故障(位置将根据以前的偏移量重置)
onPanResponderRelease: (e, {vx, vy}) => {
this.state.drag.flattenOffset()
}
感谢您花时间回答这个伟大的答案,并正确地解释正在发生的事情。最后,我使用与您提供的方法类似的方法解决了这个问题。