Skip to content

Commit ec2244d

Browse files
authored
Merge a186af9 into 2bdccae
2 parents 2bdccae + a186af9 commit ec2244d

File tree

6 files changed

+143
-70
lines changed

6 files changed

+143
-70
lines changed

examples/gap.js

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,26 @@ import React, { Component } from 'react';
33
import ReactDOM from 'react-dom';
44
import { Circle } from 'rc-progress';
55

6+
const colorMap = ['#3FC7FA', '#85D262', '#FE8C6A'];
7+
function getColor(index) {
8+
return colorMap[(index + colorMap.length) % colorMap.length];
9+
}
610
class Example extends Component {
711
constructor() {
812
super();
913
this.state = {
1014
percent: 30,
11-
color: '#3FC7FA',
15+
colorIndex: 0,
1216
};
1317
this.changeState = this.changeState.bind(this);
1418
}
1519

1620
changeState() {
17-
const colorMap = ['#3FC7FA', '#85D262', '#FE8C6A'];
1821
const value = parseInt(Math.random() * 100, 10);
22+
const colorIndex = parseInt(Math.random() * 3, 10);
1923
this.setState({
2024
percent: value,
21-
color: colorMap[parseInt(Math.random() * 3, 10)],
25+
colorIndex,
2226
});
2327
}
2428

@@ -27,52 +31,55 @@ class Example extends Component {
2731
width: '200px',
2832
height: '200px',
2933
};
34+
const { percent, colorIndex } = this.state;
35+
const color = getColor(colorIndex);
3036
return (
3137
<div>
38+
<p>
39+
<button onClick={this.changeState}>Change State [{percent}]</button>
40+
</p>
3241
<div style={circleContainerStyle}>
3342
<Circle
34-
percent={this.state.percent}
43+
percent={percent}
3544
gapDegree={70}
3645
gapPosition="top"
3746
strokeWidth="6"
3847
strokeLinecap="square"
39-
strokeColor={this.state.color}
48+
strokeColor={color}
4049
/>
4150
</div>
4251
<div style={circleContainerStyle}>
4352
<Circle
44-
percent={this.state.percent}
53+
percent={[percent / 3, percent / 3, percent / 3]}
4554
gapDegree={70}
4655
gapPosition="bottom"
4756
strokeWidth="6"
4857
trailWidth="6"
4958
strokeLinecap="round"
50-
strokeColor={this.state.color}
59+
strokeColor={[color, getColor(colorIndex + 1), getColor(colorIndex + 2)]}
5160
/>
5261
</div>
62+
5363
<div style={circleContainerStyle}>
5464
<Circle
55-
percent={this.state.percent}
65+
percent={percent}
5666
gapDegree={70}
5767
gapPosition="left"
5868
strokeWidth="6"
5969
strokeLinecap="square"
60-
strokeColor={this.state.color}
70+
strokeColor={color}
6171
/>
6272
</div>
6373
<div style={circleContainerStyle}>
6474
<Circle
65-
percent={this.state.percent}
75+
percent={percent}
6676
gapDegree={70}
6777
gapPosition="right"
6878
strokeWidth="6"
6979
strokeLinecap="square"
70-
strokeColor={this.state.color}
80+
strokeColor={color}
7181
/>
7282
</div>
73-
<p>
74-
<button onClick={this.changeState}>Change State</button>
75-
</p>
7683
</div>
7784
);
7885
}

examples/simple.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Example extends Component {
2323
}
2424

2525
render() {
26+
const { percent, color } = this.state;
2627
const containerStyle = {
2728
width: '250px',
2829
};
@@ -33,17 +34,22 @@ class Example extends Component {
3334
};
3435
return (
3536
<div>
36-
<h3>Line Progress {this.state.percent}%</h3>
37+
<h3>Line Progress {percent}%</h3>
3738
<div style={containerStyle}>
38-
<Line percent={this.state.percent} strokeWidth="4" strokeColor={this.state.color} />
39+
<Line percent={percent} strokeWidth="4" strokeColor={color} />
40+
<Line
41+
percent={[percent / 2, percent / 2]}
42+
strokeWidth="4"
43+
strokeColor={[color, '#CCC']}
44+
/>
3945
</div>
40-
<h3>Circle Progress {this.state.percent}%</h3>
46+
<h3>Circle Progress {percent}%</h3>
4147
<div style={circleContainerStyle}>
4248
<Circle
43-
percent={this.state.percent}
49+
percent={percent}
4450
strokeWidth="6"
4551
strokeLinecap="round"
46-
strokeColor={this.state.color}
52+
strokeColor={color}
4753
/>
4854
</div>
4955
<p>

src/Circle.js

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import enhancer from './enhancer';
55
import { propTypes, defaultProps } from './types';
66

77
class Circle extends Component {
8-
getPathStyles() {
9-
const { percent, strokeWidth, strokeColor, gapDegree = 0, gapPosition } = this.props;
8+
getPathStyles(offset, percent, strokeColor, strokeWidth, gapDegree = 0, gapPosition) {
109
const radius = 50 - (strokeWidth / 2);
1110
let beginPositionX = 0;
1211
let beginPositionY = -radius;
@@ -35,29 +34,66 @@ class Circle extends Component {
3534
a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY}
3635
a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`;
3736
const len = Math.PI * 2 * radius;
38-
const trailPathStyle = {
39-
strokeDasharray: `${len - gapDegree}px ${len}px`,
40-
strokeDashoffset: `-${gapDegree / 2}px`,
41-
transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s',
42-
};
43-
const strokePathStyle = {
37+
38+
const pathStyle = {
4439
stroke: strokeColor,
4540
strokeDasharray: `${(percent / 100) * (len - gapDegree)}px ${len}px`,
46-
strokeDashoffset: `-${gapDegree / 2}px`,
41+
strokeDashoffset: `-${gapDegree / 2 + offset / 100 * (len - gapDegree)}px`,
4742
transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s', // eslint-disable-line
4843
};
49-
return { pathString, trailPathStyle, strokePathStyle };
44+
45+
return {
46+
pathString,
47+
pathStyle,
48+
};
5049
}
5150

51+
getStokeList() {
52+
const {
53+
prefixCls, percent, strokeColor, strokeWidth, strokeLinecap,
54+
gapDegree, gapPosition,
55+
} = this.props;
56+
const percentList = Array.isArray(percent) ? percent : [percent];
57+
const strokeColorList = Array.isArray(strokeColor) ? strokeColor : [strokeColor];
58+
59+
let stackPtg = 0;
60+
return percentList.map((ptg, index) => {
61+
const color = strokeColorList[index] || strokeColorList[strokeColorList.length - 1];
62+
const { pathString, pathStyle } = this.getPathStyles(
63+
stackPtg, ptg, color, strokeWidth, gapDegree, gapPosition
64+
);
65+
66+
stackPtg += ptg;
67+
68+
return (
69+
<path
70+
key={index}
71+
className={`${prefixCls}-circle-path`}
72+
d={pathString}
73+
strokeLinecap={strokeLinecap}
74+
strokeWidth={ptg === 0 ? 0 : strokeWidth}
75+
fillOpacity="0"
76+
style={pathStyle}
77+
ref={(path) => {
78+
this.paths[index] = path;
79+
}}
80+
/>
81+
);
82+
});
83+
}
84+
85+
paths = {};
86+
5287
render() {
5388
const {
54-
prefixCls, strokeWidth, trailWidth, percent,
89+
prefixCls, strokeWidth, trailWidth,
90+
gapDegree, gapPosition,
5591
trailColor, strokeLinecap, style, className, ...restProps,
5692
} = this.props;
57-
const { pathString, trailPathStyle, strokePathStyle } = this.getPathStyles();
93+
const { pathString, pathStyle } = this.getPathStyles(
94+
0, 100, trailColor, strokeWidth, gapDegree, gapPosition
95+
);
5896
delete restProps.percent;
59-
delete restProps.gapDegree;
60-
delete restProps.gapPosition;
6197
delete restProps.strokeColor;
6298
return (
6399
<svg
@@ -73,17 +109,9 @@ class Circle extends Component {
73109
strokeLinecap={strokeLinecap}
74110
strokeWidth={trailWidth || strokeWidth}
75111
fillOpacity="0"
76-
style={trailPathStyle}
77-
/>
78-
<path
79-
className={`${prefixCls}-circle-path`}
80-
d={pathString}
81-
strokeLinecap={strokeLinecap}
82-
strokeWidth={this.props.percent === 0 ? 0 : strokeWidth}
83-
fillOpacity="0"
84-
ref={(path) => { this.path = path; }}
85-
style={strokePathStyle}
112+
style={pathStyle}
86113
/>
114+
{this.getStokeList()}
87115
</svg>
88116
);
89117
}

src/Line.js

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import enhancer from './enhancer';
33
import { propTypes, defaultProps } from './types';
44

55
class Line extends Component {
6+
paths = {};
7+
68
render() {
79
const {
810
className,
@@ -19,11 +21,8 @@ class Line extends Component {
1921

2022
delete restProps.gapPosition;
2123

22-
const pathStyle = {
23-
strokeDasharray: '100px, 100px',
24-
strokeDashoffset: `${(100 - percent)}px`,
25-
transition: 'stroke-dashoffset 0.3s ease 0s, stroke 0.3s linear',
26-
};
24+
const percentList = Array.isArray(percent) ? percent : [percent];
25+
const strokeColorList = Array.isArray(strokeColor) ? strokeColor : [strokeColor];
2726

2827
const center = strokeWidth / 2;
2928
const right = 100 - (strokeWidth / 2);
@@ -32,6 +31,8 @@ class Line extends Component {
3231
L ${strokeLinecap === 'round' ? right : 100},${center}`;
3332
const viewBoxString = `0 0 100 ${strokeWidth}`;
3433

34+
let stackPtg = 0;
35+
3536
return (
3637
<svg
3738
className={`${prefixCls}-line ${className}`}
@@ -48,16 +49,33 @@ class Line extends Component {
4849
strokeWidth={trailWidth || strokeWidth}
4950
fillOpacity="0"
5051
/>
51-
<path
52-
className={`${prefixCls}-line-path`}
53-
d={pathString}
54-
strokeLinecap={strokeLinecap}
55-
stroke={strokeColor}
56-
strokeWidth={strokeWidth}
57-
fillOpacity="0"
58-
ref={(path) => { this.path = path; }}
59-
style={pathStyle}
60-
/>
52+
{percentList.map((ptg, index) => {
53+
const pathStyle = {
54+
strokeDasharray: `${ptg}px, 100px`,
55+
strokeDashoffset: `-${stackPtg}px`,
56+
transition:
57+
'stroke-dashoffset 0.3s ease 0s, stroke-dasharray .3s ease 0s, stroke 0.3s linear',
58+
};
59+
const color = strokeColorList[index] || strokeColorList[strokeColorList.length - 1];
60+
61+
stackPtg += ptg;
62+
63+
return (
64+
<path
65+
key={index}
66+
className={`${prefixCls}-line-path`}
67+
d={pathString}
68+
strokeLinecap={strokeLinecap}
69+
stroke={color}
70+
strokeWidth={strokeWidth}
71+
fillOpacity="0"
72+
ref={(path) => {
73+
this.paths[index] = path;
74+
}}
75+
style={pathStyle}
76+
/>
77+
);
78+
})}
6179
</svg>
6280
);
6381
}

src/enhancer.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
11
const enhancer = WrappedComponent => class Progress extends WrappedComponent {
22
componentDidUpdate() {
3-
if (!this.path) {
4-
return;
5-
}
6-
const pathStyle = this.path.style;
7-
pathStyle.transitionDuration = '.3s, .3s, .3s, .06s';
83
const now = Date.now();
9-
if (this.prevTimeStamp && now - this.prevTimeStamp < 100) {
10-
pathStyle.transitionDuration = '0s, 0s';
4+
let updated = false;
5+
6+
Object.keys(this.paths).forEach((key) => {
7+
const path = this.paths[key];
8+
9+
if (!path) {
10+
return;
11+
}
12+
13+
updated = true;
14+
const pathStyle = path.style;
15+
pathStyle.transitionDuration = '.3s, .3s, .3s, .06s';
16+
17+
if (this.prevTimeStamp && now - this.prevTimeStamp < 100) {
18+
pathStyle.transitionDuration = '0s, 0s';
19+
}
20+
});
21+
22+
if (updated) {
23+
this.prevTimeStamp = Date.now();
1124
}
12-
this.prevTimeStamp = Date.now();
1325
}
1426

1527
render() {

src/types.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@ export const defaultProps = {
1212
trailWidth: 1,
1313
};
1414

15+
const mixedType = PropTypes.oneOfType([PropTypes.number, PropTypes.string]);
16+
1517
export const propTypes = {
1618
className: PropTypes.string,
17-
percent: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
19+
percent: PropTypes.oneOfType([mixedType, PropTypes.arrayOf(mixedType)]),
1820
prefixCls: PropTypes.string,
19-
strokeColor: PropTypes.string,
21+
strokeColor: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
2022
strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square']),
21-
strokeWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
23+
strokeWidth: mixedType,
2224
style: PropTypes.object,
2325
trailColor: PropTypes.string,
24-
trailWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
26+
trailWidth: mixedType,
2527
};

0 commit comments

Comments
 (0)