From ce00a975b4e61703eba5fb2b3aba7d744edd6b83 Mon Sep 17 00:00:00 2001 From: Danny van Kooten Date: Tue, 15 May 2018 22:26:24 +0200 Subject: [PATCH] animate numbers in count widget --- assets/js/components/CountWidget.js | 68 ++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/assets/js/components/CountWidget.js b/assets/js/components/CountWidget.js index 276ec39..0b19bc5 100644 --- a/assets/js/components/CountWidget.js +++ b/assets/js/components/CountWidget.js @@ -17,7 +17,7 @@ class CountWidget extends Component { super(props) this.state = { - value: '-', + value: 0.00, loading: false, before: props.before, after: props.after, @@ -32,11 +32,35 @@ class CountWidget extends Component { this.setState({ before: newProps.before, after: newProps.after, - value: '-', }); this.fetchData(); } + @bind + countUp(toValue) { + const duration = 1000; + const easeOutQuint = function (t) { return 1+(--t)*t*t*t*t }; + const setState = this.setState.bind(this); + const startValue = this.state.value; + const diff = toValue - startValue; + let startTime; + + const tick = function(t) { + if(!startTime) { startTime = t; } + let progress = ( t - startTime ) / duration; + let newValue = Math.round(startValue + (easeOutQuint(progress) * diff)); + setState({ + value: newValue, + }) + + if(progress < 1) { + window.requestAnimationFrame(tick); + } + } + + window.requestAnimationFrame(tick); + } + @bind fetchData() { this.setState({ loading: true }) @@ -50,33 +74,37 @@ class CountWidget extends Component { return; } - switch(this.props.format) { - case "percentage": - d = numbers.formatPercentage(d) - break; - - default: - case "number": - d = numbers.formatWithComma(d) - break; - - case "duration": - d = numbers.formatDuration(d) - break; - } - this.setState({ - loading: false, - value: d, + loading: false, }) + this.countUp(d); }) } render(props, state) { + let formattedValue = "-"; + + if(state.value > 0) { + switch(props.format) { + case "percentage": + formattedValue = numbers.formatPercentage(state.value) + break; + + default: + case "number": + formattedValue = numbers.formatWithComma(state.value) + break; + + case "duration": + formattedValue = numbers.formatDuration(state.value) + break; + } + } + return (
{props.title}
-
{state.value}
+
{formattedValue}
) }