gpt4 book ai didi

javascript - React Native Animated - 在触摸位置开始动画

转载 作者:行者123 更新时间:2023-11-30 20:12:14 26 4
gpt4 key购买 nike

我正在研究 React Native 中的动画。想要构建一个允许用户随时触摸屏幕的屏幕。当他们这样做时,一个圆圈应该出现在他们手指的位置,并跟随它。当他们释放时,圆圈应该缩小到什么都没有。

我开始关注 this tutorial ,这是一个类似 Spring 的动画,您可以在其中拖动一个预先存在的正方形(从屏幕中央开始),它会在释放时弹回。

在我的例子中,圆应该没有预先存在的位置,这就是问题所在。如果我初始化我的组件状态,比如说,pan: new Animated.ValueXY(),然后触摸屏幕,圆圈从左上角开始,不是我的手指在哪里。我尝试了各种其他解决方案,全部替换了下面 onPanResponderGrant 方法中的注释行,但似乎无法弄清楚。

如何让组件简单地跟踪我的手指而不从任何地方开始或返回的动画?

这是组件的代码:

class FollowCircle extends React.Component {
constructor(props) {
super(props);

this.state = {
pan: new Animated.ValueXY(),
scale: new Animated.Value(0)
};
}

componentWillMount() {
this._panResponder = PanResponder.create({
onStartShouldSetPanResponderCapture: () => true,
onMoveShouldSetPanResponderCapture: () => true,

onPanResponderGrant: (e, gestureState) => {
// This is the line I'm playing with
this.state.pan.setValue({ x: this.state.pan.x._value, y: this.state.pan.y._value });

Animated.spring(
this.state.scale,
{ toValue: 1, friction: 3 },
).start();
},

onPanResponderMove: Animated.event([
null, { dx: this.state.pan.x, dy: this.state.pan.y }
]),

onPanResponderRelease: (/* e, gestureState */) => {
this.state.pan.flattenOffset();
Animated.spring(
this.state.scale,
{
toValue: 0,
friction: 10,
restDisplacementThreshold: 1
},
).start();
}
});
}

render() {
const { pan, scale } = this.state;
const circleStyles = {
backgroundColor: 'black',
width: 50,
height: 50,
borderRadius: 25,
transform: [
{ translateX: pan.x },
{ translateY: pan.y },
{ scale }
]
};

return (
<AppWrapper navigation={ this.props.navigation }>
<Animated.View
style={ {
flex: 1,
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
backgroundColor: 'white'
} }
{ ...this._panResponder.panHandlers }
>
<Animated.View
style={ circleStyles }
/>
</Animated.View>
</AppWrapper>
);
}
};

这是我的替代尝试(替换注释行):

this.state.pan.setValue({ x: gestureState.x0, y: gestureState.y0 });

还有这个:

  if (this.state.pan) {
this.state.pan.setValue({ x: this.state.pan.x._value, y: this.state.pan.y._value });
} else {
this.setState({ pan: new Animated.ValueXY(gestureState.x0, gestureState.y0) });
}

两者的行为似乎相似,每次移动后都会重置左上角的圆圈位置,并且不会完全跟踪我的手指位置,除非我从那个原点开始触摸。

关于如何正确执行此操作的任何想法?

最佳答案

我最终通过将 panResponder 替换为页面大小的 TouchableHighlightonTouch 事件来解决这个问题。

该事件触发了以下函数,该函数获取 nativeEvent.pageXpageY 位置,并使用它们。我不得不对 y 位置做一些细微的改动,以使其在手机上工作:

  triggerSwipe({ nativeEvent }) {
const coordinates = { x: nativeEvent.pageX, y: nativeEvent.pageY };
const self = this;
if (!this.state.animating) {
this.setState({
x: coordinates.x,
y: coordinates.y + (this.windowHeight / 2.5),
animating: true
}, () => {
Animated.timing(
self.state.scale,
{ toValue: 20, duration: 600 },
).start(() => {
this.setState({
scale: new Animated.Value(0.01), // See Notes.md for reasoning
colorIndex: this.state.colorIndex + 1,
animating: false
});
});
});
}

动画圆圈是 TouchableHighlight 内的一个 Animated.View,输入触摸坐标。

关于javascript - React Native Animated - 在触摸位置开始动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52285873/

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