Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit feef987

Browse files
initial commit
1 parent 96ab0f9 commit feef987

File tree

3 files changed

+236
-0
lines changed

3 files changed

+236
-0
lines changed

‎Pulse.js‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React from 'react';
2+
import { View, StyleSheet, Animated, Easing, Dimensions } from 'react-native';
3+
4+
const { height, width } = Dimensions.get('window');
5+
6+
export default class Pulse extends React.Component {
7+
constructor(props) {
8+
super(props);
9+
10+
this.anim = new Animated.Value(0);
11+
}
12+
13+
componentDidMount() {
14+
Animated.timing(this.anim, {
15+
toValue: 1,
16+
duration: this.props.interval,
17+
easing: Easing.in,
18+
})
19+
.start();
20+
}
21+
22+
render() {
23+
const { size, pulseMaxSize, borderColor, backgroundColor, getStyle } = this.props;
24+
25+
return (
26+
<View style={[styles.circleWrapper, {
27+
width: pulseMaxSize,
28+
height: pulseMaxSize,
29+
marginLeft: -pulseMaxSize/2,
30+
marginTop: -pulseMaxSize/2,
31+
}]}>
32+
<Animated.View
33+
style={[styles.circle, {
34+
borderColor,
35+
backgroundColor,
36+
width: this.anim.interpolate({
37+
inputRange: [0, 1],
38+
outputRange: [size, pulseMaxSize]
39+
}),
40+
height: this.anim.interpolate({
41+
inputRange: [0, 1],
42+
outputRange: [size, pulseMaxSize]
43+
}),
44+
borderRadius: pulseMaxSize/2,
45+
opacity: this.anim.interpolate({
46+
inputRange: [0, 1],
47+
outputRange: [1, 0]
48+
})
49+
}, getStyle && getStyle(this.anim)]}
50+
/>
51+
</View>
52+
);
53+
}
54+
}
55+
56+
57+
const styles = StyleSheet.create({
58+
circleWrapper: {
59+
justifyContent: 'center',
60+
alignItems: 'center',
61+
position: 'absolute',
62+
left: width/2,
63+
top: height/2,
64+
},
65+
circle: {
66+
borderWidth: 4 * StyleSheet.hairlineWidth,
67+
},
68+
});

‎PulseLoader.js‎

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import React from 'react';
2+
import { View, Image, TouchableOpacity, Animated, Easing } from 'react-native';
3+
import Pulse from './Pulse';
4+
5+
6+
export default class LocationPulseLoader extends React.Component {
7+
constructor(props) {
8+
super(props);
9+
10+
this.state = {
11+
circles: []
12+
};
13+
14+
this.counter = 1;
15+
this.setInterval = null;
16+
this.anim = new Animated.Value(1);
17+
}
18+
19+
componentDidMount() {
20+
this.setCircleInterval();
21+
}
22+
23+
setCircleInterval() {
24+
this.setInterval = setInterval(this.addCircle.bind(this), this.props.interval);
25+
this.addCircle();
26+
}
27+
28+
addCircle() {
29+
this.setState({ circles: [...this.state.circles, this.counter] });
30+
this.counter++;
31+
}
32+
33+
onPressIn() {
34+
Animated.timing(this.anim, {
35+
toValue: this.props.pressInValue,
36+
duration: this.props.pressDuration,
37+
easing: this.props.pressInEasing,
38+
}).start(() => clearInterval(this.setInterval));
39+
}
40+
41+
onPressOut() {
42+
Animated.timing(this.anim, {
43+
toValue: 1,
44+
duration: this.props.pressDuration,
45+
easing: this.props.pressOutEasing,
46+
}).start(this.setCircleInterval.bind(this));
47+
}
48+
49+
render() {
50+
const { size, avatar, avatarBackgroundColor, interval } = this.props;
51+
52+
return (
53+
<View style={{
54+
flex: 1,
55+
backgroundColor: 'transparent',
56+
justifyContent: 'center',
57+
alignItems: 'center',
58+
}}>
59+
{this.state.circles.map((circle) => (
60+
<Pulse
61+
key={circle}
62+
{...this.props}
63+
/>
64+
))}
65+
66+
<TouchableOpacity
67+
activeOpacity={1}
68+
onPressIn={this.onPressIn.bind(this)}
69+
onPressOut={this.onPressOut.bind(this)}
70+
style={{
71+
transform: [{
72+
scale: this.anim
73+
}]
74+
}}
75+
>
76+
<Image
77+
source={{ uri: avatar }}
78+
style={{
79+
width: size,
80+
height: size,
81+
borderRadius: size/2,
82+
backgroundColor: avatarBackgroundColor
83+
}}
84+
/>
85+
</TouchableOpacity>
86+
</View>
87+
);
88+
}
89+
}
90+
91+
LocationPulseLoader.propTypes = {
92+
interval: React.PropTypes.number,
93+
size: React.PropTypes.number,
94+
pulseMaxSize: React.PropTypes.number,
95+
avatar: React.PropTypes.string.isRequired,
96+
avatarBackgroundColor: React.PropTypes.string,
97+
pressInValue: React.PropTypes.number,
98+
pressDuration: React.PropTypes.number,
99+
borderColor: React.PropTypes.string,
100+
backgroundColor: React.PropTypes.string,
101+
getStyle: React.PropTypes.func,
102+
};
103+
104+
LocationPulseLoader.defaultProps = {
105+
interval: 2000,
106+
size: 100,
107+
pulseMaxSize: 250,
108+
avatar: undefined,
109+
avatarBackgroundColor: 'white',
110+
pressInValue: 0.8,
111+
pressDuration: 150,
112+
pressInEasing: Easing.in,
113+
pressOutEasing: Easing.in,
114+
borderColor: '#D8335B',
115+
backgroundColor: '#ED225B55',
116+
getStyle: undefined,
117+
};
118+

‎README.md‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# react-native-pulse-loader
2+
tinder-like loader for your react native app
3+
4+
![react-native-pulse-loader demo](http://i.giphy.com/l0MYz2cMbOryuyPZu.gif)
5+
6+
### Installation
7+
```bash
8+
npm i react-native-pulse-loader --save
9+
```
10+
11+
### Usage
12+
13+
First, require it from your app's JavaScript files with:
14+
```bash
15+
import PulseLoader from 'react-native-pulse-loader';
16+
```
17+
18+
### Example
19+
20+
```js
21+
import React from 'react';
22+
import PulseLoader from 'react-native-pulse-loader';
23+
24+
class App extends React.Component {
25+
render() {
26+
return (
27+
<LocationPulseLoader
28+
avatar={'https://scontent-fra3-1.cdninstagram.com/t51.2885-15/e35/11429705_386886401514376_550879228_n.jpg'}
29+
/>
30+
);
31+
}
32+
}
33+
```
34+
35+
36+
### API
37+
38+
| Property | Type | Default | Description |
39+
| ------------- |:-------------:|:------------: | ----------- |
40+
| interval | number | 2000 | action buttons visible or not
41+
| size | number | 100 | width and height of the avatar
42+
| pulseMaxSize | number | 250 | maximum size of the pulse in the background
43+
| avatar | string | undefined | **required** avatar url to display
44+
| pressInValue | number | 0.8 | should be between 0 and 1. scale of the avatar, when pressed in
45+
| pressDuration | number | 150 | duration of the scale animation
46+
| pressInEasing | Easing | Easing.in | easing type of the press in animation
47+
| pressOutEasing | Easing | Easing.out | easing type of the press out animation
48+
| borderColor | string | '#D8335B' | border color of the pulse
49+
| backgroundColor| string | '#ED225B55' | background color of the pulse
50+
| getStyle | function | undefined | override the styling of the pulse. gets as parameter the Animated variable. e.g. (anim) => ({ backgroundColor: 'yellow' })

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /