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 {
|
||||
stroke: #3f51b5;
|
||||
stroke-linecap: round;
|
||||
transition: stroke-dashoffset 5s ease 0s;
|
||||
transition: stroke-dashoffset 11s ease 0s;
|
||||
}
|
||||
|
||||
.trail {
|
||||
|
@ -7,13 +7,14 @@ class Progress extends Component {
|
||||
|
||||
this.state = {
|
||||
percentage: props.initialAnimation ? 0 : props.percentage,
|
||||
percentageText: props.initialAnimation ? 0 : props.percentage,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
if (this.props.initialAnimation) {
|
||||
this.initialTimeout = setTimeout(() => {
|
||||
this.requestAnimationFrame = window.requestAnimationFrame(() => {
|
||||
this.rafTimerInit = window.requestAnimationFrame(() => {
|
||||
this.setState({
|
||||
percentage: this.props.percentage,
|
||||
});
|
||||
@ -23,16 +24,78 @@ class Progress extends Component {
|
||||
}
|
||||
|
||||
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 () {
|
||||
clearTimeout(this.initialTimeout);
|
||||
window.cancelAnimationFrame(this.requestAnimationFrame);
|
||||
clearTimeout(this.nextTimer);
|
||||
window.cancelAnimationFrame(this.rafTimerInit);
|
||||
window.cancelAnimationFrame(this.rafCounterTimer);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { strokeWidth, percentage } = this.props;
|
||||
const { strokeWidth } = this.props;
|
||||
const radius = (50 - strokeWidth / 2);
|
||||
const pathDescription = `
|
||||
M 50,50 m 0,-${radius}
|
||||
@ -66,7 +129,7 @@ class Progress extends Component {
|
||||
className={styles.text}
|
||||
x={50}
|
||||
y={50}
|
||||
>{percentage}%</text>
|
||||
>{this.state.percentageText}%</text>
|
||||
</svg>);
|
||||
}
|
||||
}
|
||||
@ -75,11 +138,13 @@ Progress.propTypes = {
|
||||
percentage: PropTypes.number.isRequired,
|
||||
strokeWidth: PropTypes.number,
|
||||
initialAnimation: PropTypes.bool,
|
||||
animatePercentageText: PropTypes.bool,
|
||||
textForPercentage: PropTypes.func,
|
||||
};
|
||||
|
||||
Progress.defaultProps = {
|
||||
strokeWidth: 8,
|
||||
animatePercentageText: false,
|
||||
initialAnimation: false,
|
||||
};
|
||||
|
||||
|
@ -36,7 +36,7 @@ const MetricTab = ({ metrics, featureToggle, toggleFeature }) => {
|
||||
<Icon style={{ width: '100px', height: '100px', fontSize: '100px', color: '#ccc' }}
|
||||
name="report problem" title="No metrics avaiable" /> :
|
||||
<div>
|
||||
<Progress strokeWidth={10} percentage={lastMinutePercent} width="50" />
|
||||
<Progress animatePercentageText strokeWidth={10} percentage={lastMinutePercent} width="50" />
|
||||
</div>
|
||||
}
|
||||
<p><strong>Last minute</strong><br /> Yes {lastMinute.yes}, No: {lastMinute.no}</p>
|
||||
|
Loading…
Reference in New Issue
Block a user