Have elements follow the mouse in RaphaelJS canvas using jQuery

http://terryyoung.blogspot.com/2011/08/elements-following-mouse-in-raphaeljs.html

by Tricia Seow

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<p>Just move around the RaphaelJS canvas area below, or switch modes using the buttons</p>

<button id="RJS_CANVAS_MOUSEMOVE_FOLLOW">Follow Mouse</button>

<button id="RJS_CANVAS_MOUSEMOVE_RANDOM">Random Movement</button>

<br>

<div id="RJS_CANVAS_MOUSEMOVE_1"></div>

CSS

/***********************************************************************
Common styles
***********************************************************************/

html, body
{
font-family:            Tahoma;
font-size:              9pt;
}

br.clear
{
clear:                  both;
}

/***********************************************************************
Common styles
***********************************************************************/

#RJS_CANVAS_MOUSEMOVE_1 {

-moz-border-radius:       10px;
-webkit-border-radius:    10px;
border-radiu:             10px;
border:                   solid 3px #2b333c;
background-color:         #dcdfe4;
width:                    640px;
height:                   360px;
}

JavaScript

/**
 * @author      Terry Young <terryyounghk [at] gmail.com>
 * @blog        http://terryyoung.blogspot.com/2011/08/elements-following-mouse-in-raphaeljs.html
 * @license     WTFPL  ( http://en.wikipedia.org/wiki/WTFPL )
 *              No warranty, no support
 *
 */
$(document).ready(function () {
    var paper       = Raphael('RJS_CANVAS_MOUSEMOVE_1', 640, 360),
        set         = paper.set(),
        circles     = 3,
        smallest    = 5,
        gap         = 5,
        strokeWidth = 2,
        margin      = 10,
        duration    = 600,
        delay       = 400,
        timer       = null,
        follow      = true;

    // cache these
    var $canvas     = $(paper.canvas);
    var offset      = $canvas.offset();

    // create circles
    for (var    i = 0, j = circles, k = 1, m = smallest;
                i < j;
                i++, k = k - 0.9 / j, m = m + gap)
    {
        set.push
        (
            paper.circle(-500, -500, m)
                .attr({
                    'stroke-width':     strokeWidth,
                    stroke:             '#492f2c',
                    fill:               'none',
                    'fill-opacity':     0,
                    opacity:            k
                })
        );
    }

    // prepare mousemove handler
    var onMouseMove = function (event) {
        var x = event.pageX - offset.left,
            y = event.pageY - offset.top;
        var pos = {x: x, y: y, cx: x, cy: y}; // lazy routine: for both rects and circles

        for (var i=0, j=set.items.length, k=duration; i<j; i++, k=k+delay)
        {
            set.items[i].stop().animate(pos, k, 'backOut');
        }
    };

    // prepare random positioning handler
    var moveRandomly = function ()
    {
        var m = smallest + ((gap + strokeWidth) * circles) + margin;
        var x = Math.max(margin, Math.floor(Math.random() * $canvas.width() - margin)),
            y = Math.max(margin, Math.floor(Math.random() * $canvas.height() -...