Reputation: 3
I am trying to calculate opacity inversely based on the size of an object. Basically the bigger it is, the more transparent it will be.
The object size is calculated like so:
var baseSize = 60;
var sVariance = 4;
var outputA = [];
function blah() {
for (i = 0; i < 5; i++) {
this.newSize = Math.ceil(baseSize - (Math.random() * sVariance));
outputA[i] = this.newSize;
}
document.writeln("Size = "+outputA);
}
blah();
...I would like to be able to calculate the opacity strength between the range of sizes. For example, if the 5 sizes generated were: 60,59,58,57,59 I would like the corresponding opacity values to be as such: .25,.5,.75,1,.5
I apologize if something like this has already been covered, but any help would be greatly appreciated.
Upvotes: 0
Views: 259
Reputation: 986
This is the function I would use. You can see the logic to convert the value in the function. Also here is an example.
Note that the $.map
function is a jQuery function which is very convenient to translate array items. If you're not using jQuery, you can replace it with a for loop.
function getOpacityArray (sizeArray, max, range) {
return $.map(sizeArray, function (n, i) {
return (max - n) / range;
});
}
So in your example you can get the opacity array after you calculate the size array, something like this:
var baseSize = 60,
sVariance = 4,
outputA = [],
opacityA = [];
function blah() {
for (i = 0; i < 5; i++) {
this.newSize = Math.ceil(baseSize - (Math.random() * sVariance));
outputA[i] = this.newSize;
}
document.writeln("Size = "+outputA);
opacityA = getOpacityArray(outputA, baseSize, sVariance);
}
blah();
Upvotes: 0
Reputation: 11508
function getSizes(baseSize, sVariance) {
var sizes = [];
for (i = 0; i < 5; i++) {
sizes[i] = Math.ceil(baseSize - (Math.random() * sVariance));
}
return sizes;
}
function calculateOpacityValues(baseSize, sVariance) {
var min = 0.25, max = 1,
step = 0.75 / sVariance, i,
opacityValues = {};
for (i = 0; i <= sVariance; i++) {
opacityValues[baseSize - i] = min + step * i;
}
return opacityValues;
}
function getOpacities(sizes, opacityValues) {
// create a map of opacities
// and your expected values
var opacities = [];
sizes.forEach(function(value, index) {
opacities[index] = opacityValues[value];
});
return opacities;
}
var baseSize = 60, sVariance = 3,
sizes = getSizes(baseSize, sVariance);
console.log(sizes);
// use the map to get the opacity
console.log(getOpacities(sizes, calculateOpacityValues(baseSize, sVariance)));
You can see it in action here. It uses the forEach construct which is not supported in older browsers, but if you need to, you'll be able to switch it to a normal for loop. I've also refactored your code a bit by moving all the generation logic in the getSizes
method and all the opacity calculation in the getOpacities
method.
On a sidenote, you should use console.log
for debugging (this logs in FireBug's console on FireFox, in the Chrome WebInspector window or in the IE development console). This is a lot better than document.write
(this is true for this case also, even if we're not talking about alert
here).
You didn't mention if you want the
I've added the logic you requested in the sample and I've updated the code.baseSize
and the variance
to be variable. In that case, you should add a method to generate the opacity value map based on your logic.
Upvotes: 0
Reputation: 1851
It sounds like you want to normalize the data so that the maximum is at 1 and the minimum is some fraction. It would help to define what you want that fraction to be (eg. always 0.25, 1 / # of values). How you normalize the data depends on that choice.
Consider doing things like subtracting everything by the lowest value in the list, or dividing everything by the greatest value, or both.
Upvotes: 1