
Angularjs Directive for Number Counting Effects
Hi guys, I was working on a simple dashboard which shows a number of views and likes. Instead of showing static numbers, I decided to give some number changing effects. I wanted an animation where number would count up and slow down at the end. Before I write my own angular directive, I decided to check online if someone from angular community already have something like it. After googling for few minutes, I couldn’t find exactly what I was looking for but I did find an angular directive count-to which was close to what I wanted. I took his work and modified it for my needs. Below is my hack.
.directive('animateNumbers',function ($timeout) { return { replace: false, scope: true, link: function (scope, element, attrs) { var e = element[0]; var refreshInterval = 30; var duration = 1000; //milliseconds var number = parseInt(e.innerText); var step = 0; var num = 0; var steps = Math.ceil(duration / refreshInterval); var increment = (number / steps); var percentCompleted = 0; var lastNumberSlowCount = 3; if(number > lastNumberSlowCount){ number = number - lastNumberSlowCount; } scope.timoutId = null; var counter = function () { scope.timoutId = $timeout(function () { num += increment; percentCompleted = Math.round((num/number) * 100); if(percentCompleted > 60 && percentCompleted < 80){ refreshInterval = refreshInterval + 10; } else if (percentCompleted > 90){ refreshInterval = 200; } step++; if (step >= steps) { $timeout.cancel(scope.timoutId); num = number; e.textContent = number; if(number > lastNumberSlowCount){ slowCounter(); } } else { e.textContent = Math.round(num); counter(); } }, refreshInterval); } var slowCounter = function(){ scope.timoutId = $timeout(function () { lastNumberSlowCount --; if(lastNumberSlowCount < 0){ $timeout.cancel(scope.timoutId); } else { number++; e.textContent = number; slowCounter(); } },500) } counter(); return true; } } });
Finally, just throw in animate-numbers attribute in your tag like <div animate-numbers>1021</div> and you are good to go.