I'm new to JS/jQuery and wrote some JavaScript/jQuery lines to create a pulsating object.I get the pulse effect by increasing/resizing the object and then bringing it back to its original state periodically.  I was uncomfortable with calculating the necessary values every time they are needed, so I used the first thing that came to my mind - global variables and only modify their values when the page is fully loaded.  But I also don't like that approach.What is best practice in JavaScript/jQuery for this kind of problem, and how can I refactor my code accordingly?Here is the code (JavaScript only, please see my link for HTML&CSS):var elementOrigHeight;var elementOrigWidth;var elementIncreasedHeight;var elementIncreasedWidth;var elementNewTop;var elementNewLeft;$(document).ready(function () {    var element = $('#circle');    var growInPercent = 100;    setGlobalVariables(element, growInPercent);        var durationGetBigger = 500;    var durationGetSmaller = 100;    var frequency = 3;    var pause = 3000;    pulsate(element, durationGetBigger, durationGetSmaller,    frequency, pause);});function pulsate(element, durationBigger, durationSmaller, frequency, pause) {    for (var i = 0; i < frequency; i++) {        getBigger(element, durationBigger);        getSmaller(element, durationSmaller);    }    setTimeout(function () {        pulsate(element, durationBigger, durationSmaller, frequency, pause)    }, pause);}function getBigger(element, duration) {    element.animate({        width: elementIncreasedWidth,        height: elementIncreasedHeight,        top: elementNewTop,        left: elementNewLeft,        opacity: 1    }, duration, 'linear');}function getSmaller(element, duration) {    element.animate({        width: elementOrigWidth,        height: elementOrigHeight,        top: 0,        left: 0,        opacity: 0.5    }, duration, 'linear');}function setGlobalVariables(element, percent) {    elementOrigHeight = element.height();    elementIncreasedHeight = Math.round(elementOrigHeight*(1+percent/100));    if (elementOrigHeight % 2 > 0) { // odd        // make sure increased size is odd too        elementIncreasedHeight = Math.floor(elementIncreasedHeight/2)*2+1;    }    else {        elementIncreasedHeight = Math.floor(elementIncreasedHeight/2)*2    }    elementOrigWidth = element.width();    elementIncreasedWidth = Math.round(elementOrigWidth*(1+percent/100));    if (elementOrigWidth % 2 > 0) { // odd        elementIncreasedWidth = Math.floor(elementIncreasedWidth/2)*2+1;    }    else {        elementIncreasedWidth = Math.floor(elementIncreasedWidth/2)*2;    }    elementNewLeft = -Math.round((elementIncreasedWidth - elementOrigWidth)/2);    elementNewTop = -Math.round((elementIncreasedHeight - elementOrigHeight)/2);}
Providing one-time calculations to frequently used methods
javascript;jquery;beginner
To keep the global scope clean and to make this more reusable, create a jQuery plugin. This site has some good starting templates for organizing your code into a plugin:http://shichuan.github.com/javascript-patterns/Here is an example of your code as a plugin:http://jsfiddle.net/phil_mcc/VCUXY//*** The pulsating plugin will make an element on the page pulsate.* Sample usage: * $(#circle).pulsate({        growInPercent: 100,        durationGetBigger: 500,        durationGetSmaller: 100,        frequency: 3,        pause: 3000    }); */(function($) { //This function wrapper will keep all variables out of the global scope    var PulsatingElement = {            init: function( options, elem ) {                // Mix in the passed-in options with the default options                this.options = $.extend( {}, this.options, options );                //save references to element                this.elem  = elem;                this.$elem = $(elem);                this.setupHeightWidth();                this.animate();                //return copy for chaining                return this;            },            //set default options            options: {                growInPercent: 20,                durationGetBigger: 500,                durationGetSmaller: 100,                frequency: 3,                pause: 3000            },                      setupHeightWidth: function () {                this.originalHeight = this.$elem.height();                              this.increasedHeight = Math.round(this.originalHeight * (1 + this.options.growInPercent / 100));                if (this.originalHeight % 2 > 0) { // odd                    // make sure increased size is odd too                    this.increasedHeight = Math.floor(this.increasedHeight / 2) * 2 + 1;                } else {                    this.increasedHeight = Math.floor(this.increasedHeight / 2) * 2                }                this.originalWidth = this.$elem.width();                this.increasedWidth = Math.round(this.originalWidth * (1 + this.options.growInPercent / 100));                if (this.originalWidth % 2 > 0) { // odd                    this.increasedWidth = Math.floor(this.increasedWidth / 2) * 2 + 1;                } else {                    this.increasedWidth = Math.floor(this.increasedWidth / 2) * 2;                }                this.newLeft = -Math.round((this.increasedWidth - this.originalWidth) / 2);                this.newTop = -Math.round((this.increasedHeight - this.originalHeight) / 2);            },            animate: function () {                for (var i = 0; i < this.options.frequency; i++) {                    this.getBigger(this.options.durationBigger);                    this.getSmaller(this.options.durationSmaller);                }                       var self = this; //need a copy of object that can be referenced in the timeout                setTimeout(function () {                    self.animate()                }, this.options.pause);            },            getBigger: function (duration) {                this.$elem.animate({                    width: this.increasedHeight,                    height: this.increasedWidth,                    top:  this.newTop,                    left:  this.newLeft,                    opacity: 1                }, duration, 'linear');            },            getSmaller: function (duration) {                 this.$elem.animate({                    width: this.originalWidth,                    height: this.originalHeight,                    top: 0,                    left: 0,                    opacity: 0.5                }, duration, 'linear');            }    };    // Object.create support test, and fallback for browsers without it    if ( typeof Object.create !== 'function' ) {        Object.create = function (o) {            function F() {}            F.prototype = o;            return new F();        };    }    // Create a plugin based on a defined object    $.plugin = function( name, object ) {        $.fn[name] = function( options ) {            return this.each(function() {                if ( ! $.data( this, name ) ) {                    $.data( this, name, Object.create(object).init(                            options, this ) );                }            });        };    };     //create a plugin called pulsate that uses the PulsatingElement Object    $.plugin('pulsate', PulsatingElement);})( jQuery );$(function () {    $(#circle).pulsate({        growInPercent: 100,        durationGetBigger: 500,        durationGetSmaller: 100,        frequency: 3,        pause: 3000    });      $(#circle2).pulsate({            growInPercent: 100,            durationGetBigger: 100,            durationGetSmaller: 500,            frequency: 3,            pause: 4000        });});