mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-03 01:18:43 +02:00
add animation of percent text when in expanded view
This commit is contained in:
parent
138279d415
commit
efcfcfa347
@ -1,7 +1,7 @@
|
|||||||
.path {
|
.path {
|
||||||
stroke: #3f51b5;
|
stroke: #3f51b5;
|
||||||
stroke-linecap: round;
|
stroke-linecap: round;
|
||||||
transition: stroke-dashoffset 5s ease 0s;
|
transition: stroke-dashoffset 11s ease 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.trail {
|
.trail {
|
||||||
@ -14,4 +14,4 @@
|
|||||||
line-height: 25px;
|
line-height: 25px;
|
||||||
dominant-baseline: middle;
|
dominant-baseline: middle;
|
||||||
text-anchor: middle;
|
text-anchor: middle;
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,14 @@ class Progress extends Component {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
percentage: props.initialAnimation ? 0 : props.percentage,
|
percentage: props.initialAnimation ? 0 : props.percentage,
|
||||||
|
percentageText: props.initialAnimation ? 0 : props.percentage,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
if (this.props.initialAnimation) {
|
if (this.props.initialAnimation) {
|
||||||
this.initialTimeout = setTimeout(() => {
|
this.initialTimeout = setTimeout(() => {
|
||||||
this.requestAnimationFrame = window.requestAnimationFrame(() => {
|
this.rafTimerInit = window.requestAnimationFrame(() => {
|
||||||
this.setState({
|
this.setState({
|
||||||
percentage: this.props.percentage,
|
percentage: this.props.percentage,
|
||||||
});
|
});
|
||||||
@ -23,16 +24,78 @@ class Progress extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps ({ percentage }) {
|
componentWillReceiveProps ({ percentage }) {
|
||||||
this.setState({ percentage });
|
if (this.state.percentage !== percentage) {
|
||||||
|
const nextState = { percentage };
|
||||||
|
if (this.props.animatePercentageText) {
|
||||||
|
this.animateTo(percentage, this.getTarget(percentage));
|
||||||
|
} else {
|
||||||
|
nextState.percentageText = percentage;
|
||||||
|
}
|
||||||
|
this.setState(nextState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTarget (target) {
|
||||||
|
const start = this.state.percentageText;
|
||||||
|
const TOTAL_ANIMATION_TIME = 10000;
|
||||||
|
const diff = start > target ? -(start - target) : target - start;
|
||||||
|
const perCycle = TOTAL_ANIMATION_TIME / diff;
|
||||||
|
const cyclesCounter = Math.round(Math.abs(TOTAL_ANIMATION_TIME / perCycle));
|
||||||
|
const perCycleTime = Math.round(Math.abs(perCycle));
|
||||||
|
|
||||||
|
let usedTime = 0;
|
||||||
|
// this initial value could be tweaked more
|
||||||
|
let lastTime = perCycleTime / 4;
|
||||||
|
return {
|
||||||
|
start,
|
||||||
|
target,
|
||||||
|
cyclesCounter,
|
||||||
|
getTimer () {
|
||||||
|
/* Somewhat tweaked values to get a curve on the counting */
|
||||||
|
if (usedTime > (TOTAL_ANIMATION_TIME / 2)) {
|
||||||
|
// if halfway, lets speed up timeouts
|
||||||
|
lastTime *= 0.95;
|
||||||
|
} else {
|
||||||
|
lastTime *= 1.1;
|
||||||
|
}
|
||||||
|
usedTime += lastTime;
|
||||||
|
return lastTime;
|
||||||
|
},
|
||||||
|
increment: diff / cyclesCounter,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
animateTo (percentage, targetState) {
|
||||||
|
cancelAnimationFrame(this.rafCounterTimer);
|
||||||
|
clearTimeout(this.nextTimer);
|
||||||
|
|
||||||
|
const current = this.state.percentageText;
|
||||||
|
|
||||||
|
targetState.cyclesCounter --;
|
||||||
|
if (targetState.cyclesCounter <= 0) {
|
||||||
|
this.setState({ percentageText: targetState.target });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const next = Math.round(current + targetState.increment);
|
||||||
|
this.rafCounterTimer = requestAnimationFrame(() => {
|
||||||
|
this.setState({ percentageText: next });
|
||||||
|
this.nextTimer = setTimeout(() => {
|
||||||
|
this.animateTo(next, targetState);
|
||||||
|
}, targetState.getTimer());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
clearTimeout(this.initialTimeout);
|
clearTimeout(this.initialTimeout);
|
||||||
window.cancelAnimationFrame(this.requestAnimationFrame);
|
clearTimeout(this.nextTimer);
|
||||||
|
window.cancelAnimationFrame(this.rafTimerInit);
|
||||||
|
window.cancelAnimationFrame(this.rafCounterTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { strokeWidth, percentage } = this.props;
|
const { strokeWidth } = this.props;
|
||||||
const radius = (50 - strokeWidth / 2);
|
const radius = (50 - strokeWidth / 2);
|
||||||
const pathDescription = `
|
const pathDescription = `
|
||||||
M 50,50 m 0,-${radius}
|
M 50,50 m 0,-${radius}
|
||||||
@ -66,7 +129,7 @@ class Progress extends Component {
|
|||||||
className={styles.text}
|
className={styles.text}
|
||||||
x={50}
|
x={50}
|
||||||
y={50}
|
y={50}
|
||||||
>{percentage}%</text>
|
>{this.state.percentageText}%</text>
|
||||||
</svg>);
|
</svg>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,11 +138,13 @@ Progress.propTypes = {
|
|||||||
percentage: PropTypes.number.isRequired,
|
percentage: PropTypes.number.isRequired,
|
||||||
strokeWidth: PropTypes.number,
|
strokeWidth: PropTypes.number,
|
||||||
initialAnimation: PropTypes.bool,
|
initialAnimation: PropTypes.bool,
|
||||||
|
animatePercentageText: PropTypes.bool,
|
||||||
textForPercentage: PropTypes.func,
|
textForPercentage: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
Progress.defaultProps = {
|
Progress.defaultProps = {
|
||||||
strokeWidth: 8,
|
strokeWidth: 8,
|
||||||
|
animatePercentageText: false,
|
||||||
initialAnimation: false,
|
initialAnimation: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ const MetricTab = ({ metrics, featureToggle, toggleFeature }) => {
|
|||||||
<Icon style={{ width: '100px', height: '100px', fontSize: '100px', color: '#ccc' }}
|
<Icon style={{ width: '100px', height: '100px', fontSize: '100px', color: '#ccc' }}
|
||||||
name="report problem" title="No metrics avaiable" /> :
|
name="report problem" title="No metrics avaiable" /> :
|
||||||
<div>
|
<div>
|
||||||
<Progress strokeWidth={10} percentage={lastMinutePercent} width="50" />
|
<Progress animatePercentageText strokeWidth={10} percentage={lastMinutePercent} width="50" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<p><strong>Last minute</strong><br /> Yes {lastMinute.yes}, No: {lastMinute.no}</p>
|
<p><strong>Last minute</strong><br /> Yes {lastMinute.yes}, No: {lastMinute.no}</p>
|
||||||
|
Loading…
Reference in New Issue
Block a user