1import React from 'react'; 2import { View } from 'react-native'; 3const PI_2 = Math.PI / 2; 4export default class NativeLinearGradient extends React.PureComponent { 5 constructor() { 6 super(...arguments); 7 this.state = { 8 width: undefined, 9 height: undefined, 10 }; 11 this.onLayout = event => { 12 this.setState({ 13 width: event.nativeEvent.layout.width, 14 height: event.nativeEvent.layout.height, 15 }); 16 if (this.props.onLayout) { 17 this.props.onLayout(event); 18 } 19 }; 20 this.getControlPoints = () => { 21 const { startPoint, endPoint } = this.props; 22 let correctedStartPoint = [0, 0]; 23 if (Array.isArray(startPoint)) { 24 correctedStartPoint = [ 25 startPoint[0] != null ? startPoint[0] : 0.0, 26 startPoint[1] != null ? startPoint[1] : 0.0, 27 ]; 28 } 29 let correctedEndPoint = [0.0, 1.0]; 30 if (Array.isArray(endPoint)) { 31 correctedEndPoint = [ 32 endPoint[0] != null ? endPoint[0] : 0.0, 33 endPoint[1] != null ? endPoint[1] : 1.0, 34 ]; 35 } 36 return [correctedStartPoint, correctedEndPoint]; 37 }; 38 this.calculateGradientAngleFromControlPoints = () => { 39 const [start, end] = this.getControlPoints(); 40 const { width = 1, height = 1 } = this.state; 41 start[0] *= width; 42 end[0] *= width; 43 start[1] *= height; 44 end[1] *= height; 45 const py = end[1] - start[1]; 46 const px = end[0] - start[0]; 47 return 90 + (Math.atan2(py, px) * 180) / Math.PI; 48 }; 49 this.getWebGradientColorStyle = () => { 50 return this.getGradientValues().join(','); 51 }; 52 this.convertJSColorToGradientSafeColor = (color, index) => { 53 const { locations } = this.props; 54 const hexColor = hexStringFromProcessedColor(color); 55 let output = hexColor; 56 if (locations && locations[index]) { 57 const location = Math.max(0, Math.min(1, locations[index])); 58 // Convert 0...1 to 0...100 59 const percentage = location * 100; 60 output += ` ${percentage}%`; 61 } 62 return output; 63 }; 64 this.getGradientValues = () => { 65 return this.props.colors.map(this.convertJSColorToGradientSafeColor); 66 }; 67 this.getBackgroundImage = () => { 68 return `linear-gradient(${this.calculateGradientAngleFromControlPoints()}deg, ${this.getWebGradientColorStyle()})`; 69 }; 70 } 71 render() { 72 const { colors, locations, startPoint, endPoint, onLayout, style, ...props } = this.props; 73 const backgroundImage = this.getBackgroundImage(); 74 // TODO: Bacon: In the future we could consider adding `backgroundRepeat: "no-repeat"`. For more browser support. 75 return (<View style={[ 76 style, 77 // @ts-ignore: [ts] Property 'backgroundImage' does not exist on type 'ViewStyle'. 78 { backgroundImage }, 79 ]} onLayout={this.onLayout} {...props}/>); 80 } 81} 82function hexStringFromProcessedColor(argbColor) { 83 if (argbColor === 0) { 84 return `rgba(0,0,0,0)`; 85 } 86 const hexColorString = argbColor.toString(16); 87 const withoutAlpha = hexColorString.substring(2); 88 const alpha = hexColorString.substring(0, 2); 89 return `#${withoutAlpha}${alpha}`; 90} 91//# sourceMappingURL=NativeLinearGradient.web.js.map