Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ notifications:
- afc163@gmail.com

node_js:
- 4.0.0
- 6.0.0

before_install:
- |
Expand Down
3 changes: 3 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

---

## 2.1.0
- Add `gapWidth` `gapPosition` props.

## 2.0.0

- refactor code
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,24 @@ ReactDOM.render(<div>
<td></td>
<td>style object will be added to svg element</td>
</tr>
<tr>
<td>percent</td>
<td>Number</td>
<td>0</td>
<td>the percent of the progress</td>
</tr>
<tr>
<td>gapWidth</td>
<td>Number</td>
<td>0</td>
<td>the gap width of half circle</td>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

其实这个我是有点困惑的,是按百分比还是绝对值?绝对值的话,宽度又是相对于什么?

Copy link
Author

@qiaolb qiaolb Mar 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

百分比的确解释起来比较麻烦,绝对值应该比较直观

</tr>
<tr>
<td>gapPosition</td>
<td>String</td>
<td>top</td>
<td>the gap position, value: top, bottom, left, right. </td>
</tr>
</tbody>
</table>

Expand Down
43 changes: 42 additions & 1 deletion examples/simple.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ const Example = React.createClass({
},
changeState() {
const colorMap = ['#3FC7FA', '#85D262', '#FE8C6A'];
const value = parseInt(Math.random() * 100, 10);
this.setState({
percent: parseInt(Math.random() * 100, 10),
percent: value,
color: colorMap[parseInt(Math.random() * 3, 10)],
});
},
Expand All @@ -25,6 +26,7 @@ const Example = React.createClass({
const circleContainerStyle = {
width: '250px',
height: '250px',
display: 'inline-block',
};
return (
<div>
Expand All @@ -41,6 +43,45 @@ const Example = React.createClass({
strokeColor={this.state.color}
/>
</div>
<div style={circleContainerStyle}>
<Circle
percent={this.state.percent}
gapWidth={70}
strokeWidth="6"
strokeLinecap="square"
strokeColor={this.state.color}
/>
</div>
<div style={circleContainerStyle}>
<Circle
percent={this.state.percent}
gapWidth={70}
strokeWidth="6"
strokeLinecap="square"
strokeColor={this.state.color}
gapPosition="bottom"
/>
</div>
<div style={circleContainerStyle}>
<Circle
percent={this.state.percent}
gapWidth={70}
strokeWidth="6"
strokeLinecap="square"
strokeColor={this.state.color}
gapPosition="left"
/>
</div>
<div style={circleContainerStyle}>
<Circle
percent={this.state.percent}
gapWidth={70}
strokeWidth="6"
strokeLinecap="square"
strokeColor={this.state.color}
gapPosition="right"
/>
</div>
<p>
<button onClick={this.changeState}>Change State</button>
</p>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rc-progress",
"version": "2.0.6",
"version": "2.1.0",
"description": "progress ui component for react",
"keywords": [
"react",
Expand Down
54 changes: 45 additions & 9 deletions src/Circle.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,60 @@
/* eslint-disable react/prop-types */
import React from 'react';
import React, { PropTypes } from 'react';
import mixin from './mixin';

export default React.createClass({
propTypes: {
gapPosition: PropTypes.oneOf(['top', 'bottom', 'left', 'right']),
},
mixins: [mixin],

render() {
const {
prefixCls, strokeWidth, trailWidth, strokeColor,
trailColor, strokeLinecap, percent, style, className,
gapWidth = 0, gapPosition,
...restProps,
} = this.props;

const radius = (50 - strokeWidth / 2);
const pathString = `M 50,50 m 0,-${radius}
a ${radius},${radius} 0 1 1 0,${2 * radius}
a ${radius},${radius} 0 1 1 0,-${2 * radius}`;
let beginPositionX = 0;
let beginPositionY = -radius;
let endPositionX = 0;
let endPositionY = -2 * radius;
switch (gapPosition) {
case 'left':
beginPositionX = -radius;
beginPositionY = 0;
endPositionX = 2 * radius;
endPositionY = 0;
break;
case 'right':
beginPositionX = radius;
beginPositionY = 0;
endPositionX = -2 * radius;
endPositionY = 0;
break;
case 'bottom':
beginPositionY = radius;
endPositionY = 2 * radius;
break;
default:
}
const pathString = `M 50,50 m ${beginPositionX},${beginPositionY}
a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY}
a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`;
const len = Math.PI * 2 * radius;
const pathStyle = {
strokeDasharray: `${len}px ${len}px`,
strokeDashoffset: `${((100 - percent) / 100 * len)}px`,
const trailPathStyle = {
strokeDasharray: `${len - gapWidth}px ${len}px`,
strokeDashoffset: `-${gapWidth / 2}px`,
transition: 'stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease',
};

const strokePathStyle = {
strokeDasharray: `${percent / 100 * (len - gapWidth)}px ${len}px`,
strokeDashoffset: `-${gapWidth / 2}px`,
transition: 'stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease',
};
return (
<svg
className={`${prefixCls}-circle ${className}`}
Expand All @@ -35,6 +68,7 @@ export default React.createClass({
stroke={trailColor}
strokeWidth={trailWidth || strokeWidth}
fillOpacity="0"
style={trailPathStyle}
/>
<path
className={`${prefixCls}-circle-path`}
Expand All @@ -43,8 +77,10 @@ export default React.createClass({
stroke={strokeColor}
strokeWidth={strokeWidth}
fillOpacity="0"
ref={(path) => { this.path = path; }}
style={pathStyle}
ref={(path) => {
this.path = path;
}}
style={strokePathStyle}
/>
</svg>
);
Expand Down
36 changes: 36 additions & 0 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,39 @@ describe('circle progress', () => {
ReactDOM.unmountComponentAtNode(div);
});
});

describe('half circle progress', () => {
it('work', () => {
const div = document.createElement(div);
document.body.appendChild(div);
const circle = ReactDOM.render(
<Circle percent="30" strokeWidth="1" gapWidth={70} gapPosition="bottom"/>,
div);
expect(circle.props.percent).to.be('30');
ReactDOM.unmountComponentAtNode(div);
});
});

describe('half circle progress', () => {
it('work', () => {
const div = document.createElement(div);
document.body.appendChild(div);
const circle = ReactDOM.render(
<Circle percent="30" strokeWidth="1" gapWidth={70} gapPosition="left"/>,
div);
expect(circle.props.percent).to.be('30');
ReactDOM.unmountComponentAtNode(div);
});
});

describe('half circle progress', () => {
it('work', () => {
const div = document.createElement(div);
document.body.appendChild(div);
const circle = ReactDOM.render(
<Circle percent="30" strokeWidth="1" gapWidth={70} gapPosition="right"/>,
div);
expect(circle.props.percent).to.be('30');
ReactDOM.unmountComponentAtNode(div);
});
});