patternjavascriptMinor
Animating based on screen width
Viewed 0 times
widthbasedscreenanimating
Problem
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
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'}
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'}
Solution
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:
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/
- 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() 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;
}
}
});Code Snippets
'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;
}
}
});Context
StackExchange Code Review Q#39276, answer score: 3
Revisions (0)
No revisions yet.