Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make React Native's ScrollView initial zoom to not be 1?

I want to put content (multiple images vertically arranged) in a React Native ScrollView (iOS only for now, Android will come later) that is bigger than the phone's screen, and start zoomed out so that it is all visible at the same time.

Are there any good examples of using ScrollView.scrollResponderZoomTo in a componentDidMount call that zooms out to fit content in the screen, something like

<ScrollView
  style={{width: 500, height: 1000}}
  // + whatever other properties make this work required way
>
  <View style={{width: 2000, height: 5000}}>
    <Image style={{width: 2000, height: 2000}} source={.....}/>
    <Image style={{width: 2000, height: 3000}} source={.....}/>
  </View>
</ScrollView>

I tried setting the 'zoomScale' property, but that seems to be ignored and always uses the value 1.

According to this issue (https://github.com/facebook/react-native/issues/2176) there is a scrollResponderZoomTo function that can be used, but when I try to use it, it seems that no matter what values I give it it zooms out much too far and off center.

The F8 sample app has a ZoomableImage module (https://github.com/fbsamples/f8app/blob/b5df451259897d1838933f01ad4596784325c2ad/js/tabs/maps/ZoomableImage.js) which uses the Image.resizeMode.contain style to make an image fit the screen, but that loses the quality of image, so when you zoom in it gets blurry.

like image 928
Shane O Sullivan Avatar asked Apr 22 '16 05:04

Shane O Sullivan


1 Answers

This may not be the way you intended to do this, but a possible solution:

You may get the devices height and width (var {height, width} = Dimensions.get('window')) and you know your image sizes,so you may easily calculate the needed width and height, let's call them var neededWidth, neededHeight;. You may then calculate the zoom to which you would like to zoom out: var zoom = Math.min(height / neededHeight, width / neededWidth);.

With these values in place, you may set an Animated value for the zoom, starting at 1 ending at zoom like this in your componentWillMount:

Animated.timing(
   this.state.animatedZoom,
   {toValue: zoom}
 ).start(); 

The constructor would look like this:

constructor(props) {
  super(props);
  this.state = {
    animatedZoom: new Animated.Value(1),
  };
}

The render function would look like this (reference for transform can be found here):

<ScrollView
  style={{width: 500, height: 1000, transform: [{ scale: this.state.animatedZoom }]}}
>
  <View style={{width: 2000, height: 5000}}>
    <Image style={{width: 2000, height: 2000}} source={.....}/>
    <Image style={{width: 2000, height: 3000}} source={.....}/>
  </View>
</ScrollView>
like image 153
Daniel Schmidt Avatar answered Sep 24 '22 02:09

Daniel Schmidt