Knockout Animation

by bakhshi

HTML

<script src="http://knockoutjs.com/downloads/knockout-2.3.0.js"></script>
<div class="output" data-bind="text:animatedNumber"></div>

<button data-bind="click:update">Update</button>

JavaScript

ko.extenders.animated = function(target,duration){
    console.log('extended', target, duration);
    var result = ko.observable(target());
    
    function animate(old, newValue){
        var steps = 100;
        var stepDuration = duration/steps;
        var currentStep = 0;
        console.log("animating", old, newValue, steps, stepDuration)
        var animationStep = function(){
            currentStep++;
            var stepValue = old + (newValue-old) * currentStep/steps;
            console.log('animation step', stepValue, currentStep);
            result(stepValue);
            
            if(currentStep >= steps)
            {
                result(newValue);
                return;
            }
            setTimeout(animationStep, stepDuration);
        }
        setTimeout(animationStep, stepDuration);        
    }
    
    target.subscribe(function(newValue){
        //cancel any exiting ones?
        animate(result(), newValue);
    });
    
    return result;
}

var number = ko.observable(1);
var model = {
    number: number,
    animatedNumber: number.extend({animated:2000}),
    update: function(){
            this.number(this.number() + 100);
    }
}

ko.applyBindings(model);