AngularJS Directives - Widget Directive

HTML

<script src="http://code.angularjs.org/angular-1.0.0rc5.min.js"></script>
<div ng-app="animateApp" ng-controller="AnimateCtrl">


        <div class="boundingBox">

           <ball ng-repeat="shape in shapes"
                    x="shape.x"
                    y="shape.y"
                    color="shape.color" />

        </div>

</div>

CSS

.boundingBox {
    width: 600px;
    height: 600px;
    background-color: #333333;
    margin:20px;
}


.circle {
    display:block;
    position:absolute;
    height: 20px;
    width: 20px;
    background-color: #999;
    -moz-border-radius: 15px;
    -webkit-border-radius: 15px;
    border-radius: 15px;
}

.box {
    display:block;
    position:absolute;
    height: 20px;
    width: 20px;

}

#controls {
    position: absolute;
    top: 620px;
}

JavaScript

var module = angular
        .module('animateApp', [])
        .directive('ball', function ($defer) {
            return {
                restrict:'E',
                link:function (scope, element, attrs) {
                    element.addClass('circle');

                    scope.$watch(attrs.x, function (x) {
                        element.css('left', x + 'px');
                    });
                    scope.$watch(attrs.y, function (y) {
                        element.css('top', y + 'px');
                    });
                    scope.$watch(attrs.color, function (color) {
                        element.css('backgroundColor', color);
                    });
                }
            };
        });

function animator(shapes, $defer) {
    (function tick() {
        var i;
        var now = new Date().getTime();
        var maxX = 600;
        var maxY = 600;
        var now = new Date().getTime();

        for (i = 0; i < shapes.length; i++) {
            var shape = shapes[i];
            var elapsed = (shape.timestamp || now) - now;

            shape.timestamp = now;
            shape.x += elapsed * shape.velX / 1000;
            shape.y += elapsed * shape.velY / 1000;

            if (shape.x > maxX) {
                shape.x = 2 * maxX - shape.x;
                shape.velX *= -1;
            }
            if (shape.x < 30) {
                shape.x = 30;
                shape.velX *= -1;
            }

            if (shape.y > maxY) {
                shape.y = 2 * maxY - shape.y;
                shape.velY *= -1;
            }
            if (shape.y < 20) {
                shape.y = 20;
                shape.velY *= -1;
            }
        }

        $defer(tick, 30);
    })();
}

function AnimateCtrl($scope, $defer) {

    function buildShape() {
        var maxVelocity = 200;
        return {
            color:'#' + (Math.random() * 0xFFFFFF << 0).toString(16),
            x:Math.min(380, Math.max(20, (Math.random() * 380))),
        ...