如何在React Native中修复横向模式下的图像比较滑块位置?

问题描述 投票:0回答:1

我正在尝试像这样在 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

如果我得到解决方案,这将非常有帮助,请告诉我是否有任何其他软件包可以解决此问题

提前致谢!

javascript react-native react-native-animatable
1个回答
0
投票

当屏幕改变方向时,您可能需要重置窗口宽度。看起来您已经更新了状态,但窗口宽度已初始化,但如果您切换方向则永远不会更新。

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;

© www.soinside.com 2019 - 2024. All rights reserved.