return (Math.sin(this.attr('count') / 10) * 10) + 'px'
return (Math.cos(this.attr('count') / 10) * 10) + 'px'
return 'rgb(0,0,' + (this.attr('count')) % 255 + ')'
return this.attr('count') % 100
var newCount = this.attr('count') + 1;
this.attr('count', newCount);
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++) {
$('#grid').append(can.view('ejs-template', {
$('#grid').append(can.view('mustache-template', {
canAnimate = function() {
can.Observe.startBatch();
for (var i = 0; i < N; i++) {
window.timeout = _.defer(canAnimate);
window.runCan = function(tmpl) {
var Box = Backbone.Model.extend({
var count = this.count += 1;
top: Math.sin(count / 10) * 10,
left: Math.cos(count / 10) * 10,
var BoxView = Backbone.View.extend({
template: _.template($('#underscore-template').html()),
this.model.bind('change', this.render, this);
this.$el.html(this.template(this.model.attributes));
var backboneInit = function() {
boxes = _.map(_.range(N), function(i) {
$('#grid').append(view.render().el);
var backboneAnimate = function() {
for (var i = 0, l = boxes.length; i < l; i++) {
window.timeout = _.defer(backboneAnimate);
window.runBackbone = function() {
var Box = Ember.Object.extend({
var count = this.get('count') + 1;
this.set('count', count);
this.set('top', Math.sin(count / 10) * 10);
this.set('left', Math.cos(count / 10) * 10);
this.set('color', count % 255);
this.set('content', count % 100);
return 'top: ' + this.get('top') + 'px; left: ' + this.get('left') + 'px; background: rgb(0,0,' + this.get('color') + ');';
}.property('top', 'left', 'color')
var BoxView = Ember.View.extend({
classNames: ['box-view'],
var emberInit = function() {
boxes = _.map(_.range(N), function(i) {
var view = BoxView.create({
var emberAnimate = function() {
for (var i = 0, l = boxes.length; i < l; i++) {
window.timeout = _.defer(emberAnimate);
window.runEmber = function() {
this.count = ko.observable(0);
return (Math.sin(this.count() / 10) * 10) + 'px'
return (Math.cos(this.count() / 10) * 10) + 'px'
this.color = function() {
return 'rgb(0,0,' + (this.count()) % 255 + ')'
this.content = function() {
return this.count() % 100
this.count(this.count() + 1);
var ViewModel = function(num) {
this.boxes = ko.observableArray();
for (var i = 0; i < num; i++) {
this.boxes.push(new Box())
var knockoutAnimate = function() {
for (var i = 0, l = vm.boxes().length; i < l; i++) {
window.timeout = _.defer(knockoutAnimate);
window.runKnockout = function() {
$('#grid').html($('#knockout-template').html());
ko.applyBindings(vm, $('#grid')[0]);
YUI().use('model', 'view', 'handlebars', function(Y) {
Y.Box = Y.Base.create('box', Y.Model, [], {
initializer: function() {
var count = this.count += 1;
top: Math.sin(count / 10) * 10,
left: Math.cos(count / 10) * 10,
Y.BoxView = Y.Base.create('boxView', Y.View, [], {
template: Y.Handlebars.compile(Y.one('#yui-handlebars-template').getContent()),
initializer: function() {
this.get('model').after('change', this.render, this);
return Y.Node.create('<div class="box-view" />');
var content = this.template(this.get('model').toJSON());
this.get('container').setContent(content);
var yuiInit = function() {
boxes = _.map(_.range(N), function(i) {
var view = new Y.BoxView({
Y.one('#grid').append(view.render().get('container'));
var yuiAnimate = function() {
for (var i = 0, l = boxes.length; i < l; i++) {
window.timeout = _.defer(yuiAnimate);
window.runYUI = function() {
window.reset = function() {