From 35a6b2e00910f69098915133cf4be098e4db91e0 Mon Sep 17 00:00:00 2001 From: zombiej Date: Thu, 17 Jan 2019 20:54:33 +0800 Subject: [PATCH 1/2] liner support --- examples/gap.js | 35 ++++++++++++++--------- examples/simple.js | 16 +++++++---- src/Circle.js | 71 ++++++++++++++++++++++++++++++---------------- src/Line.js | 44 ++++++++++++++++++---------- src/types.js | 10 ++++--- 5 files changed, 114 insertions(+), 62 deletions(-) diff --git a/examples/gap.js b/examples/gap.js index b6b7d4d..d6679dd 100644 --- a/examples/gap.js +++ b/examples/gap.js @@ -3,22 +3,26 @@ import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import { Circle } from 'rc-progress'; +const colorMap = ['#3FC7FA', '#85D262', '#FE8C6A']; +function getColor(index) { + return colorMap[(index + colorMap.length) % colorMap.length]; +} class Example extends Component { constructor() { super(); this.state = { percent: 30, - color: '#3FC7FA', + colorIndex: 0, }; this.changeState = this.changeState.bind(this); } changeState() { - const colorMap = ['#3FC7FA', '#85D262', '#FE8C6A']; const value = parseInt(Math.random() * 100, 10); + const colorIndex = parseInt(Math.random() * 3, 10); this.setState({ percent: value, - color: colorMap[parseInt(Math.random() * 3, 10)], + colorIndex, }); } @@ -27,52 +31,55 @@ class Example extends Component { width: '200px', height: '200px', }; + const { percent, colorIndex } = this.state; + const color = getColor(colorIndex); return (
+

+ +

+
-

- -

); } diff --git a/examples/simple.js b/examples/simple.js index b35903b..d90952f 100644 --- a/examples/simple.js +++ b/examples/simple.js @@ -23,6 +23,7 @@ class Example extends Component { } render() { + const { percent, color } = this.state; const containerStyle = { width: '250px', }; @@ -33,17 +34,22 @@ class Example extends Component { }; return (
-

Line Progress {this.state.percent}%

+

Line Progress {percent}%

- + +
-

Circle Progress {this.state.percent}%

+

Circle Progress {percent}%

diff --git a/src/Circle.js b/src/Circle.js index cd110ed..97e40a1 100644 --- a/src/Circle.js +++ b/src/Circle.js @@ -5,8 +5,7 @@ import enhancer from './enhancer'; import { propTypes, defaultProps } from './types'; class Circle extends Component { - getPathStyles() { - const { percent, strokeWidth, strokeColor, gapDegree = 0, gapPosition } = this.props; + getPathStyles(offset, percent, strokeColor, strokeWidth, gapDegree = 0, gapPosition) { const radius = 50 - (strokeWidth / 2); let beginPositionX = 0; let beginPositionY = -radius; @@ -35,29 +34,61 @@ class Circle extends Component { a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY} a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`; const len = Math.PI * 2 * radius; - const trailPathStyle = { - strokeDasharray: `${len - gapDegree}px ${len}px`, - strokeDashoffset: `-${gapDegree / 2}px`, - transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s', - }; - const strokePathStyle = { + + const pathStyle = { stroke: strokeColor, strokeDasharray: `${(percent / 100) * (len - gapDegree)}px ${len}px`, - strokeDashoffset: `-${gapDegree / 2}px`, + strokeDashoffset: `-${gapDegree / 2 + offset / 100 * (len - gapDegree)}px`, transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s', // eslint-disable-line }; - return { pathString, trailPathStyle, strokePathStyle }; + + return { + pathString, + pathStyle, + }; + } + + getStokeList() { + const { + prefixCls, percent, strokeColor, strokeWidth, strokeLinecap, + gapDegree, gapPosition, + } = this.props; + const percentList = Array.isArray(percent) ? percent : [percent]; + const strokeColorList = Array.isArray(strokeColor) ? strokeColor : [strokeColor]; + + let stackPtg = 0; + return percentList.map((ptg, index) => { + const color = strokeColorList[index] || strokeColorList[strokeColorList.length - 1]; + const { pathString, pathStyle } = this.getPathStyles( + stackPtg, ptg, color, strokeWidth, gapDegree, gapPosition + ); + + stackPtg += ptg; + + return ( + + ); + }); } render() { const { - prefixCls, strokeWidth, trailWidth, percent, + prefixCls, strokeWidth, trailWidth, + gapDegree, gapPosition, trailColor, strokeLinecap, style, className, ...restProps, } = this.props; - const { pathString, trailPathStyle, strokePathStyle } = this.getPathStyles(); + const { pathString, pathStyle } = this.getPathStyles( + 0, 100, trailColor, strokeWidth, gapDegree, gapPosition + ); delete restProps.percent; - delete restProps.gapDegree; - delete restProps.gapPosition; delete restProps.strokeColor; return ( - { this.path = path; }} - style={strokePathStyle} + style={pathStyle} /> + {this.getStokeList()} ); } diff --git a/src/Line.js b/src/Line.js index 747e0d7..ee6e064 100644 --- a/src/Line.js +++ b/src/Line.js @@ -19,11 +19,8 @@ class Line extends Component { delete restProps.gapPosition; - const pathStyle = { - strokeDasharray: '100px, 100px', - strokeDashoffset: `${(100 - percent)}px`, - transition: 'stroke-dashoffset 0.3s ease 0s, stroke 0.3s linear', - }; + const percentList = Array.isArray(percent) ? percent : [percent]; + const strokeColorList = Array.isArray(strokeColor) ? strokeColor : [strokeColor]; const center = strokeWidth / 2; const right = 100 - (strokeWidth / 2); @@ -32,6 +29,8 @@ class Line extends Component { L ${strokeLinecap === 'round' ? right : 100},${center}`; const viewBoxString = `0 0 100 ${strokeWidth}`; + let stackPtg = 0; + return ( - { this.path = path; }} - style={pathStyle} - /> + {percentList.map((ptg, index) => { + const pathStyle = { + strokeDasharray: `${ptg}px, 100px`, + strokeDashoffset: `-${stackPtg}px`, + transition: + 'stroke-dashoffset 0.3s ease 0s, stroke-dasharray .3s ease 0s, stroke 0.3s linear', + }; + const color = strokeColorList[index] || strokeColorList[strokeColorList.length - 1]; + + stackPtg += ptg; + + return ( + { this.path = path; }} + style={pathStyle} + /> + ); + })} ); } diff --git a/src/types.js b/src/types.js index 4a44dcc..d447ad3 100644 --- a/src/types.js +++ b/src/types.js @@ -12,14 +12,16 @@ export const defaultProps = { trailWidth: 1, }; +const mixedType = PropTypes.oneOfType([PropTypes.number, PropTypes.string]); + export const propTypes = { className: PropTypes.string, - percent: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + percent: PropTypes.oneOfType([mixedType, PropTypes.arrayOf(mixedType)]), prefixCls: PropTypes.string, - strokeColor: PropTypes.string, + strokeColor: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square']), - strokeWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + strokeWidth: mixedType, style: PropTypes.object, trailColor: PropTypes.string, - trailWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + trailWidth: mixedType, }; From a186af9db6fb467a5a77256db91ca588dd783f81 Mon Sep 17 00:00:00 2001 From: zombiej Date: Thu, 17 Jan 2019 23:11:40 +0800 Subject: [PATCH 2/2] update enhancer --- src/Circle.js | 5 +++++ src/Line.js | 6 +++++- src/enhancer.js | 28 ++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/Circle.js b/src/Circle.js index 97e40a1..c3f3663 100644 --- a/src/Circle.js +++ b/src/Circle.js @@ -74,11 +74,16 @@ class Circle extends Component { strokeWidth={ptg === 0 ? 0 : strokeWidth} fillOpacity="0" style={pathStyle} + ref={(path) => { + this.paths[index] = path; + }} /> ); }); } + paths = {}; + render() { const { prefixCls, strokeWidth, trailWidth, diff --git a/src/Line.js b/src/Line.js index ee6e064..35c0d70 100644 --- a/src/Line.js +++ b/src/Line.js @@ -3,6 +3,8 @@ import enhancer from './enhancer'; import { propTypes, defaultProps } from './types'; class Line extends Component { + paths = {}; + render() { const { className, @@ -67,7 +69,9 @@ class Line extends Component { stroke={color} strokeWidth={strokeWidth} fillOpacity="0" - ref={(path) => { this.path = path; }} + ref={(path) => { + this.paths[index] = path; + }} style={pathStyle} /> ); diff --git a/src/enhancer.js b/src/enhancer.js index 00b33a2..71272ff 100644 --- a/src/enhancer.js +++ b/src/enhancer.js @@ -1,15 +1,27 @@ const enhancer = WrappedComponent => class Progress extends WrappedComponent { componentDidUpdate() { - if (!this.path) { - return; - } - const pathStyle = this.path.style; - pathStyle.transitionDuration = '.3s, .3s, .3s, .06s'; const now = Date.now(); - if (this.prevTimeStamp && now - this.prevTimeStamp < 100) { - pathStyle.transitionDuration = '0s, 0s'; + let updated = false; + + Object.keys(this.paths).forEach((key) => { + const path = this.paths[key]; + + if (!path) { + return; + } + + updated = true; + const pathStyle = path.style; + pathStyle.transitionDuration = '.3s, .3s, .3s, .06s'; + + if (this.prevTimeStamp && now - this.prevTimeStamp < 100) { + pathStyle.transitionDuration = '0s, 0s'; + } + }); + + if (updated) { + this.prevTimeStamp = Date.now(); } - this.prevTimeStamp = Date.now(); } render() {