-
Notifications
You must be signed in to change notification settings - Fork 0
/
CircularProgress.js
107 lines (99 loc) · 2.78 KB
/
CircularProgress.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import React, { Component, PropTypes } from 'react';
import { View, ART, Platform } from 'react-native';
const { Surface, Shape, Path, Group } = ART;
export default class CircularProgress extends Component {
circlePath(cx, cy, r, startDegree, endDegree) {
const p = Path(); // eslint-disable-line
if (Platform.OS === 'ios') {
p.path.push(0, cx + r, cy);
p.path.push(4, cx, cy, r, (startDegree * Math.PI) / 180, (endDegree * Math.PI) / 180, 1);
} else {
// For Android we have to resort to drawing low-level Path primitives, as ART does not support
// arbitrary circle segments. It also does not support strokeDash.
// Furthermore, the ART implementation seems to be buggy/different than the iOS one.
// MoveTo is not needed on Android
p.path.push(
4, cx, cy, r, (startDegree * Math.PI) / 180, ((startDegree - endDegree) * Math.PI) / 180, 0
);
}
return p;
}
extractFill(fill) {
if (fill < 0.01) {
return 0;
} else if (fill > 100) {
return 100;
}
return fill;
}
render() {
const {
arcSweepAngle,
size,
width,
tintColor,
backgroundColor,
style,
rotation,
linecap,
children,
} = this.props;
const center = size / 2;
const backgroundPath = this.circlePath(
size / 2, size / 2, ((size / 2) - (width / 2)), 0, arcSweepAngle * 0.9999
);
const fill = this.extractFill(this.props.fill);
const circlePath = this.circlePath(
size / 2, size / 2, ((size / 2) - (width / 2)), 0, ((arcSweepAngle * 0.9999) * fill) / 100
);
return (
<View style={style}>
<Surface
width={size}
height={size}
>
<Group
rotation={rotation + ((360 - arcSweepAngle) / 2)}
originX={center}
originY={center}
>
<Shape
d={backgroundPath}
stroke={backgroundColor}
strokeWidth={width}
strokeCap={linecap}
/>
<Shape
d={circlePath}
stroke={tintColor}
strokeWidth={width}
strokeCap={linecap}
/>
</Group>
</Surface>
{
children
}
</View>
);
}
}
CircularProgress.propTypes = {
style: View.propTypes.style,
size: PropTypes.number.isRequired,
fill: PropTypes.number.isRequired,
width: PropTypes.number.isRequired,
tintColor: PropTypes.string,
backgroundColor: PropTypes.string,
rotation: PropTypes.number,
linecap: PropTypes.string,
children: PropTypes.object,
arcSweepAngle: PropTypes.number,
};
CircularProgress.defaultProps = {
tintColor: 'black',
backgroundColor: '#e4e4e4',
rotation: 90,
linecap: 'butt',
arcSweepAngle: 360,
};