Skip to content

Commit 900e75f

Browse files
committed
Support start/end/locations props
1 parent 8850dc5 commit 900e75f

File tree

5 files changed

+93
-28
lines changed

5 files changed

+93
-28
lines changed

docs/.storybook/decorator-centered.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const styles = StyleSheet.create({
77
alignItems: 'center',
88
justifyContent: 'center',
99
minHeight: '100vh',
10-
}
10+
},
1111
});
1212

1313
export default function(renderStory) {

docs/stories/gradientBackground.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,14 @@ import React from 'react';
22
import { StyleSheet, View, TouchableOpacity, Text } from 'react-native';
33
import LinearGradient from 'react-native-linear-gradient';
44

5-
export default () => (
6-
<LinearGradient start={{ x: 0.5, y: 1 }} end={{ x: 0.5, y: 0 }} colors={['red', 'blue']} style={styles.page}>
7-
<Text style={styles.buttonText}>Hello !</Text>
8-
</LinearGradient>
5+
export const basic = () => <LinearGradient colors={['red', 'blue']} style={styles.page} />;
6+
7+
export const withAngle = () => (
8+
<LinearGradient start={{ x: 0, y: 0 }} end={{ x: 1, y: 1 }} colors={['red', 'blue']} style={styles.page} />
99
);
1010

1111
const styles = StyleSheet.create({
1212
page: {
1313
flex: 1,
14-
justifyContent: 'center',
15-
},
16-
buttonText: {
17-
fontSize: 18,
18-
textAlign: 'center',
19-
color: '#ffffff',
20-
backgroundColor: 'transparent',
2114
},
2215
});

docs/stories/index.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import React from 'react';
2-
import LinearGradient from 'react-native-linear-gradient';
3-
import { View } from 'react-native';
4-
import signInWithFacebook from './signInWithFacebook';
5-
import gradientBackground from './gradientBackground';
2+
import * as signInWithFacebook from './signInWithFacebook';
3+
import * as gradientBackground from './gradientBackground';
64

75
import { storiesOf } from '@storybook/react';
86

9-
storiesOf('LinearGradient', module)
10-
.add('signInWithFacebook', signInWithFacebook)
11-
.add('gradientBackground', gradientBackground);
7+
storiesOf('Gradient background', module)
8+
.add('basic', gradientBackground.basic)
9+
.add('with an angle', gradientBackground.withAngle);
10+
11+
storiesOf('Sign in with Facebook', module)
12+
.add('basic', signInWithFacebook.basic)
13+
.add('with start, end, locations', signInWithFacebook.withStartEndLocations);

docs/stories/signInWithFacebook.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,28 @@ import React from 'react';
22
import { StyleSheet, View, TouchableOpacity, Text } from 'react-native';
33
import LinearGradient from 'react-native-linear-gradient';
44

5-
export default () => (
5+
export const basic = () => (
66
<TouchableOpacity>
77
<LinearGradient colors={['#4c669f', '#3b5998', '#192f6a']} style={styles.linearGradient}>
88
<Text style={styles.buttonText}>Sign in with Facebook</Text>
99
</LinearGradient>
1010
</TouchableOpacity>
1111
);
1212

13+
export const withStartEndLocations = () => (
14+
<TouchableOpacity>
15+
<LinearGradient
16+
start={{ x: 0.0, y: 0.25 }}
17+
end={{ x: 0.5, y: 1.0 }}
18+
locations={[0, 0.5, 0.6]}
19+
colors={['#4c669f', '#3b5998', '#192f6a']}
20+
style={styles.linearGradient}
21+
>
22+
<Text style={styles.buttonText}>Sign in with Facebook</Text>
23+
</LinearGradient>
24+
</TouchableOpacity>
25+
);
26+
1327
const styles = StyleSheet.create({
1428
linearGradient: {
1529
paddingLeft: 15,

src/index.js

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,69 @@
1-
import React from 'react';
1+
import React, { PureComponent } from 'react';
22
import { StyleSheet, View } from 'react-native';
33

4-
export default props => {
5-
return (
6-
<View style={[styles.container, props.style, { backgroundImage: `linear-gradient(to top, ${props.colors.join(',')})` }]}>
7-
{props.children}
8-
</View>
9-
);
10-
};
4+
export default class LinearGradient extends PureComponent {
5+
static defaultProps = {
6+
start: {
7+
x: 0.5,
8+
y: 0,
9+
},
10+
end: {
11+
x: 0.5,
12+
y: 1,
13+
},
14+
locations: [],
15+
colors: [],
16+
};
17+
18+
state = {
19+
width: 1,
20+
height: 1,
21+
};
22+
23+
measure = ({ nativeEvent }) =>
24+
this.setState({
25+
width: nativeEvent.layout.width,
26+
height: nativeEvent.layout.height,
27+
});
28+
29+
getAngle = () => {
30+
// Math.atan2 handles Infinity
31+
const angle =
32+
Math.atan2(
33+
this.state.width * (this.props.end.y - this.props.start.y),
34+
this.state.height * (this.props.end.x - this.props.start.x)
35+
) +
36+
Math.PI / 2;
37+
return angle + 'rad';
38+
};
39+
40+
getColors = () =>
41+
this.props.colors
42+
.map((color, index) => {
43+
const location = this.props.locations[index];
44+
let locationStyle = '';
45+
if (location) {
46+
locationStyle = ' ' + location * 100 + '%';
47+
}
48+
return color + locationStyle;
49+
})
50+
.join(',');
51+
52+
render() {
53+
return (
54+
<View
55+
style={[
56+
styles.container,
57+
this.props.style,
58+
{ backgroundImage: `linear-gradient(${this.getAngle()},${this.getColors()})` },
59+
]}
60+
onLayout={this.measure}
61+
>
62+
{this.props.children}
63+
</View>
64+
);
65+
}
66+
}
1167

1268
const styles = StyleSheet.create({
1369
container: {

0 commit comments

Comments
 (0)