mirror of
https://github.com/status-im/fathom.git
synced 2025-03-01 11:30:28 +00:00
improve animation performance of countup by reffing element directly (vs state update)
This commit is contained in:
parent
c2e63a2dd3
commit
13a1222f54
@ -4,40 +4,31 @@ import { h, Component } from 'preact';
|
|||||||
import * as numbers from '../lib/numbers.js';
|
import * as numbers from '../lib/numbers.js';
|
||||||
import { bind } from 'decko';
|
import { bind } from 'decko';
|
||||||
|
|
||||||
|
const duration = 1000;
|
||||||
|
const easeOutQuint = function (t) { return 1+(--t)*t*t*t*t };
|
||||||
|
|
||||||
class CountWidget extends Component {
|
class CountWidget extends Component {
|
||||||
constructor(props) {
|
|
||||||
super(props)
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
value: "-"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps(newProps, newState) {
|
componentWillReceiveProps(newProps, newState) {
|
||||||
if(newProps.value == this.props.value) {
|
if(newProps.value == this.props.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.countUp(newProps.value);
|
this.countUp(this.props.value || 0, newProps.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move to component of its own
|
// TODO: Move to component of its own
|
||||||
@bind
|
@bind
|
||||||
countUp(toValue) {
|
countUp(fromValue, toValue) {
|
||||||
const duration = 1000;
|
const format = this.formatValue.bind(this);
|
||||||
const easeOutQuint = function (t) { return 1+(--t)*t*t*t*t };
|
const startValue = isFinite(fromValue) ? fromValue : 0;
|
||||||
const setState = this.setState.bind(this);
|
const numberEl = this.numberEl;
|
||||||
const startValue = isFinite(this.state.value) ? this.state.value : 0;
|
|
||||||
const diff = toValue - startValue;
|
const diff = toValue - startValue;
|
||||||
let startTime = performance.now();
|
let startTime = performance.now();
|
||||||
|
|
||||||
const tick = function(t) {
|
const tick = function(t) {
|
||||||
let progress = Math.min(( t - startTime ) / duration, 1);
|
let progress = Math.min(( t - startTime ) / duration, 1);
|
||||||
let newValue = startValue + (easeOutQuint(progress) * diff);
|
let newValue = startValue + (easeOutQuint(progress) * diff);
|
||||||
setState({
|
numberEl.textContent = format(newValue)
|
||||||
value: newValue,
|
|
||||||
})
|
|
||||||
|
|
||||||
if(progress < 1) {
|
if(progress < 1) {
|
||||||
window.requestAnimationFrame(tick);
|
window.requestAnimationFrame(tick);
|
||||||
@ -47,30 +38,35 @@ class CountWidget extends Component {
|
|||||||
window.requestAnimationFrame(tick);
|
window.requestAnimationFrame(tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(props, state) {
|
@bind
|
||||||
|
formatValue(value) {
|
||||||
let formattedValue = "-";
|
let formattedValue = "-";
|
||||||
|
|
||||||
if(isFinite(state.value)) {
|
if(isFinite(value)) {
|
||||||
switch(props.format) {
|
switch(this.props.format) {
|
||||||
case "percentage":
|
case "percentage":
|
||||||
formattedValue = numbers.formatPercentage(state.value)
|
formattedValue = numbers.formatPercentage(value)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
case "number":
|
case "number":
|
||||||
formattedValue = numbers.formatPretty(Math.round(state.value))
|
formattedValue = numbers.formatPretty(Math.round(value))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "duration":
|
case "duration":
|
||||||
formattedValue = numbers.formatDuration(state.value)
|
formattedValue = numbers.formatDuration(value)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return formattedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(props, state) {
|
||||||
return (
|
return (
|
||||||
<div class={"totals-detail " + ( props.loading ? "loading" : '')}>
|
<div class={"totals-detail " + ( props.loading ? "loading" : '')}>
|
||||||
<div class="total-heading">{props.title}</div>
|
<div class="total-heading">{props.title}</div>
|
||||||
<div class="total-numbers">{formattedValue}</div>
|
<div class="total-numbers" ref={(e) => { this.numberEl = e; }}>{this.formatValue(props.value)}</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user