1import { LinearGradient } from 'expo-linear-gradient'; 2import React from 'react'; 3import { Image, Platform, ScrollView, StyleSheet, Text, View } from 'react-native'; 4 5import MonoText from '../components/MonoText'; 6 7function incrementColor(color: string, step: number) { 8 const intColor = parseInt(color.substr(1), 16); 9 const newIntColor = (intColor + step).toString(16); 10 return `#${'0'.repeat(6 - newIntColor.length)}${newIntColor}`; 11} 12 13export default class LinearGradientScreen extends React.Component { 14 static navigationOptions = { 15 title: 'LinearGradient', 16 }; 17 18 state = { 19 count: 0, 20 colorTop: '#000000', 21 colorBottom: '#cccccc', 22 }; 23 24 _interval?: number; 25 26 componentDidMount() { 27 this._interval = setInterval(() => { 28 this.setState({ 29 count: this.state.count + 1, 30 colorTop: incrementColor(this.state.colorTop, 1), 31 colorBottom: incrementColor(this.state.colorBottom, -1), 32 }); 33 }, 100); 34 } 35 36 componentWillUnmount() { 37 clearInterval(this._interval); 38 } 39 40 render() { 41 const location = Math.sin(this.state.count / 100) * 0.5; 42 const position = Math.sin(this.state.count / 100); 43 return ( 44 <ScrollView 45 style={{ flex: 1 }} 46 contentContainerStyle={{ 47 alignItems: 'stretch', 48 paddingVertical: 10, 49 }}> 50 <ColorsTest colors={[this.state.colorTop, this.state.colorBottom]} /> 51 <LocationsTest locations={[location, 1.0 - location]} /> 52 <ControlPointTest start={[position, 0]} /> 53 {Platform.OS !== 'web' && <SnapshotTest />} 54 </ScrollView> 55 ); 56 } 57} 58 59const Container: React.FunctionComponent<{ title: string }> = ({ title, children }) => ( 60 <View style={styles.container}> 61 <Text style={styles.containerTitle}>{title}</Text> 62 {children} 63 </View> 64); 65 66const SnapshotTest = () => ( 67 <Container title="Snapshot"> 68 <View style={{ flexDirection: 'row', alignSelf: 'stretch', justifyContent: 'space-evenly' }}> 69 <LinearGradient 70 colors={['white', 'red']} 71 start={[0.5, 0.5]} 72 end={[1, 1]} 73 style={{ 74 width: 100, 75 maxHeight: 200, 76 minHeight: 200, 77 borderWidth: 1, 78 marginVertical: 20, 79 borderColor: 'black', 80 }} 81 /> 82 <Image 83 source={require('../../assets/images/confusing_gradient.png')} 84 style={{ width: 100, height: 200, marginVertical: 20 }} 85 /> 86 </View> 87 <Text style={{ marginHorizontal: 20 }}>The gradients above should look the same.</Text> 88 </Container> 89); 90 91const ControlPointTest: React.FunctionComponent<{ 92 start?: [number, number]; 93 end?: [number, number]; 94}> = ({ start = [0.5, 0], end = [0, 1] }) => { 95 const startInfo = `start={[${start.map(point => +point.toFixed(2)).join(', ')}]}`; 96 const endInfo = `end={[${end.map(point => +point.toFixed(2)).join(', ')}]}`; 97 98 return ( 99 <Container title="Control Points"> 100 <View> 101 {[startInfo, endInfo].map((pointInfo, index) => ( 102 <MonoText key={'--' + index}>{pointInfo}</MonoText> 103 ))} 104 </View> 105 <LinearGradient 106 start={start} 107 end={end} 108 locations={[0.5, 0.5]} 109 colors={['blue', 'lime']} 110 style={styles.gradient} 111 /> 112 </Container> 113 ); 114}; 115 116const ColorsTest = ({ colors }: { colors: string[] }) => { 117 const info = colors.map(value => `"${value}"`).join(', '); 118 return ( 119 <Container title="Colors"> 120 <MonoText>{`colors={[${info}]}`}</MonoText> 121 <LinearGradient colors={colors} style={styles.gradient} /> 122 </Container> 123 ); 124}; 125 126const LocationsTest: React.FunctionComponent<{ locations: number[] }> = ({ locations }) => { 127 const locationsInfo = locations.map(location => +location.toFixed(2)).join(', '); 128 return ( 129 <Container title="Locations"> 130 <MonoText>{`locations={[${locationsInfo}]}`}</MonoText> 131 <LinearGradient colors={['red', 'blue']} locations={locations} style={styles.gradient} /> 132 </Container> 133 ); 134}; 135 136const styles = StyleSheet.create({ 137 container: { 138 padding: 8, 139 flexShrink: 0, 140 }, 141 containerTitle: { 142 fontSize: 14, 143 fontWeight: '600', 144 textAlign: 'center', 145 marginBottom: 8, 146 }, 147 gradient: { 148 flex: 1, 149 flexShrink: 0, 150 minHeight: 200, 151 maxHeight: 200, 152 }, 153}); 154