Как правильно расположить дочерние элементы масштабируемого компонента? Щепотка, чтобы увеличить с фиксированным размером детей - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь выяснить, как реализовать функцию масштабирования с помощью ImageCackground с детьми. Мне удалось масштабировать изображение и соответственно масштабировать детей, но по какой-то причине дети меняют свое положение, когда я увеличиваю масштаб. Рабочий пример: https://snack.expo.io/SbrYV_HU5

обработчики:

     const uri = "https://image.shutterstock.com/image-illustration/snow-falling-stock-image-black-260nw-1519161953.jpg"

      const children = [
        // x and y are % values
         {id:1, x: 50, y: 50, uri: "https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcTBRKq5srwCKehVS0GDjwpX46jYdYUr46hVgx7BTlQbgTTbDo6O&usqp=CAU"}
      ]

  const AnimatedImage = Animated.createAnimatedComponent(ImageBackground)
  let _baseScale = new Animated.Value(1);
  let _pinchScale = useRef(new Animated.Value(1));
  let _lastScale = useRef(1);
  let _scale = Animated.multiply(_baseScale, _pinchScale.current)
  let iconScale = Animated.divide(new Value(1), _scale)
  const _onPinchGestureEvent = Animated.event(
    [{ nativeEvent: { scale: _pinchScale.current } }],
    { useNativeDriver: true }
  );

  const _onPinchHandlerStateChange = event => {
    if (event.nativeEvent.oldState === State.ACTIVE) {
      _lastScale.current *= event.nativeEvent.scale;
      _baseScale.setValue(_lastScale.current);
      _pinchScale.current.setValue(1);
    }
  };

рендер:

return (
    <View style={[styles.container]} >
          < PinchGestureHandler
            onGestureEvent={_onPinchGestureEvent}
            onHandlerStateChange={_onPinchHandlerStateChange}
          >
            <Animated.View style={[styles.size]}>
              <AnimatedImage
                source={{ uri }}
                style={[
                  styles.image,
                  {width: 200, height: 200},
                  {transform: [{ scale: _scale }]}
                ]}>
                {children.map((child) => {
                  return (
                    <Animated.View style={[
                      {transform: [{ scale: iconScale }]},
                      { top: `${child.y}%`, left: `${child.x}%` }
                      ]}
                    key={child.id}
                    >
                    <Animated.Image 
                        source={{uri: 'https://s3.amazonaws.com/media-p.slid.es/uploads/alexanderfarennikov/images/1198519/reactjs.png'}}
                      style={styles.child} />
                    </Animated.View>
                      )
                })}
              </AnimatedImage>
            </Animated.View>
          </PinchGestureHandler>
    </View>
  )

стили:

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    overflow: 'hidden'
  },
  image: {
    ...StyleSheet.absoluteFillObject,
    width: undefined,
    height: undefined,
    resizeMode: "cover",
  },
  size: {
    width: 300,
    height: 300
  },
  child: {
    transform: [
        { translateX: -iconWidth / 2 },
        { translateY: -iconWidth / 2 }
    ],
    width: iconWidth,
    height: iconWidth
  }
})
...