HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Providing one-time calculations to frequently used methods

Submitted by: @import:stackexchange-codereview··
0
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):

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:

  • 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.