patternjavascriptMinor
Providing one-time calculations to frequently used methods
Viewed 0 times
usedprovidingtimecalculationsfrequentlyonemethods
Problem
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):
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 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);
}Solution
Ok, so after some (more!) search on the net, I will propose one thing that I was already pondering about (having a little experience mostly with OOP languages Java and C#).
creating a class/datastructure to hold the values
I was inspired by these sources:
still not sure if this is a "better" approach in JavaScript, but at least for my rather inexperienced eyes it looks more structured
the refactored version of my pulsating object is here
the slightly changed javascript (find the class ElementWrapper at the end):
creating a class/datastructure to hold the values
I was inspired by these sources:
- answer to this question
- answer nr 2 to this question
- and this webmonkey explanation
still not sure if this is a "better" approach in JavaScript, but at least for my rather inexperienced eyes it looks more structured
the refactored version of my pulsating object is here
the slightly changed javascript (find the class ElementWrapper at the end):
$(document).ready(function () {
var element = $('#circle');
var growInPercent = 100;
var elementWrapper = new ElementWrapper(element, growInPercent);
var durationGetBigger = 500;
var durationGetSmaller = 100;
var frequency = 3;
var pause = 3000;
pulsate(elementWrapper, durationGetBigger, durationGetSmaller,
frequency, pause);
});
function pulsate(elementWrapper, durationBigger, durationSmaller, frequency, pause) {
for (var i = 0; i 0) { // odd
// make sure increased size is odd too
return Math.floor(increase / 2) * 2 + 1;
}
else {
return Math.floor(increase / 2) * 2;
}
}
}Code Snippets
$(document).ready(function () {
var element = $('#circle');
var growInPercent = 100;
var elementWrapper = new ElementWrapper(element, growInPercent);
var durationGetBigger = 500;
var durationGetSmaller = 100;
var frequency = 3;
var pause = 3000;
pulsate(elementWrapper, durationGetBigger, durationGetSmaller,
frequency, pause);
});
function pulsate(elementWrapper, durationBigger, durationSmaller, frequency, pause) {
for (var i = 0; i < frequency; i++) {
getBigger(elementWrapper, durationBigger);
getSmaller(elementWrapper, durationSmaller);
}
setTimeout(function () {
pulsate(elementWrapper, durationBigger, durationSmaller, frequency, pause)
}, pause);
}
function getBigger(elementWrapper, duration) {
elementWrapper.element.animate({
width: elementWrapper.increasedWidth,
height: elementWrapper.increasedHeight,
top: elementWrapper.newTop,
left: elementWrapper.newLeft,
opacity: 1
}, duration, 'linear');
}
function getSmaller(elementWrapper, duration) {
elementWrapper.element.animate({
width: elementWrapper.originalWidth,
height: elementWrapper.originalHeight,
top: 0,
left: 0,
opacity: 0.5
}, duration, 'linear');
}
function ElementWrapper(element, percent) {
this.element = element;
this.originalHeight = element.height();
this.originalWidth = element.width();
this.increasedHeight = getIncreasedValue(this.originalHeight, percent);
this.increasedWidth = getIncreasedValue(this.originalWidth, percent);
this.newLeft = -Math.round((this.increasedWidth - this.originalWidth) / 2);
this.newTop = -Math.round((this.increasedHeight - this.originalHeight) / 2);
function getIncreasedValue(originalValue, percent) {
var increase = Math.round(originalValue * (1 + percent / 100));
if (originalValue % 2 > 0) { // odd
// make sure increased size is odd too
return Math.floor(increase / 2) * 2 + 1;
}
else {
return Math.floor(increase / 2) * 2;
}
}
}Context
StackExchange Code Review Q#23820, answer score: 3
Revisions (0)
No revisions yet.