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 > 51 <ColorsTest colors={[this.state.colorTop, this.state.colorBottom]} /> 52 <LocationsTest locations={[location, 1.0 - location]} /> 53 <ControlPointTest start={[position, 0]} /> 54 {Platform.OS !== 'web' && <SnapshotTest />} 55 </ScrollView> 56 ); 57 } 58} 59 60const Container: React.FunctionComponent<{ title: string }> = ({ title, children }) => ( 61 <View style={styles.container}> 62 <Text style={styles.containerTitle}>{title}</Text> 63 {children} 64 </View> 65); 66 67const SnapshotTest = () => ( 68 <Container title="Snapshot"> 69 <View style={{ flexDirection: 'row', alignSelf: 'stretch', justifyContent: 'space-evenly' }}> 70 <LinearGradient 71 colors={['white', 'red']} 72 start={[0.5, 0.5]} 73 end={[1, 1]} 74 style={{ 75 width: 100, 76 height: 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}> = ({ 95 start = [0.5, 0], 96 end = [0, 1], 97}) => { 98 const startInfo = `start={[${start.map(point => +point.toFixed(2)).join(', ')}]}`; 99 const endInfo = `end={[${end.map(point => +point.toFixed(2)).join(', ')}]}`; 100 101 return ( 102 <Container title="Control Points"> 103 <View> 104 {[startInfo, endInfo].map((pointInfo, index) => ( 105 <MonoText key={'--' + index}> 106 {pointInfo} 107 </MonoText> 108 ))} 109 </View> 110 <LinearGradient 111 start={start} 112 end={end} 113 locations={[0.5, 0.5]} 114 colors={['blue', 'lime']} 115 style={{ flex: 1, height: 200 }} 116 /> 117 </Container> 118 ); 119}; 120 121const ColorsTest = ({ colors }: { colors: string[] }) => { 122 const info = colors.map(value => `"${value}"`).join(', '); 123 return ( 124 <Container title="Colors"> 125 <MonoText>{`colors={[${info}]}`}</MonoText> 126 <LinearGradient colors={colors} style={{ flex: 1, height: 200 }} /> 127 </Container> 128 ); 129}; 130 131const LocationsTest: React.FunctionComponent<{ locations: number[] }> = ({ locations }) => { 132 const locationsInfo = locations.map(location => +location.toFixed(2)).join(', '); 133 return ( 134 <Container title="Locations"> 135 <MonoText>{`locations={[${locationsInfo}]}`}</MonoText> 136 <LinearGradient 137 colors={['red', 'blue']} 138 locations={locations} 139 style={{ flex: 1, height: 200 }} 140 /> 141 </Container> 142 ); 143}; 144 145const styles = StyleSheet.create({ 146 container: { 147 padding: 8, 148 }, 149 containerTitle: { 150 fontSize: 14, 151 fontWeight: '600', 152 textAlign: 'center', 153 marginBottom: 8, 154 }, 155}); 156