The RGB_Calc
Class was born of the need for speed, yet also the need to accommodate flexible input & output formats.
In testing, I found using Array
s to pass data in & out provided the fastest execution times by far.
The predecessor of this class passed back only (custom) “color-Object
s,”
and (if memory serves) it “processed” all input before actually converting any colors,
and when I replaced that previous class with this new RGB_Calc
Class in my “MasterColorPicker” project
and configured this new Class to pass back simple Array
s instead
(using the same conversion functions internally with about the same extraneous overhead),
maximum palette draw-time went from about 8.5 seconds to about 1.5 seconds (timed by eye/ear using the clicks on my analog wall-clock).
I was shocked (but happy☺) at the dramatic increase; I expected maybe 25%-100% faster times, but 700% faster is even better!
The RGB_Calc
Class focuses on converting the
sRGB (standard Red-Green-Blue) color-space
to & from various other color-models.
Note a color-space has defined limits to values — the sRGB color space limits each value to integers ranging from 0—255.
In reality, colors could be more intense (have more Chroma), or more densely packed throughout the range of intensity,
but 255 is the limit that computers use.
A color-model does not define the values’ limits; however by definition of the individual models,
there are generally limits to the intensity (Chroma) of the colors.
So we generally define sRGB color-space-values like this: (64, 128, 255),
but any color-model (including an RGB model) generally uses percent values like this (25%, 50%, 100%);
or some use hue-angles which correlate to a percentage of distance around the circumference of a circle (90deg, 50%, 100%).
By converting from color models using percents to a color-space, we are saying that the color-model we use has the same
limits of color-intensity (chroma) as the color-space.
Chroma, or color-intensity, should not be confused with brightness or luminance, though.
The mathematical color-space is then applied to the monitor, and every monitor has its own gamut;
that is the actual range of colors that the monitor will show, related to its contrast-ratio,
where generally speaking, the higher the contrast, the darker the black is, and the more bright and pure and less washed-out the colors appear.
This all gets more confusing as we try to compare computer monitors with real-life and
different wavelengths of light bouncing off different objects that reflect that wave in different ways,
and how the eye perceives color and vision in general,
and that is where this discussion leads…but not here.
To use the package, you must first create a couple of namespaces for it.
Typically, these namespaces are JavaScript™ constants,
and are used by many of SoftMoon-WebWare’s various different library packages,
so they can’t all create the constant.
The SoftMoon
namespace is our root, and it holds simple “universal” data
that different libraries may need.
The SoftMoon.WebWare
namespace holds executable code.
Also, you need to create an Array
for named-color-palette files to load themselves into
if you are hard-loading them with <script> tags
(▼more on that in the Palettes section below).
If you are only loading palettes from a server
(using “ajax” via SoftMoon.WebWare.loadPalettes()
),
or not at all, you don’t need the
SoftMoon.loaded_palettes
property.
If you are not loading palettes from a server (using “ajax”), you do not need the HTTP.js file.
Don’t confuse the fact that you can load the palettes using <script> tags from a server
— but that is not using “ajax.”
The following HTML code will create the proper namespace Objects
and then load the code files and the CSS palette file:
<script type='text/javascript'>
const SoftMoon={};
Object.defineProperties(SoftMoon, {
WebWare: {value: {}, enumerable: true},
loaded_palettes: {value: [], enumerable: true}
});
</script>
<script type='text/javascript' src='JS_toolbucket/+++JS/+++.js' defer></script>
<script type='text/javascript' src='JS_toolbucket/+++JS/+++Math.js' defer></script>
<script type='text/javascript' src='JS_toolbucket/SoftMoon-WebWare/HTTP.js' defer></script>
<script type='text/javascript' src='JS_toolbucket/SoftMoon-WebWare/RGB_Calc.js' defer></script>
<script type='text/javascript' src='color_palettes/desktop_palettes/CSS4.palette.js'
defer onload='SoftMoon.WebWare.addPalette(SoftMoon.loaded_palettes.pop())'></script>
Once loaded, the RGB_Calc
Class is already set up to give you access to all of the individual conversion functions.
These ▼“quick” functions are tuned for maximum speed,
and are members of RGB_Calc
so they depend being called as such to access the
configuration options: RGB_Calc.config
.
They all require passing in an Array
of “proper” values (see each function); that is,
converting from sRGB (→to→ any color-model) requires passing in values from 0—255,
converting from other color-models typically (but not by all)
requires passing in factor-values from 0.0—1.0,
and “improper” input values yield undefined results;
they are not checked for “improper” values, as this slows the calculator.
const RGB_Calc=SoftMoon.WebWare.RGB_Calc;
const c1=RGB_Calc.from.hsl([0.3, 0.5, 0.84]);
// By default, the returned value is a custom RGBA_Color object;
// its .toString('css') method yields: "RGB(202, 235, 194)"
console.log(c1);
const c2=RGB_Calc.to.hsl([202, 235, 194]);
// By default, the returned value is a custom HSLA_Color object;
// its .toString('wrap deg percent') method yields: "HSL(108.29deg, 50.61728%, 84.11765%)"
console.log(c2);
// Note the slight difference in conversion values;
// this is because RGBA_Color objects’ .toString() method has rounded the resulting RGB values to integers.
// To find the precision RGB values
// **when the calculator’s configuration options do NOT round the RGB result**:
console.log(c1.rgb) // ←yields an Array
// We can also get conversion values returned in a simple Array or YOUR custom Class object.
// To temporarily change a configuration value:
RGB_Calc.config.stack({RGBA_Factory: {value:Array}}); // with .stack(), the passed value must be a properties descriptor
const c3=RGB_Calc.from.hsl([0.3, 0.5, 0.84]); // ←c3 is a native JavaScript Array, not an RGBA_Color object
// (note we can also directly change config values without having first .stack()ed if we want them to be more permanent)
RGB_Calc.config.RGBA_Factory=MyCustomColorClass; // this should point to YOUR constructor function
const c4=RGB_Calc.from.hsl([0.3, 0.5, 0.84]); // ←c4 is an instance of MyCustomColorClass
RGB_Calc.config.cull(); // now the RGBA_Factory is whatever it was before we .stack()ed
For all calculators, both “quick” and “auditing” types,
values returned (in whatever Object) are always in the “byte” range of 0-255 for
the RGB color-space (they may be numeric-floats if .config.roundRGB==false
,
so we can’t exactly call them “bytes” or call this the sRGB color-space);
and factors from 0.0–1.0 for all other color-models.
Besides being a simple stand-alone static-functional class,
RGB_Calc
is also a Class constructor to create new “calculators” with their own set of options.
But the calculators you can construct can offer greater input flexibility, specifically, but not limited to,
the ability to “audit” (interpret) a String
similar to a CSS color-definition;
except it can interpret any color-model that RGB_Calc
is set-up to convert (you can plug-in your own and extend it),
as well as ▼“named-colors” from any of the “palettes” that are loaded.
The individual ▼“audit” conversion functions can accept
a single String
with the values separated by commas and/or spaces,
or an Array
of values in either String
or numeric (Number
) format.
They generally (except see special option RGB_Calc.config.inputAsFactor
)
accept values with limits that a CSS definition would impose:
i.e. 0–255 for sRGB, and 0%–100% for others,
or for hue-angles, any value is accepted and automatically transformed into a standard angle
(since angles are circular, 45° = 405° = −335°).
Any value outside the limits will not be accepted, and may throw an Error
if you choose
(see RGB_Calc.config.onError
).
Besides the individual conversion functions, a newly constructed “audit” RGB_Calc
Class object
offers a “general input” interpreter that interprets just about any format you throw at it and returns
the RGBA values in the Object
of your choice;
an explanation of the String
values it can interpret follows the code examples:
const myCalc=new SoftMoon.WebWare.RGB_Calc;
const c1=myCalc( "HSL(0.3turn, 50%, 84%)" );
// By default, the returned value is a custom RGBA_Color object;
// its .toString('css') method yields: "RGB(202, 235, 194)"
console.log(c1);
const c2=myCalc.to.hsl( "CMYK(14.0255%, 0%, 17.44681%, 7.84314%)" );
// Here, the CMYK color is converted to RGB internally, and then to HSL.
// RGB values may be rounded if myCalc.config.roundRGB=true
// and this can affect the final HSL conversion values slightly.
// Note that rounding the RGB values makes the
// final HSL values a true representation of the sRGB color-space.
// By default, the returned value is a custom HSLA_Color object;
// its .toString('css') method yields: "HSL(108.29deg, 50.61728%, 84.11765%)"
console.log(c2);
const c3=myCalc.from.hsl("108.29deg, 50.61728%, 84.11765%");
// By default, the returned value is a custom RGBA_Color object;
// its .toString('css') method yields: "RGB(202, 235, 194)"
console.log(c3);
// you can even leave out the units:
// “audit” calculators by default use percents not factors (except for RGB uses bytes!)
// except for hue-angles use the unit in myCalc.config.hueAngleUnit ("deg" by default)
// UNLESS myCalc.config.inputAsFactor=true ←then ALL values are considered factors (0.0–0.1)
const c4=myCalc.from.hsl("108.29, 50.61728, 84.11765");
console.log(c4);
myCalc.config.inputAsFactor=true; // we can also use .config.stack(…)
const c5=myCalc.from.hsl("0.3, 0.5, 84%") //←all values are factors, except 84% because it has a qualifier!
const c6=myCalc.from.hsl([0.3, 0.5, "84%"]) //←we can even pass an array of numeric and/or string values
// Just like the “quick-calc” examples above, we can also get conversion values
// returned in a simple Array or YOUR custom Class object
// using myCalc.config.stack()
// or by changing myCalc.config. values directly.
Valid String
values for colors include:
- RGB values in hexadecimal (a.k.a. hex) with or without the leading # symbol.
- RGB values as:
- integer byte values (0—255)
- percent ratios (0%—100% — ¡be sure to use the percent % symbol with RGB values!)
Each value may be separated by spaces/commas. You may wrap() or prefix: the values with rgb( ) or rgb: but that is not necessary.
- various different color-space models including:
- CMYK
- CMY
- HSV / HSB
- HSL
- HCG
- Hue ← define only a hue-angle-value and see the full-color (fully chromatic) tone of the hue.
- XYZ → (Observer = 2°, Illuminant = D65) 0 ≤ X ≤ 95.047, 0 ≤ Y ≤ 100, 0 ≤ Z ≤ 108.883
Use models by wrapping() or prefixing: their given values. Values are given as percent ratios (0%—100% with or without the percent sign %); except Hue values are given in angular values using one of the following units: (the default unit used when none is specified is found in an
RGB_Calc
object’s.config.hueAngleUnit
property)- in degrees (0°—360° ← post-fixed using the ° symbol or “deg”).
- in radians (0ᴿ–2πᴿ≈6.2831853ᴿ ← post-fixed using the ᴿ symbol, the ᶜ symbol, or “rad”).
- in gradians (0ᵍ—400ᵍ ← post-fixed using the ᵍ symbol or “grad”).
- in % of a turn (0%—100% ← post-fixed using the % symbol).
- of a turn (0●—1● ← post-fixed using the ● symbol or “turn”).
- Any of the available ▼named “palette” colors.
Colors should be prefixed: or wrapped() with the appropriate color-palette name;
except CSS colors do not need to be wrapped or prefixed by default.
(The default color-palette name can be found and changed at
SoftMoon.defaultPalette
) “Named color” palettes may have sub-palettes; you may or may not need to include the sub-palette name in your color-spec, depending on the palette. Generally, if all the colors in the parent palette and its sub-palettes have different names, no sub-palette is required in the spec.ANSI: 35 ANSI: 8-bit: shades and tones: 35
You may specify opacity (the opposite of transparency) in any of the color space models (RGB, CMYK, CMY, HSV, HSL, HCG, HWB, Hue) by adding an additional factor (0-1) or percent (0%-100% ← you must use the percent % sign). This is called the “Alpha” channel in technical terms. The color-space model names may or may not end with an additional “A” (for example, RGB vs. RGBA). Per CSS4 specifications, the opacity value may also be separated with a / symbol that is itself preceded and followed by a space; for example RGBA(0, 153, 255 / 62%) Note the “loose” interpretation of CSS specs allows commas with the / alpha separator. Hex-RGB values may have an additional 2 hex digits to specify the alpha; for example #ADDCAD80 Named colors may use the same Alpha specification for color space models described above, but it must end with either a semicolon ; or a space followed by opacity; For examples:
- Green 30%;
- DodgerBlue, 78%;
- ANSI: 35 / .84 opacity;
Note that named colors may already have and Alpha value, and if you “add on” another Alpha value as shown above,
it will be multiplied by the color’s existing one. For example, if a named-color already has
an Alpha value of 50%, and you add on another 50% Alpha, the final Alpha value is 25%.
You can forbid this action using myCalc.config.forbidAddOnAlpha=true;
(or by using myCalc.config.stack({forbidAddOnAlpha:{value:true}});
).
Examples:
- These all give the same red color:
- 255 0 0
- rgb (255 0 0)
- rgb(255, 0 0)
- #FF000
- ff0000
- HCG(0deg, 100, 50)
- HSL: 0°, 100%, 50%
- HSV: 0° 100% 100
- red
- CSS: red
- X11( RED )
- These all give the same blueish color:
- 135, 206, 250
- RGB (135, 206, 250)
- RGB: 135, 206, 250
- #87cefa
- 87ceFA
- hcg(202.96deg, 45.098% 96.429%)
- hsl:56.3768%,92,75.49
- hsv ( .563768turn 46% 98.039% )
- lightSkyBlue
- css (LiGHTSKyBLue)
- X11:lIghtskYblUE
The properties & methods of the RGB_Calc
object, and its class instances
RGB_Calc
.config
- holds this calculator’s configuration options.
It is an instance of the
▼RGB_Calc.ConfigStack
Class. .to
- holds functions converting sRGB to other color-models.
.from
- holds functions converting from other color-models to sRGB.
.install()
- Used to install different conversion functions “on the fly,” such as when there are two different color-blind filters available, etc.
.outputRGB()
- filters all sRGB output, according to this calculator’s
.config.roundRGB
flag and returns the output using the object-constructor defined by this calculator’s.config.RGBA_Factory
.getByte()
- filters sRGB input and guarantees results from 0—255
.getFactor()
- filters input and returns a factor from 0—1,
or
false
if the value is out-of-range. Input may be a string or number, and may be a percent (0-100), or already a factor if.config.inputAsFactor
is true; but strings with a%
qualifier at the end are always considered percents. .getHueFactor()
- filters input and returns a factor from 0—1;
note hue-angles are circular, so no value is out-of-range.
The conversion factor is determined by
.config.hueAngleUnit
or the value may already a factor if.config.inputAsFactor
is true; but strings with a hue-angle-unit qualifier at the end respect that conversion factor. If the hue-angle-unit is not recognized, this function returnsfalse
. .getAlpha()
- filters input and returns a factor from 0—1,
or
false
if the value is out-of-range. Input may be a string or number. Input values are considered factors from0.0
–1.0
unless they have%
qualifiers. .factorize()
- filters an
Array
of values usingthis.getFactor()
,this.getHueFactor()
, andthis.getAlpha()
, and returns either:- a new
Array
(with the factorized values) when.config.preserveInputArrays=true
- the same
Array
(with the modified values) when.config.preserveInputArrays=false
false
if.getFactor()
orthis.getHueFactor()
or.getAlpha()
returnsfalse
- a new
.applyAlpha()
- This function applies an alpha value to a given color-object.
The two Alpha values are multiplied according to the
formula in
multiplyAddOnAlpha()
(see below). It is used when you pass a “named-color” to an “auditing” calculator, and you specify an “add-on” Alpha value to a color that already has an Alpha value. For example: skyPalette: clouds / 84% opacity; Suppose this color (skyPalette: clouds) is a partly transparent blueish-graytone: RGB(50%, 55%, 70%, 80%) Then the final alpha result is (by the default formula):80% × 84% = 67.2%
If you use your own custom color-objects for RGB calculator output, you may need to update or replace this function to work with them, if they don’t have an.alpha
property, and they are not anArray
or a child-class ofArray
. .multiplyAddOnAlpha()
- This function takes two alpha values and multiples them according to a specific formula. You may modify the formula to suit your needs by replacing this function.
.convertColor()
- used by “audit”
.to
functions to interpret the given color using the “catch-all” function (see.$()
below) and convert it to sRGB before further converting to the final format. .$()
- This is only found on “audit” instances of the
RGB_Calc
class and is a mirror of the “catch-all” function that is the central to that class. In other words:var rgb, myCalc = new SoftMoon.WebWare.RGB_Calc(); rgb=myCalc('red') //the easy preferred way rgb=mycalc.$('red') //the long way
This allows methods of an “audit”RGB_Calc.to
Class instance to access the “catch-all.” .ConfigStack
- constructor (static property of
RGB_Calc
only) .hueAngleUnitFactors
- data table (static property of
RGB_Calc
only) .colorblindProviders
- table of color-blind filter-functions and their meta-data. (static property of
RGB_Calc
only, and only present when an external color-blind filter provider file is present)
In general, only the first 4 listed properties of RGB_Calc
(above)
are used, and in common use, only the first 3 listed.
There are 2 different color-blind filters currently available for the RGB_Calc
Class library.
Both install themselves as RGB_Calc.to.colorblind()
methods;
but only one can work at a time.
They also install their meta-data in the static RGB_Calc.colorblindProviders
property.
You can use RGB_Calc.install('colorblind', 'Rigden')
or RGB_Calc.install('colorblind', 'Wickline')
,
and the filter you choose will become the one that is active,
not only in RGB_Calc.to
but in all future calculators
constructed (using for example myCalc = new RGB_Calc();
).
If you use, for example myCalc.install('colorblind', 'Rigden')
then
the colorblind filter you install will only take effect on that individual instance
of the RGB_Calc
Class.
The RGB_Calc.to
and RGB_Calc.from
methods are all lowercase,
and the RGB_Calc.from
methods must be for
the “catch-all” String
filtering function to recognize them.
You may add to them as you wish.
The format makes programming with them simple & easy to de-localize,
allowing, for examples: RGB_Calc.from[model]
or myCalc.to[model]
.
The RGB_Calc.to
and RGB_Calc.from
objects have as their prototype
the calculator they are attached to.
That means that the prototype of RGB_Calc.to
or RGB_Calc.from
is itself RGB_Calc
.
Likewise, when you construct a custom calculator: const myCalc = new RGB_Calc()
the objects myCalc.to
and myCalc.from
have as their prototypes myCalc
.
Therefore, any of the methods of RGB_Calc.to
or RGB_Calc.from
(or similar to newly constructed calculators)
can refer to this.config
and assess the ConfigStack
instance
for the given calculator.
The other RGB_Calc
methods are all hooks to functions that are used internally.
These hooks are for plug-ins to the RGB_Calc
Class to access.
You may use these hooks or hack them as you wish, but generally you need not worry about them.
Finally, the last 3 properties listed above of RGB_Calc
are static properties
and are not included with class instances.
They are also available for your hacking or other use, but the RGB_Calc.ConfigStack
constructor
and its .prototype
need special attention.
Every calculator gets its own instance of an RGB_Calc.ConfigStack
constructed object for its .config
property,
and every RGB_Calc.ConfigStack
instance is “attached” to its calculator.
Also, every custom Color Object
(RGBA_Color
s, ColorWheel_Color
s, & CMYKA_Color
s)
gets its own ConfigStack
, and those stacks each may have different defaults for each type of custom Color Object
.
The “ConfigStack” has in its prototype all the default configuration values and special methods.
You can easily change the values in any individual calculator or Color Object
without affecting the others,
for example RGB_Calc.config.roundRGB=true;
.
But the “ConfigStack” is a prototype-stack with methods to add to and remove from the stack:
specifically RGB_Calc.config.stack()
and RGB_Calc.config.cull()
.
When you .stack()
, the “Stack” adds another new Object
to its own top-level making itself the prototype of this new Object
,
and re-points its calculator’s .config
property to this new Object
.
(Remember, when JavaScript™ looks for a property of an object and doesn’t find it there,
it looks in that object’s prototype and then recursively the prototype’s prototype until it finds the property;
this makes native JavaScript™ Objects an ideal container for configuration values!)
Then you can change the configuration values as you like to temporarily suit your needs,
then use .config.cull()
to return to the previous configuration values.
To make it even easier, .config.stack()
accepts a parameter that is a JavaScript™
Object-Properties-Definer (see a good
►JavaScript™ reference):
for example myCalc.config.stack({roundRGB:{value:false}, RGBA_Factory:{value:Array}});
.
In this way, you can temporarily modify individual configuration value(s) for an individual calculator
and then restore the original value(s), quickly and easily without having to keep track of said original value(s).
You can use .config.stack()
multiple times and build the “ConfigStack”
to as many levels as you need; the .config.reset()
method will remove
all the Objects
stacked for the given calculator’s configuration.
For any calculator, you don't need to .stack()
the .config
to temporarily change the config values if you only use defaults in your calculator instance,
as the defaults are in the prototype. However, if you pass a .config
descriptor
object to the RGB_Calc
constructor, those values are
stored in the top level of your ConfigStack, and modifying the .config
directly modifies them.
Using delete
as shown below is faster and convenient if you only
want to temporarily change one or maybe two values.
Using it with many values may be slower and clutters your codespace —
that’s why .stack()
and .cull()
were included.
const myCalc=new SoftMoon.WebWare.RGB_Calc({hueAngleUnit:'grad'});
myCalc.from.hsv("34, 95, 45"); // input as gradians & percents by this calc’s current default
myCalc.config.inputAsFactor=true;
myCalc.from.hsv("34grad, .95, .45"); // input as gradians & factors by this calc’s current default
delete myCalc.config.inputAsFactor; // now the .config value goes back to the old default, faster than .stack() & .cull()
myCalc.config.hueAngleUnit='rad'; // we can never go back to "grad" - if we delete this value, the prototype value is used
myCalc.config.stack(); // if we did this first (after we created the calculator) all values could be preserved using delete
There is also a flag to .config.resetConfigStackOnThrownError
when using the standard
.config.onError()
handler.
However, now-a-days it is considered best practice to use a try {…} finally {…}
code-block (this config option was developed for legacy dinosaur browsers,
but it still may simplify your complex coding schemes).
Note using try {…} finally {…}
also covers your script’s butt if a native JavaScript™ Error occurs
(none now known to exist) in the RGB_Calc code itself.
const myCalc=new SoftMoon.WebWare.RGB_Calc;
document.querySelector('input#userColor').attachEventListener('change', function()
{
myCalc.config.stack({throwErrors: {value:true}});
try {doItAgainAndAgain(this.value);} // if the user-input is in error, an Error is thrown and console outputs once here …
catch(e) {console.error('we had an error with the color:',e);} // … … … and a second time here
//we ALWAYS want to clean up the stack, but since any Errors are caught above, we really don’t need “finally” below
finally {myCalc.config.cull();}
} );
function doItAgainAndAgain(userInput)
{
const c1=myCalc.to.hsl('RGB: 234,127,35');
console.log(c1); //outputs from the standard HSLA_Color object: HSL(27.74deg, 82.57261%, 52.7451%)
myCalc.config.stack({HSLA_Factory: {value:Array}});
try {
const c2=myCalc.to.hsl(userInput);
console.log(c2); //outputs from the Array object, or “null.” (“red” is): Array(3) [ 0, 0.5, 1 ]
}
//we ALWAYS want to clean up the stack, or if an error is thrown in the above calculator,
//the stack will still have the HSLA_Factory as an Array next time we use this function or this calculator.
finally {myCalc.config.cull();}
}
doItAgainAndAgain('red'); // no errors here - console outputs twice
doItAgainAndAgain('foo-bar'); // an error but it is not thrown - console outputs twice, second is "null"
There is no reason you can’t also change the ConfigStack.prototype
itself.
As is with JavaScript™,
this will modify the default configuration values for all
calculators: the basic RGB_Calc
itself, as well any constructed in the past or future.
Recognized properties & methods of a ConfigStack
instance:
ConfigStack
.reflect
- For the RGB color model, depending on this Boolean flag, values passed in outside the range of 0—255 are either “reflected” or “clamped” back into the correct range.
.roundRGB
- For the RGB color model, depending on this Boolean flag, values may be rounded to integers or left as floating-points.
.inputShortHex
- When
true
, “audit” functions can recognize 3- or 4-digit hex values as valid colors. Whenfalse
, only 6- and 8-digit hex values are valid colors .inputAsFactor
- When
true
, all “audit” functions interpret input values as factors from 0—1; except string based values with unit qualifiers (i.e. a percent sign % or a Hue-Angle-Unit); and also exceptNumber
object instances with a.unit
property that qualifies another unit:class Hue extends Number {} Hue.prototype.unit="deg"; const h=new Hue(78); const s=new Number(50); s.unit="%"; const red=new Number(0.37); red.unit='factor'; // did you know Number instances work exactly like primitive numbers // except they can carry meta-data: console.log(h.unit); //deg console.log(h*s); //3900 console.log((h-4)*(h+4)); //6068 console.log(red.unit); //factor const foo=3; foo.bar='baz'; //not an error but… console.log(foo.bar) //undefined
Whenfalse
, all “audit” functions take by default (float)bytes for RGB, and percents and whatever.config.hueAngleUnit
is for the other color-models. Remember, all “quick” calculator functions always take inputs as (float)bytes or factors; there is no other option. .hueAngleUnit
- Default input unit when none is specified in “audit” functions and
ColorWheel_Color Objects
; also default output unit forColorWheel_Color Objects
(HSL, HSV, HSB, HCG, and HWB). Valid units are listed as the property keys ofRGB_Calc.hueAngleUnitFactors
. The.hueAngleUnit
default is overridden by.inputAsfactor
(see above) when input values have undeclared units. .useHexSymbol
- When outputting RGB Hex values, this Boolean flag determines the format. For example: A1B2C3 vs. #A1B2C3
.preserveInputArrays
- When you pass an
Array
into an “audit” calculator, it will interpret the values and may convert them into factors from0–1
. You may want to have access to those converted values, or you may want to preserve the original values: your choice. RGBArrays
are always preserved. .defaultAlpha
- When a calculator’s method, or an
RGBA_Color
constructor, aColorWheel_Color
constructor, or aCMYKA_Color
constructor gets passed anundefined
Alpha value, this value is used instead. It may be anything, includingundefined
also. However, these color-objects, once constructed, may have any value directly set for the Alpha, includingundefined
, and this default is ignored. Also, these color objects’.toString()
methods, when told to force an Alpha output, will output a default Alpha value of100%
if both their Alpha values and their.config.defaultAlpha
are not numeric. Note that when a calculator outputs, it will not outputundefined
Alpha values; when usingArray
s as an output object (see the “Factory” pointers below) its.length
value will reflect that omission. .forbidAddOnAlpha
- For named (palette) colors
we can forbid (or allow) an add-on alpha or not according to this Boolean value
(
true
/false
). If a named color’s value is RGBA(50%, 55%, 70%, 80%) and it is in the “Sky” palette and its name is “clouds” auditing calculators can use the following spec: Sky: clouds / 84% opacity; Using the default alpha-multiplier function (RGB_Calc.multiplyAddOnAlpha()
) the final alpha value will be 80% × 84% = 67.2% .RGBA_Factory
- Pointer to the constructor for the output
Object
holding RGB values. You may want to useArray
orSoftMoon.WebWare.RGBA_Color
, or create your own Class constructor for any of these Factories. .HSLA_Factory
- Pointer to the constructor for the output
Object
holding HSL values. You may want to useArray
orSoftMoon.WebWare.HSLA_Color
, or create your own Class constructor for any of these Factories. .HSBA_Factory
- Pointer to the constructor for the output
Object
holding HSB values. You may want to useArray
orSoftMoon.WebWare.HSBA_Color
, or create your own Class constructor for any of these Factories. .HSVA_Factory
- Pointer to the constructor for the output
Object
holding HSV values. You may want to useArray
orSoftMoon.WebWare.HSVA_Color
, or create your own Class constructor for any of these Factories. .HCGA_Factory
- Pointer to the constructor for the output
Object
holding HCG values. You may want to useArray
orSoftMoon.WebWare.HCGA_Color
, or create your own Class constructor for any of these Factories. .HWBA_Factory
- Pointer to the constructor for the output
Object
holding HWB values. You may want to useArray
orSoftMoon.WebWare.HWBA_Color
, or create your own Class constructor for any of these Factories. .CMYKA_Factory
- Pointer to the constructor for the output
Object
holding CMYK values. You may want to useArray
orSoftMoon.WebWare.CMYKA_Color
, or create your own Class constructor for any of these Factories. .onError()
- This is the standard input value error handler filter function. Replace it as necessary.
.throwErrors
- Boolean flag used by the standard
.OnError()
function (above). Change totrue
for debugging, etc… If errors are not thrown, theconfig.errorResult
is returned instead. .logErrors
- Boolean flag used by the standard
.OnError()
function (above). Change totrue
for debugging, etc… .errorResult
- The value returned by the standard
.OnError()
function (above) when input values are in error andconfig.throwErrors
isfalse
. .resetConfigStackOnThrownError
- If you throw errors, you may need to clean up your
.config
stack, lest you create a bug or memory leak in your code’s functioning. Set this Boolean flag totrue
to do so automatically when using the standard.onError()
function (above). See also the notes and code example above on usingtry {} finally {}
code blocks instead. .stack()
- Add another layer to the “top” of this
ConfigStack
’s prototype-based stack. Pass in an optional ►Object
properties descriptor to quickly set new configuration values. Then make any temporary changes you like to the configuration values; they will be valid until you.cull()
or.reset()
this stack (see below). .cull()
- Removes the “top” layer of this
ConfigStack
’s prototype-based stack. Configuration values revert to previous settings before the last.stack()
(see above). .reset()
- Removes all layers
.stack()
ed onto thisConfigStack
’s prototype-based stack. Configuration values revert to the “bottom” layer of settings (just above the.prototype
). .owner
- Private property: do not over-write this value in the
ConfigStack
instance. This refers back to the calculator instance or the custom ColorObject
instance that thisConfigStack
instance is “attached” to. .stringFormat
- For
RGBA_Color Objects
,CMYK_Color Objects
, &ColorWheel_Color Objects
(HSL, HSV, HSB, HCG, and HWB) thisString
value may define a custom output format by the default.toString()
method. Note you may also pass a format-string that follows these same rules directly to the.toString()
method and it will take precedence over the rules found in this default format. It has no formatting rules other than values found in the beginning of the format-string override conflicting values later in the format-string. The format-string may contain anything, but the values shown below have meaning. Note the formatting style examples are shown for the RGB color-space, others are similar:output formatting style: # ‡ #rrggbbaa ‡ hex ‡ css ◊ RGBA(r, g, b, a) ☼ html ◊ wrap function prefix RGBA: r, g, b, a ☼ commas r, g, b, a csv plain r g b a tabbed rTabgTabbTaba self RGBA_Color(r, g, b, a) All formats may not include the alpha value if it is undefined. ‡ hex formats are only for the RGB color-space and may or may not have the #
symbol, depending on the Boolean value of.config.useHexSymbol
and/or the presence of#
in the format string itself.◊ css & html formatting styles prevent (most of) the numeric output format from being a factor (see the next table), and prevent hue-angle units from being “symbols” — they convert to the “textual” equivalent (see the following table) except for %
which is not a true CSS unit for hue-angles, but word on the street is that all browsers support it. Also, for the HWB color-model, the output is de-standardized to suit the weird non-standard spec format, and commas,
are removed, and the alpha separator/
is used, and…(read on)…☼ The “A” in “RGBA” and other color-models will not be included if the alpha value is undefined. Also for HWBA_Colors
, the “A” will always be dropped when the output style is css ‖ html.Numeric values output format: byte for the sRGB color-space only, values are shown as integer-bytes (0–255) percent values are shown as percents (0%–100%) factor values are shown as factors (0.0–1.0) (not for css ‖ html formatting styles, except for hue & alpha values) alpha always show an alpha value, even if one is not defined. If it is not defined, it becomes defined in the RGBA_Color
object as the.config.defaultAlpha
value, or1
if the default is not defined.Hue-angle-unit output format: Only for ColorWheel_Color
objects (HSL, HSV, HSB, HCG, and HWB)deg values are shown as degrees (0°–360°) ° rad values are shown as radians (0ᴿ–2πᴿ≈6.2831853ᴿ) ᴿ ᶜ grad values are shown as gradians (0ᵍ–400ᵍ) ᵍ % values are shown as percent of a turn (0%–100%) turn values are shown as turns of a circle (0.0●–1.0●)
“factor” is not actually a valid unit for hue-angles — it gets converted to “turn”● factor .useAngleUnitSymbol
- Only for
ColorWheel_Color Objects
(HSL, HSV, HSB, HCG, and HWB), and not when the format output style is css ‖ html (they always prevent using symbols): depending on this Boolean flag (true
/false
), the.toString()
method may output hues with either: ▪ a symbol: (example: 78°); ▪ or a textual suffix: (example: 78deg) ← when applicable for the hue-angle-unit. Typically, the hue-angle-unit used for output is defined by: ▪.config.hueAngleUnit
or ▪.config.formatString
or ▪ by passing a “formatString” directly to the.toString()
method itself, and may already be a symbol or not, but this flag, when Boolean, will override the final result. This flag is ignored when its value is not Boolean, such asnull
orundefined
or0
or1
.
The 7 “Factory” pointers of a ConfigStack
instance (above)
control the output of the functions of RGB_Calc
and its instances.
You can set any the default configuration values for your new calculator by passing an
Object
with corresponding key/value pairs to the constructor as the 1Objects
(RGBA_Color
, etc.) by passing to their constructors the configuration options object
as the final (5.config.stack()
method,
this configuration Object
is not a JavaScript™ “properties descriptor.”
/*
* this example provides a calculator that returns
* RGB output as a simple array of values,
* instead of the default RGBA_Color object instance:
*/
myCalc=new SoftMoon.WebWare.RGB_Calc({RGBA_Factory:Array});
/*
* this example provides a calculator that returns
* an RGBA_Color object instance that outputs
* hex using the # symbol, regardless of the universal default:
*/
myCalc=new SoftMoon.WebWare.RGB_Calc;
myCalc.config.RGBA_Factory=function(r,g,b,a) {
return new SoftMoon.WebWare.RGBA_Color(r,g,b,a,{useHexSymbol:true});
};
“audit”, “quick”, & “mini” calculators
When you create your own new calculator, it can be either an “audit” or “quick” type.
This is controlled by passing true
for a “quick” calculator,
or false
(the default) for an “auditing” calculator, as the 2Object
(passed into the constructor as the 3Array
listing the conversion functions as individual String
values.
You can have any combination of these options, such as a “quick-mini” calculator that returns native Array
s.
// This is the calculator that the “Rigden-colorblind_websafe-table_interpolator”
// plug-in for this RGB_Calc
class uses in its own internal workings.
// It is a “quick” calculator that only has RGB to HCG functionality, and it returns an Array.
const rgb_calc=new SoftMoon.WebWare.RGB_Calc(
{HCGA_Factory: Array, defaultAlpha: undefined},
true,
{to:['hcg']}
);
using the named-color palettes
The RGB_Calc
Class can interpret named colors, as well as color-models,
when using an “auditing” calculator.
It comes packaged with nine named-color database files included:
ANSI, Brewer, common, Crayola, CSS, Material Design, OpenOffice, universal, & X11.
The palette file format can come in two formatting flavors: JavaScript™ & JSON.
The JavaScript™-formatted palette-files can be hard-loaded using an HTML <script> tag in
your web-page; while the JSON-formatted palette-files can be loaded from a server
using HTTP.
The RGB_Calc
package comes with a basic JavaScript™ function
(SoftMoon.WebWare.loadPalettes()
)
to load JSON palettes from a server
as well as a basic PHP file for the server’s color_palettes/
folder “index”
that are designed to work together.
(Note that the name of this folder can be changed but it must end with a folder-separator /
— see: SoftMoon.colorPalettes_defaultPath
)
(Note also that the PHP “index” file may be replaced with one in any programming language, or even a static text file!)
You can simply add/remove palette files (they must have the extension: .palette.json)
from the server’s color_palettes/
folder
without having to modify any HTML, JavaScript™, or PHP code
(if you use a static text file for the “index”, you will have to keep it manually updated);
the “qualifying” palette files in the folder will be loaded.
Without a server, the palette files must be loaded via
HTML <script> tags in the JavaScript™ flavor.
You can also create your own named-color palettes,
and an instructional file to do so is included in the color_palettes/
folder.
As a special note, your palettes can have their own .config
values for the calculator that interprets them,
and this should be a simple object containing the properties and their settings you desire,
the same as you pass into the calculator or custom-color-objects constructors
(not an object-properties-descriptor formatted for ▲ .config.stack()
).
You may want to pay attention to them if you use a “non-standard” configuration.
All palettes use inputAsFactor=false
and hueAngleUnit='deg'
by default,
regardless of whatever the current calculator’s .config
values are.
Remember, simply using unit-qualifiers in your palette’s color specs may alleviate the need for any .config
values.
In particular, your individual palettes may want to control the default Hue-angle-unit,
input-as-factors, input-as-short-hex, default Alpha values, or whether to allow add-on Alpha values.
Configuration values for palettes are by default limited to the above list of properties,
since normally the other calculator configuration settings are not Palette-specific,
but your implementation may add (or remove) properties from this list.
There is no reason you couldn’t, for example, create a system that uses your own
custom Color-objects as return-data from the calculator,
and your individual Palettes may want to specify which “Factory” to choose.
You can control which .config
properties are allowed in a Palette
through the array at SoftMoon.WebWare.Palette.configProps
by adding/removing string-names of the specific properties.
Palette files may have extraneous meta-data in them.
The supplied files come with meta-data that the
►MasterColorPicker
project uses.
You may also put any meta-data in the palettes you create, but when they are loaded
and processed, the final SoftMoon.WebWare.Palette
object
that gets saved in SoftMoon.palettes
will not, by default, include said meta-data.
If you want your meta-data included in the processed palette, you need to tell the
SoftMoon.WebWare.Palette
constructor to include it.
To do so, add string values for the meta-data property names
to the SoftMoon.WebWare.Palette.properties
array.
If your custom palette uses the meta-data property “foobar,”
then use the code: SoftMoon.WebWare.Palette.properties.push('foobar');
Palette files are supplied in the JavaScript™ flavor. To use them with a server requires that they are converted to JSON. This is simple and easy; there is an instructional file to do so manually, as well as a PHP file to do so automatically. Find both in the color_palettes/ folder.
To use a JavaScript™ flavored palette,
you must first create a property of the SoftMoon
namespace:
SoftMoon.loaded_palettes=new Array;
then load the file using a <script> tag.
The palette will place itself in the SoftMoon.loaded_palettes
array.
You must then use a JavaScript™ Event-handler to add the palette to the “processed”
palettes (found in SoftMoon.palettes
).
You use the function SoftMoon.WebWare.addPalette()
to process the palette.
You can use an “onload” property of the <script> tag as shown in the example at the top of this page,
or wait until all palettes are loaded and use an “onload” event on the window
and then add all palettes found in the SoftMoon.loaded_palettes
array.
To use a JSON flavored palette,
the SoftMoon.WebWare.loadPalettes()
function contacts the server,
requesting the index for the palette files.
The index returned contains the names of all palette files
in the color_palettes/
folder & its sub-folders.
Once the loadPalettes()
function gets the index, it “qualifies” each file for loading.
Any file in a “trash” folder or its sub-folders is ignored.
Any file in a “users” folder or its sub-folders is ignored,
unless it is in an “autoload” folder or its sub-folders.
The names of these folders (“trash”, “users”, “autoload”)
can be modified, but it is a bit trickier
and requires knowing how to use JavaScript™ Regular Expressions;
see the loadPalettes()
function code in the RGB_Calc.js file for more details.
Once a palette file is deemed “qualified” for loading, it is loaded, processed,
and added to SoftMoon.palettes
The SoftMoon.WebWare.loadPalettes()
function requires no parameters to work,
but it can take many, to customize the palette loading process.
These are no light-duty customizations.
The details of these customizing options are beyond this text,
require that you fully understand JavaScript™
and asynchronous communications,
and are fairly self-explanatory if you read the
loadPalettes()
function code in the RGB_Calc.js file.
The loadPalettes()
function relies on the external file HTTP.js
to handle communications, and some of the parameters you pass are for
customizing that Class’ functionality so see its file also.
Palettes may also be loaded from a browser’s internal database.
The SoftMoon.WebWare.loadDBPalettes()
function handles this.
However, no functionality is supplied to store a palette in the database; this may change in the future.
(The ►MasterColorPicker
project can create them, if you are interested; but remember:
browser databases only work with the website domain (when using a server)
or the individual HTML file (when working from your home filesystem) that created the database.)
Palettes in the database should be JSON formatted.
You can also customize the functionality of the loading process as you can when loading from a server — see the code.
RGB_Calc
’s custom color Object
s
The RGB_Calc
package comes with constructors for custom color Object
s
and these are used as the default output from conversion functions.
They are meant to be relatively “universal” in usage with other software packages.
They are designed internally so if you change one value in the color-object,
it reflects throughout the entire object.
For example, in an RGBA_Color
object, if you change the property of
.red
, the other properties .r
.rgb[0]
.rgba[0]
& .hex
all change in accordance.
The RGBA_Color
objects also have within themselves conversion properties
to other color-models, as well as properties that provide “contrast” and “shade.”
These other custom objects have within them a conversion property to RGB,
and HSBA_Color
& HSVA_Color
objects also provide
a conversion property to CMYK, since this is a near-parallel mapping.
You can find this latter conversion service as a static function
at:
SoftMoon.WebWare.HSVA_Color.to_CMYK()
const myRGB=new SoftMoon.WebWare.RGBA_Color(245, 191, 46);
console.log(myRGB.to.hcg); //this is a property, not a method.
console.log(myRGB.to.cmyk); //this is a property, not a method.
console.log(myRGB.contrast); //this is a property, not a method.
const myHSV=new SoftMoon.WebWare.HSVA_Color(0.4, 0.9, 0.67);
console.log(myHSV.to.rgb); //this is a property, not a method.
console.log(myHSV.to.cmyk); //this is a property, not a method.
const myHSV_array=[0.4, 0.9, 0.67];
console.log(SoftMoon.WebWare.HSVA_Color.to_CMYK(myHSV_array)); // this is a simple function, not a method.
These custom color Object
s also provide .toString()
methods
that provide user-friendly reading.
These methods are highly customizable with ease, on-the-fly as necessary.
To control their output, you use the ConfigStack
configuration object
of the custom color Object
(e.g. myColor.config.stringFormat
)
or pass in the formatting info directly to the .toString()
method.
For ColorWheel_Color
s, the .config.useAngleUnitSymbol
option is valid also.
See the ▲details in the section on ConfigStack
s above.
You should note that the HSB and HSV color-models are actually one-in-the-same.
RGB_Calc
’s custom underlying Color-Object
is therefore the same.
You can access “.brightness
” from an HSVA_Color
instance,
and “.value
” from an HSBA_Color
instance.
The only difference is in the constructor
and name
values:
const hsv=new SoftMoon.WebWare.HSVA_Color(0.3, 0.5, 0.7);
const hsb=new SoftMoon.WebWare.HSBA_Color(0.3, 0.5, 0.7);
console.log(hsv instanceof HSBA_Color); //false
console.log(hsb instanceof HSVA_Color); //false
console.log(hsv instanceof ColorWheel_Color); //true
console.log(hsb instanceof ColorWheel_Color); //true
console.log(hsv.name) //HSVA_Color
console.log(hsb.name) //HSBA_Color
console.log(hsv.brightness) //0.7
console.log(hsb.value) //0.7