diff --git a/CHANGELOG.md b/CHANGELOG.md index e27d745d34..f8c0864e48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,25 @@ ##### Breaking Changes - [Badge] Swapped primary and accent colors (#4449) +- [CircularProgress] The API has become more flexible and straightforward. `size` attribute now means the outer diameter in pixels. Line thickness is variable and should be defined via the `thickness` attribute. Default margins are eliminated. If you'd like to upgrade your existing app without changing the actual sizes of your `CircularProgress` components, here are the formulas: +```js +newSize = 59.5 * oldSize; +thickness = 3.5 * oldSize; +margin = (oldSize < 0.71) ? + ((50 - 59.5 * oldSize) / 2) : + (5.25 * oldSize); +``` + +Examples: +``` +// Before: + + + +// After: + // Thickness is 3.5 by default + +``` ## 0.15.2 ###### _Jul 7, 2016_ diff --git a/docs/src/app/components/pages/components/CircularProgress/ExampleDeterminate.js b/docs/src/app/components/pages/components/CircularProgress/ExampleDeterminate.js index bd6f660b77..7167cf5098 100644 --- a/docs/src/app/components/pages/components/CircularProgress/ExampleDeterminate.js +++ b/docs/src/app/components/pages/components/CircularProgress/ExampleDeterminate.js @@ -32,9 +32,22 @@ export default class CircularProgressExampleDeterminate extends React.Component render() { return (
- - - + + +
); } diff --git a/docs/src/app/components/pages/components/CircularProgress/ExampleSimple.js b/docs/src/app/components/pages/components/CircularProgress/ExampleSimple.js index 56f96e989a..ad948839de 100644 --- a/docs/src/app/components/pages/components/CircularProgress/ExampleSimple.js +++ b/docs/src/app/components/pages/components/CircularProgress/ExampleSimple.js @@ -4,8 +4,8 @@ import CircularProgress from 'material-ui/CircularProgress'; const CircularProgressExampleSimple = () => (
- - + +
); diff --git a/src/CircularProgress/CircularProgress.js b/src/CircularProgress/CircularProgress.js index 9c3eddcf53..8299e9905a 100644 --- a/src/CircularProgress/CircularProgress.js +++ b/src/CircularProgress/CircularProgress.js @@ -4,9 +4,11 @@ import transitions from '../styles/transitions'; function getRelativeValue(value, min, max) { const clampedValue = Math.min(Math.max(min, value), max); - const rangeValue = max - min; - const relValue = Math.round(clampedValue / rangeValue * 10000) / 10000; - return relValue * 100; + return clampedValue / (max - min); +} + +function getArcLength(fraction, props) { + return fraction * Math.PI * (props.size - props.thickness); } function getStyles(props, context) { @@ -18,36 +20,27 @@ function getStyles(props, context) { } = props; const {baseTheme: {palette}} = context.muiTheme; - const zoom = size * 1.4 ; - const baseSize = 50; - let margin = Math.round( ((50 * zoom) - 50) / 2 ); - - if (margin < 0) margin = 0; const styles = { root: { position: 'relative', - margin: margin, display: 'inline-block', - width: baseSize, - height: baseSize, + width: size, + height: size, }, wrapper: { - width: baseSize, - height: baseSize, + width: size, + height: size, display: 'inline-block', transition: transitions.create('transform', '20s', null, 'linear'), transitionTimingFunction: 'linear', }, svg: { - height: baseSize, + width: size, + height: size, position: 'relative', - transform: `scale(${zoom})`, - width: baseSize, }, path: { - strokeDasharray: '89, 200', - strokeDashoffset: 0, stroke: props.color || palette.primary1Color, strokeLinecap: 'round', transition: transitions.create('all', '1.5s', null, 'ease-in-out'), @@ -57,7 +50,7 @@ function getStyles(props, context) { if (props.mode === 'determinate') { const relVal = getRelativeValue(value, min, max); styles.path.transition = transitions.create('all', '0.3s', null, 'linear'); - styles.path.strokeDasharray = `${Math.round(relVal * 1.25)}, 200`; + styles.path.strokeDasharray = `${getArcLength(relVal, props)}, ${getArcLength(1, props)}`; } return styles; @@ -87,13 +80,17 @@ class CircularProgress extends Component { */ mode: PropTypes.oneOf(['determinate', 'indeterminate']), /** - * The size of the progress. + * The diameter of the progress in pixels. */ size: PropTypes.number, /** * Override the inline-styles of the root element. */ style: PropTypes.object, + /** + * Stroke width in pixels. + */ + thickness: PropTypes.number, /** * The value of progress, only works in determinate mode. */ @@ -105,7 +102,8 @@ class CircularProgress extends Component { value: 0, min: 0, max: 100, - size: 1, + size: 40, + thickness: 3.5, }; static contextTypes = { @@ -122,23 +120,22 @@ class CircularProgress extends Component { clearTimeout(this.rotateWrapperTimer); } - scalePath(path, step) { + scalePath(path, step = 0) { if (this.props.mode !== 'indeterminate') return; - step = step || 0; step %= 3; if (step === 0) { - path.style.strokeDasharray = '1, 200'; + path.style.strokeDasharray = `${getArcLength(0, this.props)}, ${getArcLength(1, this.props)}`; path.style.strokeDashoffset = 0; path.style.transitionDuration = '0ms'; } else if (step === 1) { - path.style.strokeDasharray = '89, 200'; - path.style.strokeDashoffset = -35; + path.style.strokeDasharray = `${getArcLength(0.7, this.props)}, ${getArcLength(1, this.props)}`; + path.style.strokeDashoffset = getArcLength(-0.3, this.props); path.style.transitionDuration = '750ms'; } else { - path.style.strokeDasharray = '89, 200'; - path.style.strokeDashoffset = -124; + path.style.strokeDasharray = `${getArcLength(0.7, this.props)}, ${getArcLength(1, this.props)}`; + path.style.strokeDashoffset = getArcLength(-1, this.props); path.style.transitionDuration = '850ms'; } @@ -164,7 +161,8 @@ class CircularProgress extends Component { const { style, innerStyle, - size, // eslint-disable-line no-unused-vars + size, + thickness, ...other, } = this.props; @@ -174,15 +172,18 @@ class CircularProgress extends Component { return (
- +