CanJs Livebinding vs. Ember vs. Backbone vs. Knockout vs. YUI

Animating 100 (or N) circles

HTML

<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>
<script src="https://github.com/downloads/emberjs/ember.js/ember-0.9.8.1.js"></script>
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.js"></script>
<script src="http://yui.yahooapis.com/3.5.0pr2/build/yui/yui-min.js"></script>
<script src="http://canjs.us/release/latest/can.jquery.js"></script>
<script src="http://canjs.us/release/latest/can.view.mustache.js"></script>

<button onclick="runCan('ejs')">Animate with Can (EJS)</button>
<button onclick="runCan('mustache')">Animate with Can (Mustache)</button>
<button onclick="runBackbone()">Animate with Backbone</button>
<button onclick="runEmber()">Animate with Ember</button>
<button onclick="runKnockout()">Animate with Knockout</button>
<button onclick="runYUI()">Animate with YUI</button>
<button onclick="reset()">Reset</button>

<div id="grid"></div>

<script type="text/ejs" id="ejs-template">
  <% can.each(boxes, function( box ) { %>
    <div class="box-view">
      <div class="box" id="box-<%= box.count  %>" style="<%= box.style() %>">
        <%= box.content() %>
      </div>
    </div>
  <% }) %>
</script>

<script type="text/mustache" id="mustache-template">
  {{#boxes}}
  <div class="box-view">
    <div class="box" id="{{count}}" style="{{style}}"}}>
      {{content}}
    </div>
    </div>
  {{/#boxes}}
</script>

<script type="x-template" id="underscore-template">
  <div class="box" id="box-<%= number %>" style="top: <%= top %>px; left: <%= left %>px; background: rgb(0,0,<%= color %>);">
    <%= content %>
  </div>
</script>

<script type="text/x-handlebars" id="handlebars-template" data-template-name="box">
  <div class="box" {{bindAttr id="model.number" style="model.style"}}>
    {{ model.content }}
  </div>
</script>

<script type="text/x-template"...

CSS

p {
  font: 12px/16px Arial;
  margin: 10px 10px 15px;    
}

button {
  font: bold 14px/14px Arial;  
  margin-left: 10px;
}

#grid {
  margin: 10px;   
}

.box-view {
  width: 20px; height: 20px;
  float: left;
  position: relative;
  margin: 8px;    
}

.box {
  border-radius: 100px;
  width: 20px; height: 10px;
  padding: 5px 0;
  color: #fff;
  font: 10px/10px Arial;
  text-align: center;
  position: absolute;
}

JavaScript

// Change N to change the number of drawn circles.
var N = 100;

//CanJS
(function() {

    var Box = function() {
        return {
            count: 0,
            top: function() {
                return (Math.sin(this.attr('count') / 10) * 10) + 'px'
            },
            left: function() {
                return (Math.cos(this.attr('count') / 10) * 10) + 'px'
            },
            color: function() {
                return 'rgb(0,0,' + (this.attr('count')) % 255 + ')'
            },
            content: function() {
                return this.attr('count') % 100
            },
            tick: function() {
                var newCount = this.attr('count') + 1;
                this.attr('count', newCount);
            },
            style: function() {
                return 'top: ' + this.top() + '; left: ' + this.left() + '; background: ' + this.color() + ';';
            }
        }
    },

        canInit = function(tmpl) {
            boxes = new can.Observe.List();
            for (var i = 0; i < N; i++) {
                boxes.push(new Box());
            }
            if (tmpl === 'ejs') {
                $('#grid').append(can.view('ejs-template', {
                    boxes: boxes
                }));
            } else {
                $('#grid').append(can.view('mustache-template', {
                    boxes: boxes
                }));
            }
        },
        canAnimate = function() {
            can.Observe.startBatch();
            for (var i = 0; i < N; i++) {
                boxes[i].tick();
            }
            can.Observe.stopBatch();
            window.timeout = _.defer(canAnimate);
        };

    window.runCan = function(tmpl) {
        reset();
        canInit(tmpl);
        canAnimate();
    };
})();

// The Backbone implementation:
(function() {

    var Box = Backbone.Model.extend({

        defaults: {
            top: 0,
            left: 0,
            color: 0,
            content: 0
        },

       ...