1
1
import * as React from 'react' ;
2
2
import type { ProgressProps } from '..' ;
3
- import type { StrokeColorType } from '../interface' ;
3
+ import type { StrokeColorObject } from '../interface' ;
4
+
5
+ interface BlockProps {
6
+ bg : string ;
7
+ children ?: React . ReactNode ;
8
+ }
9
+
10
+ const Block = ( { bg, children } : BlockProps ) => (
11
+ < div
12
+ style = { {
13
+ width : '100%' ,
14
+ height : '100%' ,
15
+ background : bg ,
16
+ } }
17
+ >
18
+ { children }
19
+ </ div >
20
+ ) ;
21
+
22
+ function getPtgColors ( color : Record < string , string > , scale : number ) {
23
+ return Object . keys ( color ) . map ( ( key ) => {
24
+ const parsedKey = parseFloat ( key ) ;
25
+ const ptgKey = `${ Math . floor ( parsedKey * scale ) } %` ;
26
+
27
+ return `${ color [ key ] } ${ ptgKey } ` ;
28
+ } ) ;
29
+ }
4
30
5
31
export interface ColorGradientProps {
6
32
prefixCls : string ;
@@ -11,8 +37,7 @@ export interface ColorGradientProps {
11
37
strokeLinecap : ProgressProps [ 'strokeLinecap' ] ;
12
38
strokeWidth : ProgressProps [ 'strokeWidth' ] ;
13
39
size : number ;
14
- color : StrokeColorType ;
15
- conic : boolean ;
40
+ color : string | StrokeColorObject ;
16
41
gapDegree : number ;
17
42
}
18
43
@@ -27,19 +52,12 @@ const PtgCircle = React.forwardRef<SVGCircleElement, ColorGradientProps>((props,
27
52
strokeLinecap,
28
53
strokeWidth,
29
54
size,
30
- conic,
31
55
gapDegree,
32
56
} = props ;
33
57
34
58
const isGradient = color && typeof color === 'object' ;
35
59
36
- const stroke = React . useMemo ( ( ) => {
37
- if ( conic ) {
38
- return '#FFF' ;
39
- }
40
-
41
- return isGradient ? `url(#${ gradientId } )` : undefined ;
42
- } , [ gradientId , isGradient , conic ] ) ;
60
+ const stroke = isGradient ? `#FFF` : undefined ;
43
61
44
62
// ========================== Circle ==========================
45
63
const halfSize = size / 2 ;
@@ -60,36 +78,30 @@ const PtgCircle = React.forwardRef<SVGCircleElement, ColorGradientProps>((props,
60
78
) ;
61
79
62
80
// ========================== Render ==========================
63
- if ( ! conic ) {
81
+ if ( ! isGradient ) {
64
82
return circleNode ;
65
83
}
66
84
67
85
const maskId = `${ gradientId } -conic` ;
68
- const conicColorKeys = Object . keys ( color ) . filter ( ( key ) => key !== 'conic' ) ;
69
86
70
87
const fromDeg = gapDegree ? `${ 180 + gapDegree / 2 } deg` : '0deg' ;
71
88
72
- const conicColors = conicColorKeys . map ( ( key ) => {
73
- const parsedKey = parseFloat ( key ) ;
74
- const ptgKey = `${ gapDegree ? Math . floor ( ( parsedKey * ( 360 - gapDegree ) ) / 360 ) : parsedKey } %` ;
75
-
76
- return `${ color [ key ] } ${ ptgKey } ` ;
77
- } ) ;
89
+ const conicColors = getPtgColors ( color , ( 360 - gapDegree ) / 360 ) ;
90
+ const linearColors = getPtgColors ( color , 1 ) ;
78
91
79
92
const conicColorBg = `conic-gradient(from ${ fromDeg } , ${ conicColors . join ( ', ' ) } )` ;
93
+ const linearColorBg = `linear-gradient(to ${ gapDegree ? 'bottom' : 'top' } , ${ linearColors . join (
94
+ ', ' ,
95
+ ) } )`;
80
96
81
97
return (
82
98
< >
83
99
< mask id = { maskId } > { circleNode } </ mask >
84
100
85
101
< foreignObject x = { 0 } y = { 0 } width = { size } height = { size } mask = { `url(#${ maskId } )` } >
86
- < div
87
- style = { {
88
- width : '100%' ,
89
- height : '100%' ,
90
- background : conicColorBg ,
91
- } }
92
- />
102
+ < Block bg = { linearColorBg } >
103
+ < Block bg = { conicColorBg } />
104
+ </ Block >
93
105
</ foreignObject >
94
106
</ >
95
107
) ;
0 commit comments