我正在尝试像这样在 React Native 上构建图像比较滑块https://www.npmjs.com/package/react-compare-slider。我几乎以纵向模式构建组件。但是,当我尝试在横向模式下执行相同操作时,滑块拖动无法按预期工作。
这是代码
import React, {useState, useEffect} from 'react';
import {
View,
Image,
PanResponder,
Animated,
StyleSheet,
Dimensions,
ActivityIndicator,
} from 'react-native';
import Orientation from 'react-native-orientation-locker';
// import {CompareSlider} from 'react-native-compare-slider';
const ImageComparisonSlider = ({
leftImage,
rightImage,
initialPosition = 0.5,
}) => {
const [sliderPosition, setSliderPosition] = useState(
new Animated.Value(initialPosition * Dimensions.get('window').width),
);
const [leftImageLoaded, setLeftImageLoaded] = useState(false);
const [rightImageLoaded, setRightImageLoaded] = useState(false);
const [isDeviceRotated, setisDeviceRotated] = useState(false);
const panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: (_, gestureState) => {
const newPosition = Math.max(
0,
Math.min(gestureState.moveX, Dimensions.get('window').width),
);
sliderPosition.setValue(newPosition);
},
});
const renderImage = (imageUri, onLoadEnd, style) => (
<Image
source={{uri: imageUri}}
style={style}
resizeMode="cover"
onLoadEnd={onLoadEnd}
/>
);
const bothImagesLoaded = leftImageLoaded && rightImageLoaded;
const onOrientationDidChange = orientation => {
if (orientation == 'LANDSCAPE-LEFT' || orientation == 'LANDSCAPE-RIGHT') {
setisDeviceRotated(true);
} else {
setisDeviceRotated(false);
}
};
useEffect(() => {
Orientation.addOrientationListener(onOrientationDidChange);
return () => Orientation.removeOrientationListener(onOrientationDidChange);
}, []);
return (
<View
style={{
width: isDeviceRotated ? '50%' : '100%',
height: !isDeviceRotated ? '50%' : '100%', // Adjust as needed
position: 'relative',
}}>
{!bothImagesLoaded && (
<View style={styles.loaderContainer}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
)}
{bothImagesLoaded && (
<>
{renderImage(rightImage, () => {}, styles.image)}
<Animated.View
style={[
styles.leftImageContainer,
{
width: sliderPosition,
},
]}>
{renderImage(leftImage, () => {}, styles.leftImage)}
</Animated.View>
<Animated.View
style={[styles.sliderLine, {left: sliderPosition}]}
{...panResponder.panHandlers}>
<View style={styles.sliderHandle} />
</Animated.View>
</>
)}
<Image
source={{uri: leftImage}}
style={styles.hiddenImage}
onLoad={() => setLeftImageLoaded(true)}
/>
<Image
source={{uri: rightImage}}
style={styles.hiddenImage}
onLoad={() => setRightImageLoaded(true)}
/>
</View>
);
};
const styles = StyleSheet.create({
image: {
width: '100%',
height: '100%',
},
leftImageContainer: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
overflow: 'hidden',
},
leftImage: {
width: Dimensions.get('window').width,
height: '100%',
},
sliderLine: {
position: 'absolute',
top: 0,
bottom: 0,
width: 3,
backgroundColor: 'white',
},
sliderHandle: {
position: 'absolute',
top: '50%',
left: -10,
width: 20,
height: 20,
borderRadius: 10,
backgroundColor: 'white',
transform: [{translateY: -10}],
},
loaderContainer: {
...StyleSheet.absoluteFillObject,
justifyContent: 'center',
alignItems: 'center',
},
hiddenImage: {
width: 0,
height: 0,
},
});
export default ImageComparisonSlider;
请也检查一下:https://www.loom.com/share/4dc8d887fe1449268c8c944aa25f6dbd
如果我得到解决方案,这将非常有帮助,请告诉我是否有任何其他软件包可以解决此问题
提前致谢!
当屏幕改变方向时,您可能需要重置窗口宽度。看起来您已经更新了状态,但窗口宽度已初始化,但如果您切换方向则永远不会更新。
const [windowWidth, setWindowWidth] = useState(Dimensions.get("window").width);
const onOrientationDidChange = orientation => {
if (orientation == 'LANDSCAPE-LEFT' || orientation == 'LANDSCAPE-RIGHT') {
setisDeviceRotated(true);
} else {
setisDeviceRotated(false);
}
setWindowWidth(Dimensions.get("window").width);
};
您还可以尝试使用
useWindowDimensions
钩子,例如 const width = useWindowDimensions().width;