|
1 | 1 | /* eslint react/prop-types: 0 */ |
2 | | -import React, { Component } from 'react'; |
3 | | -import PropTypes from 'prop-types'; |
4 | | -import enhancer from './enhancer'; |
5 | | -import { propTypes, defaultProps } from './types'; |
| 2 | +import React, { useMemo } from 'react'; |
| 3 | +import classNames from 'classnames'; |
| 4 | +import { useTransitionDuration, defaultProps } from './common'; |
6 | 5 |
|
7 | 6 | let gradientSeed = 0; |
8 | 7 |
|
@@ -58,142 +57,105 @@ function getPathStyles(offset, percent, strokeColor, strokeWidth, gapDegree = 0, |
58 | 57 | }; |
59 | 58 | } |
60 | 59 |
|
61 | | -class Circle extends Component { |
62 | | - paths = {}; |
63 | | - |
64 | | - gradientId = 0; |
65 | | - |
66 | | - constructor() { |
67 | | - super(); |
68 | | - this.gradientId = gradientSeed; |
| 60 | +const Circle = ({ |
| 61 | + prefixCls, |
| 62 | + strokeWidth, |
| 63 | + trailWidth, |
| 64 | + gapDegree, |
| 65 | + gapPosition, |
| 66 | + trailColor, |
| 67 | + strokeLinecap, |
| 68 | + style, |
| 69 | + className, |
| 70 | + strokeColor, |
| 71 | + percent, |
| 72 | + ...restProps |
| 73 | +}) => { |
| 74 | + const gradientId = useMemo(() => { |
69 | 75 | gradientSeed += 1; |
70 | | - } |
71 | | - |
72 | | - getStokeList() { |
73 | | - const { |
74 | | - prefixCls, |
75 | | - percent, |
76 | | - strokeColor, |
77 | | - strokeWidth, |
78 | | - strokeLinecap, |
79 | | - gapDegree, |
80 | | - gapPosition, |
81 | | - } = this.props; |
82 | | - const percentList = toArray(percent); |
83 | | - const strokeColorList = toArray(strokeColor); |
84 | | - |
| 76 | + return gradientSeed; |
| 77 | + }, []); |
| 78 | + const { pathString, pathStyle } = getPathStyles( |
| 79 | + 0, |
| 80 | + 100, |
| 81 | + trailColor, |
| 82 | + strokeWidth, |
| 83 | + gapDegree, |
| 84 | + gapPosition, |
| 85 | + ); |
| 86 | + const percentList = toArray(percent); |
| 87 | + const strokeColorList = toArray(strokeColor); |
| 88 | + const gradient = strokeColorList.find( |
| 89 | + color => Object.prototype.toString.call(color) === '[object Object]', |
| 90 | + ); |
| 91 | + |
| 92 | + const [paths] = useTransitionDuration(percentList); |
| 93 | + |
| 94 | + const getStokeList = () => { |
85 | 95 | let stackPtg = 0; |
86 | 96 | return percentList.map((ptg, index) => { |
87 | 97 | const color = strokeColorList[index] || strokeColorList[strokeColorList.length - 1]; |
88 | 98 | const stroke = |
89 | 99 | Object.prototype.toString.call(color) === '[object Object]' |
90 | | - ? `url(#${prefixCls}-gradient-${this.gradientId})` |
| 100 | + ? `url(#${prefixCls}-gradient-${gradientId})` |
91 | 101 | : ''; |
92 | | - const { pathString, pathStyle } = getPathStyles( |
93 | | - stackPtg, |
94 | | - ptg, |
95 | | - color, |
96 | | - strokeWidth, |
97 | | - gapDegree, |
98 | | - gapPosition, |
99 | | - ); |
100 | | - |
| 102 | + const pathStyles = getPathStyles(stackPtg, ptg, color, strokeWidth, gapDegree, gapPosition); |
101 | 103 | stackPtg += ptg; |
102 | | - |
103 | 104 | return ( |
104 | 105 | <path |
105 | 106 | key={index} |
106 | 107 | className={`${prefixCls}-circle-path`} |
107 | | - d={pathString} |
| 108 | + d={pathStyles.pathString} |
108 | 109 | stroke={stroke} |
109 | 110 | strokeLinecap={strokeLinecap} |
110 | 111 | strokeWidth={strokeWidth} |
111 | 112 | opacity={ptg === 0 ? 0 : 1} |
112 | 113 | fillOpacity="0" |
113 | | - style={pathStyle} |
114 | | - ref={path => { |
115 | | - this.paths[index] = path; |
116 | | - }} |
| 114 | + style={pathStyles.pathStyle} |
| 115 | + ref={paths[index]} |
117 | 116 | /> |
118 | 117 | ); |
119 | 118 | }); |
120 | | - } |
121 | | - |
122 | | - render() { |
123 | | - const { |
124 | | - prefixCls, |
125 | | - strokeWidth, |
126 | | - trailWidth, |
127 | | - gapDegree, |
128 | | - gapPosition, |
129 | | - trailColor, |
130 | | - strokeLinecap, |
131 | | - style, |
132 | | - className, |
133 | | - strokeColor, |
134 | | - ...restProps |
135 | | - } = this.props; |
136 | | - const { pathString, pathStyle } = getPathStyles( |
137 | | - 0, |
138 | | - 100, |
139 | | - trailColor, |
140 | | - strokeWidth, |
141 | | - gapDegree, |
142 | | - gapPosition, |
143 | | - ); |
144 | | - delete restProps.percent; |
145 | | - const strokeColorList = toArray(strokeColor); |
146 | | - const gradient = strokeColorList.find( |
147 | | - color => Object.prototype.toString.call(color) === '[object Object]', |
148 | | - ); |
149 | | - |
150 | | - return ( |
151 | | - <svg |
152 | | - className={`${prefixCls}-circle ${className}`} |
153 | | - viewBox="0 0 100 100" |
154 | | - style={style} |
155 | | - {...restProps} |
156 | | - > |
157 | | - {gradient && ( |
158 | | - <defs> |
159 | | - <linearGradient |
160 | | - id={`${prefixCls}-gradient-${this.gradientId}`} |
161 | | - x1="100%" |
162 | | - y1="0%" |
163 | | - x2="0%" |
164 | | - y2="0%" |
165 | | - > |
166 | | - {Object.keys(gradient) |
167 | | - .sort((a, b) => stripPercentToNumber(a) - stripPercentToNumber(b)) |
168 | | - .map((key, index) => ( |
169 | | - <stop key={index} offset={key} stopColor={gradient[key]} /> |
170 | | - ))} |
171 | | - </linearGradient> |
172 | | - </defs> |
173 | | - )} |
174 | | - <path |
175 | | - className={`${prefixCls}-circle-trail`} |
176 | | - d={pathString} |
177 | | - stroke={trailColor} |
178 | | - strokeLinecap={strokeLinecap} |
179 | | - strokeWidth={trailWidth || strokeWidth} |
180 | | - fillOpacity="0" |
181 | | - style={pathStyle} |
182 | | - /> |
183 | | - {this.getStokeList().reverse()} |
184 | | - </svg> |
185 | | - ); |
186 | | - } |
187 | | -} |
| 119 | + }; |
188 | 120 |
|
189 | | -Circle.propTypes = { |
190 | | - ...propTypes, |
191 | | - gapPosition: PropTypes.oneOf(['top', 'bottom', 'left', 'right']), |
| 121 | + return ( |
| 122 | + <svg |
| 123 | + className={classNames(`${prefixCls}-circle`, className)} |
| 124 | + viewBox="0 0 100 100" |
| 125 | + style={style} |
| 126 | + {...restProps} |
| 127 | + > |
| 128 | + {gradient && ( |
| 129 | + <defs> |
| 130 | + <linearGradient |
| 131 | + id={`${prefixCls}-gradient-${gradientId}`} |
| 132 | + x1="100%" |
| 133 | + y1="0%" |
| 134 | + x2="0%" |
| 135 | + y2="0%" |
| 136 | + > |
| 137 | + {Object.keys(gradient) |
| 138 | + .sort((a, b) => stripPercentToNumber(a) - stripPercentToNumber(b)) |
| 139 | + .map((key, index) => ( |
| 140 | + <stop key={index} offset={key} stopColor={gradient[key]} /> |
| 141 | + ))} |
| 142 | + </linearGradient> |
| 143 | + </defs> |
| 144 | + )} |
| 145 | + <path |
| 146 | + className={`${prefixCls}-circle-trail`} |
| 147 | + d={pathString} |
| 148 | + stroke={trailColor} |
| 149 | + strokeLinecap={strokeLinecap} |
| 150 | + strokeWidth={trailWidth || strokeWidth} |
| 151 | + fillOpacity="0" |
| 152 | + style={pathStyle} |
| 153 | + /> |
| 154 | + {getStokeList().reverse()} |
| 155 | + </svg> |
| 156 | + ); |
192 | 157 | }; |
193 | 158 |
|
194 | | -Circle.defaultProps = { |
195 | | - ...defaultProps, |
196 | | - gapPosition: 'top', |
197 | | -}; |
| 159 | +Circle.defaultProps = defaultProps; |
198 | 160 |
|
199 | | -export default enhancer(Circle); |
| 161 | +export default Circle; |
0 commit comments