3
\$\begingroup\$

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 > 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 < 840 && width > 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'))) &&
 width < 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);
 }
});
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jan 15, 2014 at 10:29
\$\endgroup\$
1
  • \$\begingroup\$ Probably not because those constants may become incorrect (besides top and left which will be 0) when the window resizes \$\endgroup\$ Commented Jan 15, 2014 at 12:53

1 Answer 1

3
\$\begingroup\$

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() > 840;
 }
 },
 {
 delay: 1500,
 down: 490,
 left: -199,
 up: 165,
 right: 179,
 vertical_dur: 2000,
 horizontal_dur: 2000,
 conditions: function() {
 return $(window).width() < 840 && $(window).width() > 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;
 }
 }
});
answered Jan 15, 2014 at 17:19
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.