jQuery.fn.animate as an animation loop

HTML

<div id="container">
    <div id="ball"></div>
</div>

CSS

#container {
    background: #000;
    width: 200px;
    height: 200px;
    position: relative;
    overflow: hidden;
}

#ball {
    background: #FFF;
    width: 20px;
    height: 20px;
    position: absolute;
    top: 90px;
    left: 90px;
}

JavaScript

$.fx.step.ball = function(fx) {
    var fxParams = fx.end,
        speed = fxParams.speed,
        angle = fxParams.angle,
        position = fxParams.position,
        tick = jQuery.now(),
        dt = tick - fxParams.lastTick
        dy = Math.cos(angle) * dt * speed,
        dx = Math.sin(angle) * dt * speed,
        left = position.left + dx,
        top = position.top - dy,
        bounce = false;
    
    // Bounce the ball
    if ( left <= 0 ) {
        left = 1;
        angle = Math.atan2(-dx, dy);
    } else if ( top <= 0 ) {
        top = 1;
        angle = Math.atan2(dx, -dy);
    } else if ( left >= 180 ) {
        left = 179;
        angle = Math.atan2(-dx, dy);
    } else if ( top >= 180 ) {
        top = 179;
        angle = Math.atan2(dx, -dy);
    }
    
    // Update ball position
    fx.elem.style.left = left+'px';
    fx.elem.style.top = top+'px';
    
    // Update fxParams
    fx.end.position = {
        left: left,
        top: top
    }
    fx.end.lastTick = tick;
    fx.end.angle = angle%(Math.PI*2);
};

$(function() {
    var $ball = $('#ball');
    $ball.animate({ball: {
        position: $ball.position(),
        angle: Math.floor(Math.random()*4)*Math.PI/2+Math.PI/6,
        speed: 0.1,
        lastTick: jQuery.now()
    }}, Infinity);
});