如何解决Animated.ValueXY.setValue() 有时不会设置正确的值
我正在使用 Expo 构建一个图像裁剪器,使用 React Native 的 Animated
和 PanResponder
API。用户应该能够在裁剪方块内拖动图像以选择要裁剪的区域。
PanResponder
的 onPanResponderMove()
方法使用 Animated.ValueXY
设置 setValue()
值,在 onPanResponderRelease()
方法中我们检查用户没有拖到外面允许的面积。如果有,ValueXY
的值将设置为允许区域内边缘的值。
包含 Image 组件的 <Animated.View />
使用这些 X 和 Y 值根据拖动手势定位图像。这些值被限制在允许范围之外。
目前有一个奇怪的问题,如果用户拖动很远的距离,图片会跳转到错误的位置。例如,如果您一直在图像的顶部,然后用一个手势将其向下拖动到另一端,则图像位置会跳到中心。如果您随后触摸屏幕并仅移动一个增量,则图像位置会跳转到正确位置。
我不明白为什么会发生这种情况,如果有任何想法/帮助,我将不胜感激!
谢谢?
import React,{ useRef } from 'react';
import { View,Animated,TouchableOpacity,TouchableWithoutFeedback,Image,Text,PanResponder,ActivityIndicator,StyleSheet,useWindowDimensions } from 'react-native';
const App = (props) => {
const screenWidth = useWindowDimensions().width;
const screenHeight = useWindowDimensions().height;
const pan = useRef(new Animated.ValueXY()).current;
const panResponder = PanResponder.create({
onMoveShouldSetPanResponder: () => true,onPanResponderGrant: () => {
pan.setoffset({
x: pan.x._value,y: pan.y._value
});
},onPanResponderMove: (e,gestureState) => {
pan.setValue({ x: gestureState.dx,y: gestureState.dy })
},onPanResponderRelease: (e,gestureState) => {
let distanceFromCenter;
let positivizeddistance;
distanceFromCenter = pan.y._value + pan.y._offset;
if (distanceFromCenter < 0) positivizeddistance = distanceFromCenter * -1;
else positivizeddistance = distanceFromCenter;
if (positivizeddistance >= allowabledistance) {
const newValue = {
x:
gestureState.dx,y:
distanceFromCenter < 0
? Math.ceil(allowabledistance * -1)
: Math.floor(allowabledistance)
};
pan.setValue(newValue);
} else {
pan.flattenOffset();
}
},});
const imageDimensions = {
height: 1920,width: 1080,};
const { width,height } = imageDimensions;
const imageScreenRatio = width / screenWidth;
const allowabledistance = Math.floor((height - width) / 2 / imageScreenRatio);
return (
<View style={styles.container}>
<Animated.View
{...panResponder.panHandlers}
style={{
transform:
[
{
translateX: 0
},{
translateY: pan.y
.interpolate({
inputRange: [allowabledistance * -1,allowabledistance],outputRange: [allowabledistance * -1,extrapolate: 'clamp',})
}
],}}
>
<TouchableWithoutFeedback>
<View>
<Image
source={{ uri: 'https://i.pinimg.com/originals/0b/ac/f6/0bacf62a4bd456d02d02c6b8a5c98f67.jpg' }}
style={styles.image}
resizeMode="contain"
/>
</View>
</TouchableWithoutFeedback>
</Animated.View>
<View
style={{
...styles.bar,height: (screenHeight - screenWidth) / 2,top: 0,}}
/>
<View
style={{
...styles.bar,bottom: 0,}}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: 'black',},image: {
width: '100%',height: '100%',bar: {
position: 'absolute',backgroundColor: 'black',opacity: 0.6,width: '100%',});
export default App;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。