Search code examples
javascriptcssreactjsreact-nativereact-native-stylesheet

How to keep absolute Touchables consistent across various screen sizes?


I have a screen with an png image, I am trying to add touchables on the joints. I want to keep touchabes consistent across screen sizes

Image

This is my code

import { 
  Platform,
  ImageBackground,
  View,
  StyleSheet,
  TouchableOpacity,
  Dimensions,
  PixelRatio
} from 'react-native';

const { width, height } = Dimensions.get('window');
const radius = PixelRatio.roundToNearestPixel(width / 2);
const getWidthPercent = (percent) => (width * percent) / 100;
const getHeightPercent = (percent) => (height * percent) / 100;


<View style={styles.container}>
   <ImageBackground
       style={styles.image}
       resizeMode="contain"
       source={require('../../assets/skeleton-large.png')}>       
        <TouchableOpacity style={styles.leftShoulder}></TouchableOpacity>
        <TouchableOpacity style={styles.rightShoulder}></TouchableOpacity>
           
  </ImageBackground>
</View>

jointStyleDefaults

const jointStyleDefaults = {
  backgroundColor: '#CC41444B',
  position: 'absolute',
  width: radius * 0.3, // to keep the size of circle responsive across screen size
  height: radius * 0.3,
  borderRadius: radius
};

StyleSheet

const styles = StyleSheet.create({
  container: {
    flex: 1,   
  },
  image: {
    flex: 1
  },
  leftShoulder: {
    ...jointStyleDefaults,
    top: getHeightPercent(13),
    bottom: 0,
    right: 0,
    left:  getWidthPercent(25) 
  },
  rightShoulder: {
    ...jointStyleDefaults,
    top: getHeightPercent(13),
    bottom: 0,
    right: 0,
   left:  getWidthPercent(60) 
  },  
});

I want to keep circular images at fixed point on png across screen sizes. How do i achieve this?


Solution

  • I think you should use percent I can't say correct percent but you need to try with percent then I think we will get the current position. I am adding a quick example but you need to retrieve correct percent by your self. But I think it's the correct way.

    
    const { width, height } = Dimensions.get('window');
    
    const getWidthPercent = percent => width * percent / 100;
    
    // I think you need to subtract ActionBar (Top title bar) and bottom tab bar height from the height then calculate percentage for more accuracy.
    const getHeightPercent = percent => height * percent / 100;
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,   
      },
      image: {
        flex: 1,
      },
      leftShoulder: {
        ...jointStyleDefaults,
        top: getHeightPercent(30),
        bottom: 0,
        right: 0,
        left: getWidthPercent(5),
      },
      rightShoulder: {
        ...jointStyleDefaults,
        top: getHeightPercent(30),
        bottom: 0,
        right: 0,
        left: getWidthPercent(85),
      },
    });