# Math calculation refactoring in JavaScript

Here's the full source to a plugin I'm developing, the relevant code I want to refactor is:

function measure($element,$bubble){
var scrollTop = $window.scrollTop(), viewportHeight =$window.height(),
readableTop = $element.position().top, readableHeight =$element.height(),
scrollHeight = viewportHeight / readableHeight * viewportHeight,
progress = (scrollTop - readableTop) / (readableHeight - viewportHeight),
total = getTotalMinutes($element), remaining = Math.ceil(total - (total * progress)), distanceProgress = (scrollTop - readableTop) / readableHeight, distanceLiteral = readableTop + distanceProgress * readableHeight + viewportHeight / 2 -$bubble.height() / 2,

return {
remaining: remaining,
progress: progress,
distance: distance
};
}


How might I make this calculation more understandable? I'm not terribly good at math, so I got there by trial and error, pretty much.

Now I'd like to refactor into something more readable or at least trim the repetitive nonsense, but I have no clue where to start.

Could you lend me a hand or give me any advice on how to tackle this?

Strictly in terms of code readability, you want to break down a function like this into it's core parts. Additionally, to reduce repetitive behavior you could make it more of a prototype and use some object oriented style to get to your result without a block of math.

Things to Consider

• Law of Demeter - Passing into your function only what you need and not entire objects.
• Breaking your function into segments, why not use methods to systematically get to your answer? Easily readable/maintainable.
• Reduce the amount of variable creation, you dont need to set each value to a new variable when one is already passed in from the function arguments. Law of Demeter helps here, too.
• Keeping your code expandable.

Here's an example of a function that follows the three above rules, a simple example that leaves you to put in your mathematics.

Example

var measure = function(elementHeight, elementPositionTop, bubbleHeight) {
var remaining = 0, progress = 0, distance = 0;

return {
init: function() {
measure.buildRemaining();
measure.buildProgress();
measure.buildDistance();
},
buildRemaining: function() {
remaining = elementHeight * bubbleHeight;
},
buildProgress: function() {
progress = remaining / 2.5;
},
buildDistance: function() {
distance = (elementPositionTop - progress) + remaining;
},
result: function() {
measure.init();
return {
remaining: remaining,
progress: progress,
distance: distance
}
}
}
}($element.height(),$element.position().top, \$bubble.height());


Accessing the Function

measure.result();


Returns

Object { remaining=5850, progress=2340, distance=3582 }