Custom Web Software Development

JavaScript, HTML 5, CSS 4, & PHP 8: Innovative Enterprise level Scripting for interactive sites, SaaS, & cross-platform desktop apps
  • Home
  • Automotive Dealer Website Development
  • Free desktop apps
  • Rainbow-Maker
  • MasterColorPicker
  • Free libraries: JavaScript and PHP
  • <input type="picker">
  • RGB_Calc color-space converter
  • FormFieldGenie fieldset multiplier
  • UniDOM.js x-browser solution +
  • eMail address validation scripts
  • PHP Utility Functions
  • ActiveState Komodo Edit support
  • RGB_Calc color-space conversion calculator

    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 Arrays to pass data in & out provided the fastest execution times by far.  The predecessor of this class passed back only (custom) “color-Objects,” 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 Arrays 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[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. 0255 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 "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:

    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:

    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}});).


    The properties & methods of the RGB_Calc object, and its class instances


    holds this calculator’s configuration options.  It is an instance of the ▼RGB_Calc.ConfigStack Class.
    holds functions converting sRGB to other color-models.
    holds functions converting from other color-models to sRGB.
    Used to install different conversion functions “on the fly,” such as when there are two different color-blind filters available, etc.
    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
    filters sRGB input and guarantees results from 0—255
    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.
    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 returns false.
    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 from 0.01.0 unless they have % qualifiers.
    filters an Array of values using this.getFactor(), this.getHueFactor(), and this.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() or this.getHueFactor() or .getAlpha() returns false
    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 an Array or a child-class of Array.
    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.
    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” Class instance to access the “catch-all.”
    constructor (static property of RGB_Calc only)
    data table (static property of RGB_Calc only)
    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 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 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 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[model].

    The and RGB_Calc.from objects have as their prototype the calculator they are attached to.  That means that the prototype of or RGB_Calc.from is itself RGB_Calc.  Likewise, when you construct a custom calculator: const myCalc = new RGB_Calc() the objects and myCalc.from have as their prototypes myCalc.  Therefore, any of the methods of 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_Colors, ColorWheel_Colors, & CMYKA_Colors) 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'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; 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:


    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.
    For the RGB color model, depending on this Boolean flag, values may be rounded to integers or left as floating-points.
    When true, “audit” functions can recognize 3- or 4-digit hex values as valid colors.  When false, only 6- and 8-digit hex values are valid colors
    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 except Number 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;'baz'; //not an error but… console.log( //undefined When false, 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.
    Default input unit when none is specified in “audit” functions and ColorWheel_Color Objects; also default output unit for ColorWheel_Color Objects (HSL, HSV, HSB, HCG, and HWB).  Valid units are listed as the property keys of RGB_Calc.hueAngleUnitFactors.  The .hueAngleUnit default is overridden by .inputAsfactor (see above) when input values have undeclared units.
    When outputting RGB Hex values, this Boolean flag determines the format.  For example: A1B2C3 vs. #A1B2C3
    When you pass an Array into an “audit” calculator, it will interpret the values and may convert them into factors from 0–1.  You may want to have access to those converted values, or you may want to preserve the original values: your choice.  RGB Arrays are always preserved.
    When a calculator’s method, or an RGBA_Color constructor, a ColorWheel_Color constructor, or a CMYKA_Color constructor gets passed an undefined Alpha value, this value is used instead.  It may be anything, including undefined also.  However, these color-objects, once constructed, may have any value directly set for the Alpha, including undefined, and this default is ignored.  Also, these color objects’ .toString() methods, when told to force an Alpha output, will output a default Alpha value of 100% if both their Alpha values and their .config.defaultAlpha are not numeric.  Note that when a calculator outputs, it will not output undefined Alpha values; when using Arrays as an output object (see the “Factory” pointers below) its .length value will reflect that omission.
    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%
    Pointer to the constructor for the output Object holding RGB values.  You may want to use Array or SoftMoon.WebWare.RGBA_Color, or create your own Class constructor for any of these Factories.
    Pointer to the constructor for the output Object holding HSL values.  You may want to use Array or SoftMoon.WebWare.HSLA_Color, or create your own Class constructor for any of these Factories.
    Pointer to the constructor for the output Object holding HSB values.  You may want to use Array or SoftMoon.WebWare.HSBA_Color, or create your own Class constructor for any of these Factories.
    Pointer to the constructor for the output Object holding HSV values.  You may want to use Array or SoftMoon.WebWare.HSVA_Color, or create your own Class constructor for any of these Factories.
    Pointer to the constructor for the output Object holding HCG values.  You may want to use Array or SoftMoon.WebWare.HCGA_Color, or create your own Class constructor for any of these Factories.
    Pointer to the constructor for the output Object holding HWB values.  You may want to use Array or SoftMoon.WebWare.HWBA_Color, or create your own Class constructor for any of these Factories.
    Pointer to the constructor for the output Object holding CMYK values.  You may want to use Array or SoftMoon.WebWare.CMYKA_Color, or create your own Class constructor for any of these Factories.
    This is the standard input value error handler filter function.  Replace it as necessary.
    Boolean flag used by the standard .OnError() function (above).  Change to true for debugging, etc…  If errors are not thrown, the config.errorResult is returned instead.
    Boolean flag used by the standard .OnError() function (above).  Change to true for debugging, etc…
    The value returned by the standard .OnError() function (above) when input values are in error and config.throwErrors is false.
    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 to true to do so automatically when using the standard .onError() function (above).  See also the notes and code example above on using try {} finally {} code blocks instead.
    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).
    Removes the “top” layer of this ConfigStack’s prototype-based stack.  Configuration values revert to previous settings before the last .stack() (see above).
    Removes all layers .stack()ed onto this ConfigStack’s prototype-based stack.  Configuration values revert to the “bottom” layer of settings (just above the .prototype).
    Private property: do not over-write this value in the ConfigStack instance.  This refers back to the calculator instance or the custom Color Object instance that this ConfigStack instance is “attached” to.
    For RGBA_Color Objects, CMYK_Color Objects, & ColorWheel_Color Objects (HSL, HSV, HSB, HCG, and HWB) this String 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
    css RGBA(r, g, b, a)
    prefix RGBA: r, g, b, a
    commas r, g, b, a
    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 csshtml.
    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 csshtml 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, or 1 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”
    Only for ColorWheel_Color Objects (HSL, HSV, HSB, HCG, and HWB), and not when the format output style is csshtml (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 as null or undefined or 0 or 1.

    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 1st parameter.  You can also set default configuration values for the custom Color Objects (RGBA_Color, etc.) by passing to their constructors the configuration options object as the final (5th or 6th) value.  Note that unlike the .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 2nd parameter to the constructor.  You can even make your own custom “mini” calculators that only have the conversion function(s) you specifically need.  The “mini” calculator descriptor Object (passed into the constructor as the 3rd parameter) can have “to” and/or “from” options (property keys), and their values should be an Array 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 Arrays.

    // 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 array.  If your custom palette uses the meta-data property “foobar,” then use the code:'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 Objects

    The RGB_Calc package comes with constructors for custom color Objects 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(; //this is a property, not a method. console.log(; //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(; //this is a property, not a method. console.log(; //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 Objects 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_Colors, the .config.useAngleUnitSymbol option is valid also.  See the ▲details in the section on ConfigStacks 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( //HSVA_Color console.log( //HSBA_Color console.log(hsv.brightness) //0.7 console.log(hsb.value) //0.7