Create a gist now

Instantly share code, notes, and snippets.

auto-updating counter with pusher and lots of javascript
/*
* by: https://github.com/cluesque and https://github.com/whatbird
* for: http://actblue.com
*
* blog post: http://blog.actbluetech.com/
*
* note: this implementation assumes you want to show "dollars" but receive data in "cents"
*
* requirements: jQuery, pusher.com account
*
* usage:
* push data to pusher with at least this info {amount: ###, total: ###}
* where "amount" is the new amount to add, and "total" is the cumulative amount.
*
* with js:
* var yourPusherKey = "ABCD1234";
* var yourPusherStreamName = 'app_events_production';
* var yourPusherEvent = 'new_data_coming_in';
* BigNumber.init($('div#yourBigNumber'), yourPusherKey, yourPusherStreamName, yourPusherEvent);
*/
var BigNumber = {
// Parameters controlling animation
tau: 10000, // Time constant on approaching correctness
minInterval: 100, // Minimum interval (msec) between updates
maxInterval: 440, // Maximum interval (msec) between updates
minTick: 1, // Minimum update amount
defined: function(variable) { return typeof variable !== 'undefined';},
commify: function(num) {
return num.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
},
currentAmount: function() {
return parseInt(BigNumber.element.data('amount') / 100);
},
displayedAmount: function() {
return parseInt(parseFloat("0"+BigNumber.element.text().replace(/[$,]/g,'')));
},
skew: function() {
return BigNumber.currentAmount() - BigNumber.displayedAmount();
},
init: function(element, key, stream, theEvent) {
BigNumber.element = element;
BigNumber.element.data('amount', BigNumber.displayedAmount()*100);
BigNumber.currentInterval = BigNumber.minInterval;
new Pusher(key).subscribe(stream).bind(theEvent, BigNumber.update);
},
update: function(data) {
var total, storedAmount = BigNumber.element.data('amount');
if(data.total > storedAmount) {
total = data.total + data.amount;
} else {
total = storedAmount + data.amount;
}
BigNumber.element.data('amount', total);
return BigNumber.startAnimation();
},
adjustAnimation: function(interval) {
if(interval != BigNumber.currentInterval) {
clearInterval(BigNumber.intervalId);
BigNumber.currentInterval = interval;
BigNumber.intervalId = setInterval(BigNumber.animate, BigNumber.currentInterval);
}
},
startAnimation: function() {
if(!BigNumber.defined(BigNumber.intervalId) || BigNumber.intervalId == null) {
BigNumber.intervalId = setInterval(BigNumber.animate, BigNumber.currentInterval);
}
return BigNumber;
},
stopAnimation: function() {
clearInterval(BigNumber.intervalId);
BigNumber.intervalId = null;
return BigNumber;
},
animate: function() {
if (BigNumber.displayedAmount() >= BigNumber.currentAmount()) {
BigNumber.stopAnimation();
} else {
var tick, interval, skew = BigNumber.skew();
if(skew < BigNumber.tau / BigNumber.maxInterval) {
tick = BigNumber.minTick;
interval = BigNumber.maxInterval;
}
else if(skew < BigNumber.tau / BigNumber.minInterval) {
tick = BigNumber.minTick;
interval = Math.ceil(BigNumber.tau / skew);
}
else {
interval = BigNumber.minInterval;
tick = Math.ceil(skew * BigNumber.minInterval / BigNumber.tau);
}
BigNumber.adjustAnimation(interval);
var newTotal = BigNumber.displayedAmount() + tick;
BigNumber.element.text(BigNumber.commify(newTotal));
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment