1import { 2 Image, 3 ImageContentFit, 4 ImageContentPosition, 5 ImageContentPositionString, 6} from 'expo-image'; 7import { ScrollView, StyleSheet, Text, View } from 'react-native'; 8 9import HeadingText from '../../components/HeadingText'; 10import { Colors } from '../../constants'; 11 12const CONTENT_FITS = [ 13 ImageContentFit.COVER, 14 ImageContentFit.CONTAIN, 15 ImageContentFit.FILL, 16 ImageContentFit.NONE, 17 ImageContentFit.SCALE_DOWN, 18]; 19 20const CONTENT_POSITIONS: ImageContentPositionString[] = [ 21 'center', 22 'top', 23 'right', 24 'bottom', 25 'left', 26 'top center', 27 'top right', 28 'top left', 29 'right center', 30 'right top', 31 'right bottom', 32 'bottom center', 33 'bottom right', 34 'bottom left', 35 'left center', 36 'left top', 37 'left bottom', 38]; 39 40type ContentFitExample = { 41 size: [number, number]; 42 position?: ImageContentPosition; 43}; 44 45const EXAMPLES: ContentFitExample[] = [ 46 { 47 size: [1500, 1000], 48 }, 49 { 50 size: [300, 200], 51 }, 52 { 53 size: [200, 300], 54 }, 55 { 56 size: [240, 160], 57 position: { top: 10, left: 20 }, 58 }, 59 { 60 size: [240, 160], 61 position: { top: 0, right: 0 }, 62 }, 63 { 64 size: [240, 160], 65 position: { bottom: 5, left: 10 }, 66 }, 67 { 68 size: [240, 160], 69 position: { bottom: '10%', right: '10%' }, 70 }, 71 { 72 size: [240, 160], 73 position: { left: '15%' }, 74 }, 75 { 76 size: [240, 160], 77 position: { top: '-50%', right: '10%' }, 78 }, 79]; 80 81function sourceWithSize(size: [number, number]): string { 82 return `https://picsum.photos/seed/138/${size[0]}/${size[1]}`; 83} 84 85function renderExample(contentFit: ImageContentFit, example: ContentFitExample, index: number) { 86 const sizeText = example.size.join(' x '); 87 const positionText = example.position 88 ? JSON.stringify(example.position).replaceAll(/[{}"]/g, '').replaceAll(/[:,]/g, ' ') 89 : null; 90 91 return ( 92 <View key={index} style={styles.imageContainer}> 93 <Image 94 style={styles.image} 95 source={{ uri: sourceWithSize(example.size) }} 96 contentFit={contentFit} 97 contentPosition={example.position} 98 /> 99 <Text style={styles.description}>{[sizeText, positionText].filter(Boolean).join('\n')}</Text> 100 </View> 101 ); 102} 103 104function renderContentFitExamples(contentFit: ImageContentFit, index: number) { 105 return ( 106 <View key={index} style={styles.contentFitExamples}> 107 <HeadingText style={styles.headingText}>{`Content fit: "${contentFit}"`}</HeadingText> 108 <ScrollView style={styles.examplesScrollView} horizontal indicatorStyle="black"> 109 {EXAMPLES.map((example, index) => renderExample(contentFit, example, index))} 110 </ScrollView> 111 </View> 112 ); 113} 114 115function renderContentPositionExample(contentPosition: ImageContentPositionString, index: number) { 116 const example: ContentFitExample = { 117 size: [100, 100], 118 position: contentPosition, 119 }; 120 return renderExample(ImageContentFit.NONE, example, index); 121} 122 123export default function ImageContentFitScreen() { 124 return ( 125 <ScrollView style={styles.container}> 126 <HeadingText style={styles.headingText}>Full-size image</HeadingText> 127 <Image style={styles.fullImageExample} source={{ uri: sourceWithSize([1500, 1000]) }} /> 128 <Text style={styles.description}>1500 x 1000</Text> 129 130 {CONTENT_FITS.map(renderContentFitExamples)} 131 132 <View style={styles.contentFitExamples}> 133 <HeadingText style={styles.headingText}>Content positions (strings)</HeadingText> 134 <ScrollView style={styles.examplesScrollView} horizontal indicatorStyle="black"> 135 {CONTENT_POSITIONS.map(renderContentPositionExample)} 136 </ScrollView> 137 </View> 138 </ScrollView> 139 ); 140} 141 142const styles = StyleSheet.create({ 143 container: { 144 flex: 1, 145 }, 146 contentFitExamples: { 147 backgroundColor: Colors.greyBackground, 148 borderTopColor: Colors.border, 149 borderTopWidth: StyleSheet.hairlineWidth, 150 }, 151 fullImageExample: { 152 width: 300, 153 height: 200, 154 margin: 10, 155 alignSelf: 'center', 156 }, 157 headingText: { 158 marginTop: -6, 159 marginBottom: 6, 160 marginHorizontal: 10, 161 }, 162 examplesScrollView: { 163 padding: 10, 164 }, 165 imageContainer: { 166 marginRight: 15, 167 alignItems: 'center', 168 }, 169 image: { 170 width: 100, 171 height: 100, 172 borderColor: Colors.tintColor, 173 borderWidth: 1, 174 }, 175 description: { 176 padding: 5, 177 fontSize: 11, 178 textAlign: 'center', 179 }, 180}); 181