Animating based on screen width Depending on the width of the screen the JavaScript animates a node and then loops another animation.

I'm trying to understand DRY but my JavaScript skills aren't quite up to scratch to get this code as optimised as possible. I'm also wanting to implement $(window).resize(function() { }); to detect this change without a refresh. Is using constants the best way to optimise this code? If so, how would this be achieved?

jsFiddle

'use strict';

/*jslint browser: true*/
/*global $, jQuery*/

/*
--------------------------------------------------------
VARIABLES
--------------------------------------------------------
*/

var width       = $(window).width(),        // window width
    down_dur,
    left_dur,
    up_dur,
    right_dur;

/*
--------------------------------------------------------
FUNCTION CODE TO BE EXECUTED
--------------------------------------------------------
*/

function animate_node(down, down_dur, left, left_dur, up, up_dur, right, right_dur) {

    down        = down  + 'px';
    left        = left  + 'px';
    up          = up    + 'px';
    right       = right + 'px';

    $('.node')
        .animate({top: down},
            { duration: down_dur, easing : 'linear', queue: true })
        .animate({marginLeft: left},
            { duration: left_dur, easing : 'linear', queue: true })
        .animate({top: up},
            { duration: up_dur, easing : 'linear', queue: true })
        .animate({marginLeft: right},
            { duration: right_dur, easing : 'linear', queue: true });
}

/*
--------------------------------------------------------
CALL THE FUNCTIONS
--------------------------------------------------------
*/

// fire the following when the dom is ready
$(function () {

    if (width &gt; 840) {
        $('.node').each(function(i) {
            $(this).delay(1500 * (i + 1))
                .animate({top: '157px'},
                    { duration: 1000, easing : 'linear', queue: true })
                .animate({marginLeft: '264px'},
                    { duration: 1000, easing : 'linear', queue: true });
        });
        animate_node(425, 2000, -284, 2000, 157, 2000, 264, 2000);
        setInterval(function() {
            animate_node(425, 2000, -284, 2000, 157, 2000, 264, 2000);
        }, 2000);
    } else if (width &lt; 840 &amp;&amp; width &gt; 600) {
        $('.node').each(function(i) {
            $(this).delay(1500 * (i + 1))
                .animate({top: '165px'},
                    { duration: 1000, easing : 'linear', queue: true })
                .animate({marginLeft: '179px'},
                    { duration: 1000, easing : 'linear', queue: true });
        });
        animate_node(490, 2000, -199, 2000, 165, 2000, 179, 2000);
        setInterval(function() {
            animate_node(490, 2000, -199, 2000, 165, 2000, 179, 2000);
        }, 2000);
    } else if ((!(document.documentElement.hasOwnProperty('ontouchstart'))) &amp;&amp;
            width &lt; 600) {
        $('.node').each(function(i) {
            $(this).delay(1833.333 * (i + 1));
        });
        animate_node(1095, 5000, 102, 500, 165, 5000, -9, 500);
        setInterval(function() {
            animate_node(1095, 5000, 102, 500, 165, 5000, -9, 500);
        }, 2000);
    }

});
I would move all positions and other configuration to a simpleObject which contains a condition which is checked to determine if the configuration should be used for the current screen dimensions:


Remove unneeded variables
Added functions to remove duplication
Moved positions to animationConfig so logic and configuration is separated


I made a assumption in the code which is that the path is always a square, so up, down, left
and right duration are replaced with a horizontal and vertical duration

jsfiddle: http://jsfiddle.net/EJF9q/1/

'use strict';

function animate_node(down, down_dur, left, left_dur, up, up_dur, right, right_dur) {

    function animate_cfg(duration) {
        return { duration: duration, easing : 'linear', queue: true };
    }

    down    += 'px';
    left    += 'px';
    up      += 'px';
    right   += 'px';

    $('.node')
        .animate({top: down},           animate_cfg(down_dur))
        .animate({marginLeft: left},    animate_cfg(left_dur))
        .animate({top: up},             animate_cfg(up_dur))
        .animate({marginLeft: right},   animate_cfg(right_dur));
}

function animate_config(config) {
    animate_node(
        config.down,
        config.vertical_dur,
        config.left,
        config.horizontal_dur,
        config.up,
        config.vertical_dur,
        config.right,
        config.horizontal_dur);
}

// OnReady
$(function () {

    var animationConfigs = [
        {
            startTop: 157,
            delay: 1500,
            down: 425,
            left: -284,
            up: 157,
            right: 264,
            vertical_dur: 2000,
            horizontal_dur: 2000,
            conditions: function() {
                return $(window).width() &gt; 840;
            }
        },
        {
            delay: 1500,
            down: 490,
            left: -199,
            up: 165,
            right: 179,
            vertical_dur: 2000,
            horizontal_dur: 2000,
            conditions: function() {
                return $(window).width() &lt; 840 &amp;&amp; $(window).width() &gt; 600;
            }
        },
        // Etc...
    ];

    for (var i in animationConfigs) {
        var animationCfg = animationConfigs[i];
        if (animationCfg.conditions()) {
            $('.node').each(function(i) {
                $(this).delay(1500 * (i + 1))
                    .animate({ top: animationCfg.up + 'px' },
                        { duration: 1000, easing : 'linear', queue: true })
                    .animate({marginLeft: animationCfg.right + 'px'},
                        { duration: 1000, easing : 'linear', queue: true });
            });
            animate_config(animationCfg);
            setInterval(function() {
                animate_config(animationCfg);
            }, 2000);
            break;
        }
    }
});