To generalise an answer to this, I'll work through how I made the formula to calculate a bar's length. The length will be a float from 0 - 1.
To calculate the bar's length, you need 3 values
The bar's maximum value: barMaximum
The bar's minimum value: barMinimum
The player's current health
To begin with, lets imagine the second from top bar (shown in blue). It has a barMinimum
of 20
, and a range
of 30
(To get the range, subtract the minimum from the maximum).

What the formula will do is move and scale the blue bar's range to fit in our desired range (in this case 0 - 1).
Picture the (poorly drawn) number line below:

We see the blue bar ranges from 20 to 50, and our desired range is from 0 to 1. This blue bar represents the range of values that the player's health could be. The first thing we want to do is move it to our desired range.
We know the distance from the start of the blue bar the start of our desired range, as it is just the blue bar's minimum value (in this case its 20). So to move the blue bar to the start of our desired range, we need to move it left 20 spaces. And to move it left 20 spaces, we need to subtract 20 from it.

Don't forget that this bar simply represents the range of values that health
could be, which is why I have named the variable movedHealth
. To put this action into code, we could say:
movedHealth = health - 20;
And to generalise this (so it can be used for any bar) we could say:
movedHealth = health - barMinimum;
Okay, so now we have moved the blue bar into the correct place. Now we need to scale it so it fits within our desired range. As we are scaling, we can assume that we will need to use multiplying or dividing for our next move. But how can we find out what we need to multiply/divide by?
What we can do is look at a few examples of where we know our blue bar (which now represents movedHealth
) will move.
We know that if movedHealth
is half way through our blue bar (in this case 15), we want it to be half way through our desired range (which is 0.5). Another example: if movedHealth
is at the moved bar's maximum (30 in this case), we want it to be at our desired range's maximum (which is 1).
Lets use the latter example to help us calculate our scale. We can use some simple algebra to figure out what to do here. We know that our moved bar's maximum value is 30, and our desired range's is 1. So the moved bar's maximum is 30 times our desired range's maximum
moved bar's maximum = desired range's maximum * 30
We can then generalise this for any value:
moved bar = desired range * 30
So this means that if we wanted to scale up a value from our desired range (0 - 1) to our moved bar, we would multiply it by 30. Therefore, if we wanted to scale down a value from our moved bar to our desired range, we would divide it by 30:
desired range = moved bar / 30
This can be visualised on our number line:

To re-iterate, to scale a value from our moved bar (0 - 30 here) to our desired range (0 - 1), we divide it by 30. This means that we can replace the "moved bar" part of our equation with movedHealth
, since the bar is just representing the values movedHealth
could be:
desired range = movedHealth / 30
And now that we have scaled down our movedHealth
to our desired range, we can replace "desired range" with scaledHealth
, since we have scaled down its possible values to the range of 0 to 1.
scaledHealth = movedHealth / 30;
Now we have this equation for this specific example, lets generalise it to fit any bar. The only part we need to change is the 30. This 30 came from the bar's maximum value after being moved. If we look at the diagram below we can not only see the progression of the blue bar, but also the links between certain aspects.

For example the fact that moved bar's maximum value, is equal to its range. This is because:
original bar's maximum = 50
original bar's minimum = 30
original bar's range = original bar's maximum - original bar's minimum
= 50 - 20
= 30
And when we look at how we calculated the moved bar's maximum value, we subtracted 20 (the original bar's minimum) from the original bar's maximum value. When visualise this in an equation we see:
moved bar's maximum = original bar's maximum - original bar's minimum
Which is identical to how we calculate the original bar's range. So because of this, we can now replace the "30" in our scaledHealth
equation:
So
scaledHealth = movedHealth / 30;
becomes
scaledHealth = movedHealth / barRange;
And since scaledHealth
is actually the length of the bar (from 0 - 1) we should probably replace it with a more fitting name, such as barLength
. So:
barLength = movedHealth / barRange;
Now lets put all our code in one place:
movedHealth = health - barMinimum;
barRange = barMaximum - barMinimum;
scaledHealth = movedHealth / barRange;
To put this into one equation, we can first substitute any reference of movedHealth
with (health - barMinimum)
, so we get:
barRange = barMaximum - barMinimum;
scaledHealth = (health - barMinimum) / barRange;
And now we can substitute any reference of barRange
for (barMaximum - barMinimum)
, so we get:
barLength = (health - barMinimum) / (barMaximum - barMinimum);
And don't forget that this doesn't account for values of health
which are outside of the bar's range. So to counteract this, we could do something like this:
Math.max(0, Math.min(1, barLength));
So now we can write a function, using this new found equation:
var health = 35; // can be ANY value, just put 35 as an example
var barMinimum = 20; // replace with whatever the current bar's minimum is
var barMaximum = 50; // again, replace with the bar's maximum
function calculateBarLength(health, barMinimum, barMaximum) {
return Math.max(0, Math.min(1, (health - barMinimum) / (barMaximum - barMinimum)));
}
var barLength = calculateBarLength(health, barMinimum, barMaximum);
console.log(barLength);
// outputs 0.5
Vuala!
This is very similar to scaling a number between to ranges. For example this post.