Skip to content

Commit 8a24f5c

Browse files
committed
Add a more eye-catching indicator
1 parent 01580cf commit 8a24f5c

File tree

6 files changed

+78
-28
lines changed

6 files changed

+78
-28
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ export default () => (
136136
<td>top</td>
137137
<td>the gap position, value: top, bottom, left, right. </td>
138138
</tr>
139+
<tr>
140+
<td>dot</td>
141+
<td>Boolean | Object</td>
142+
<td>false</td>
143+
<td>within dot or not, value: true, false, { size: Number }</td>
144+
</tr>
139145
</tbody>
140146
</table>
141147

docs/examples/gap.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class Example extends React.Component<ProgressProps, any> {
3030
const circleContainerStyle = {
3131
width: '200px',
3232
height: '200px',
33+
marginBottom: '60px'
3334
};
3435
const { percent, colorIndex } = this.state;
3536
const color = getColor(colorIndex);
@@ -48,6 +49,7 @@ class Example extends React.Component<ProgressProps, any> {
4849
strokeWidth={6}
4950
strokeLinecap="square"
5051
strokeColor={color}
52+
dot={{ size: 10 }}
5153
/>
5254
</div>
5355
<div style={circleContainerStyle}>
@@ -59,6 +61,7 @@ class Example extends React.Component<ProgressProps, any> {
5961
trailWidth={6}
6062
strokeLinecap="round"
6163
strokeColor={[color, getColor(colorIndex + 1), getColor(colorIndex + 2)]}
64+
dot={true}
6265
/>
6366
</div>
6467

docs/examples/gradient-circle.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const Example = () => {
2020
'0%': '#108ee9',
2121
'100%': '#87d068',
2222
}}
23+
dot={true}
2324
/>
2425
</div>
2526
<h3>Circle Progress {100}%</h3>
@@ -47,6 +48,7 @@ const Example = () => {
4748
'0%': '#87d068',
4849
},
4950
]}
51+
dot={{}}
5052
/>
5153
</div>
5254
</div>

src/Circle.tsx

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import type { ProgressProps, GapPositionType } from './interface';
55

66
let gradientSeed = 0;
77

8+
function pxToNumber(px: string) {
9+
return parseInt(px.slice(0, px.indexOf('p')), 10);
10+
}
11+
812
function stripPercentToNumber(percent: string) {
913
return +percent.replace('%', '');
1014
}
@@ -76,6 +80,7 @@ const Circle: React.FC<ProgressProps> = ({
7680
className,
7781
strokeColor,
7882
percent,
83+
dot,
7984
...restProps
8085
}) => {
8186
const gradientId = React.useMemo(() => {
@@ -98,31 +103,62 @@ const Circle: React.FC<ProgressProps> = ({
98103

99104
const [paths] = useTransitionDuration(percentList);
100105

106+
const getDotList = (pathDoms) => {
107+
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
108+
if (dot) {
109+
return pathDoms.map((pathDom, index) => {
110+
const strokeDasharrayTemp = pathDom.props.style.strokeDasharray;
111+
const strokeLength =
112+
pxToNumber(strokeDasharrayTemp.slice(0, strokeDasharrayTemp.indexOf(' '))) +
113+
Math.abs(pxToNumber(pathDom.props.style.strokeDashoffset)) +
114+
strokeWidth / 2;
115+
116+
path.setAttribute('d', pathDom.props.d);
117+
const dotPoint = path.getPointAtLength(strokeLength);
118+
return (
119+
<circle
120+
key={index + 10}
121+
className={`${prefixCls}-circle-dot`}
122+
cx={dotPoint.x}
123+
cy={dotPoint.y}
124+
r={typeof dot === 'object' ? dot.size : strokeWidth}
125+
fill={pathDom.props.stroke ? pathDom.props.stroke : pathDom.props.style.stroke}
126+
/>
127+
);
128+
});
129+
}
130+
return [];
131+
132+
};
133+
101134
const getStokeList = () => {
102135
let stackPtg = 0;
103-
return percentList.map((ptg, index) => {
104-
const color = strokeColorList[index] || strokeColorList[strokeColorList.length - 1];
105-
const stroke =
106-
Object.prototype.toString.call(color) === '[object Object]'
107-
? `url(#${prefixCls}-gradient-${gradientId})`
108-
: '';
109-
const pathStyles = getPathStyles(stackPtg, ptg, color, strokeWidth, gapDegree, gapPosition);
110-
stackPtg += ptg;
111-
return (
112-
<path
113-
key={index}
114-
className={`${prefixCls}-circle-path`}
115-
d={pathStyles.pathString}
116-
stroke={stroke}
117-
strokeLinecap={strokeLinecap}
118-
strokeWidth={strokeWidth}
119-
opacity={ptg === 0 ? 0 : 1}
120-
fillOpacity="0"
121-
style={pathStyles.pathStyle}
122-
ref={paths[index]}
123-
/>
124-
);
125-
});
136+
const pathDoms = percentList
137+
.map((ptg, index) => {
138+
const color = strokeColorList[index] || strokeColorList[strokeColorList.length - 1];
139+
const stroke =
140+
Object.prototype.toString.call(color) === '[object Object]'
141+
? `url(#${prefixCls}-gradient-${gradientId})`
142+
: '';
143+
const pathStyles = getPathStyles(stackPtg, ptg, color, strokeWidth, gapDegree, gapPosition);
144+
stackPtg += ptg;
145+
return (
146+
<path
147+
key={index}
148+
className={`${prefixCls}-circle-path`}
149+
d={pathStyles.pathString}
150+
stroke={stroke}
151+
strokeLinecap={strokeLinecap}
152+
strokeWidth={strokeWidth}
153+
opacity={ptg === 0 ? 0 : 1}
154+
fillOpacity="0"
155+
style={pathStyles.pathStyle}
156+
ref={paths[index]}
157+
/>
158+
);
159+
})
160+
.reverse();
161+
return pathDoms.concat(getDotList(pathDoms));
126162
};
127163

128164
return (
@@ -158,7 +194,7 @@ const Circle: React.FC<ProgressProps> = ({
158194
fillOpacity="0"
159195
style={pathStyle}
160196
/>
161-
{getStokeList().reverse()}
197+
{getStokeList()}
162198
</svg>
163199
);
164200
};

src/common.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useRef, useEffect } from 'react';
2-
import { ProgressProps } from './interface';
2+
import type { ProgressProps } from './interface';
33

44
export const defaultProps: Partial<ProgressProps> = {
55
className: '',
@@ -8,7 +8,7 @@ export const defaultProps: Partial<ProgressProps> = {
88
strokeColor: '#2db7f5',
99
strokeLinecap: 'round',
1010
strokeWidth: 1,
11-
style: {},
11+
style: { overflow: 'visible' },
1212
trailColor: '#D9D9D9',
1313
trailWidth: 1,
1414
};
@@ -21,7 +21,7 @@ export const useTransitionDuration = (percentList: number[]) => {
2121
const now = Date.now();
2222
let updated = false;
2323

24-
Object.keys(paths).forEach(key => {
24+
Object.keys(paths).forEach((key) => {
2525
const path = paths[key].current;
2626
if (!path) {
2727
return;

src/interface.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as React from 'react';
1+
import type * as React from 'react';
22

33
export interface ProgressProps {
44
strokeWidth?: number;
@@ -13,10 +13,13 @@ export interface ProgressProps {
1313
gapDegree?: number;
1414
gapPosition?: GapPositionType;
1515
transition?: string;
16+
dot?: dotType;
1617
}
1718

1819
export type StrokeColorType = string | string[] | object;
1920

2021
export type GapPositionType = 'top' | 'right' | 'bottom' | 'left';
2122

2223
export type StrokeLinecapType = 'round' | 'butt' | 'square';
24+
25+
export type dotType = boolean | object;

0 commit comments

Comments
 (0)