Roo/lib/Color.js
authorAlan Knowles <alan@akbkhome.com>
Thu, 9 Feb 2012 05:36:54 +0000 (13:36 +0800)
committerAlan Knowles <alan@akbkhome.com>
Thu, 9 Feb 2012 05:36:54 +0000 (13:36 +0800)
Roo/lib/Color.js

index e69de29..7be9ccd 100644 (file)
@@ -0,0 +1,682 @@
+/*
+
+Colour.js
+
+Functions for colour handling and processing.
+
+http://www.safalra.com/web-design/javascript/colour-handling-and-processing/
+
+The author of this program, Safalra (Stephen Morley), irrevocably releases all
+rights to this program, with the intention of it becoming part of the public
+domain. Because this program is released into the public domain, it comes with
+no warranty either expressed or implied, to the extent permitted by law.
+
+For more free and public domain JavaScript code by the same author, visit:
+http://www.safalra.com/web-design/javascript/
+
+*/
+
+
+/* An abstract Colour implementation. Concrete Colour implementations should use
+ * an instance of this function as their prototype, and implement the getRGB and
+ * getHSL functions. getRGB should return an object representing the RGB
+ * components of this Colour, with the red, green, and blue components in the
+ * range [0,255] and the alpha component in the range [0,100]. getHSL should
+ * return an object representing the HSL components of this Colour, with the hue
+ * component in the range [0,360), the saturation and lightness components in
+ * the range [0,100], and the alpha component in the range [0,1].
+ */
+Roo.lib.Colour = function(){
+
+  /* Returns an object representing the RGBA components of this Colour. The red,
+   * green, and blue components are converted to integers in the range [0,255].
+   * The alpha is a value in the range [0,1].
+   */
+  this.getIntegerRGB = function(){
+
+    // get the RGB components of this colour
+    var rgb = this.getRGB();
+
+    // return the integer components
+    return {
+      'r' : Math.round(rgb.r),
+      'g' : Math.round(rgb.g),
+      'b' : Math.round(rgb.b),
+      'a' : rgb.a
+    };
+
+  };
+
+  /* Returns an object representing the RGBA components of this Colour. The red,
+   * green, and blue components are converted to numbers in the range [0,100].
+   * The alpha is a value in the range [0,1].
+   */
+  this.getPercentageRGB = function(){
+
+    // get the RGB components of this colour
+    var rgb = this.getRGB();
+
+    // return the percentage components
+    return {
+      'r' : 100 * rgb.r / 255,
+      'g' : 100 * rgb.g / 255,
+      'b' : 100 * rgb.b / 255,
+      'a' : rgb.a
+    };
+
+  };
+
+  /* Returns a string representing this Colour as a CSS hexadecimal RGB colour
+   * value - that is, a string of the form #RRGGBB where each of RR, GG, and BB
+   * are two-digit hexadecimal numbers.
+   */
+  this.getCSSHexadecimalRGB = function(){
+
+    // get the integer RGB components
+    var rgb = this.getIntegerRGB();
+
+    // determine the hexadecimal equivalents
+    var r16 = rgb.r.toString(16);
+    var g16 = rgb.g.toString(16);
+    var b16 = rgb.b.toString(16);
+
+    // return the CSS RGB colour value
+    return '#'
+        + (r16.length == 2 ? r16 : '0' + r16)
+        + (g16.length == 2 ? g16 : '0' + g16)
+        + (b16.length == 2 ? b16 : '0' + b16);
+
+  };
+
+  /* Returns a string representing this Colour as a CSS integer RGB colour
+   * value - that is, a string of the form rgb(r,g,b) where each of r, g, and b
+   * are integers in the range [0,255].
+   */
+  this.getCSSIntegerRGB = function(){
+
+    // get the integer RGB components
+    var rgb = this.getIntegerRGB();
+
+    // return the CSS RGB colour value
+    return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
+
+  };
+
+  /* Returns a string representing this Colour as a CSS integer RGBA colour
+   * value - that is, a string of the form rgba(r,g,b,a) where each of r, g, and
+   * b are integers in the range [0,255] and a is in the range [0,1].
+   */
+  this.getCSSIntegerRGBA = function(){
+
+    // get the integer RGB components
+    var rgb = this.getIntegerRGB();
+
+    // return the CSS integer RGBA colour value
+    return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')';
+
+  };
+
+  /* Returns a string representing this Colour as a CSS percentage RGB colour
+   * value - that is, a string of the form rgb(r%,g%,b%) where each of r, g, and
+   * b are in the range [0,100].
+   */
+  this.getCSSPercentageRGB = function(){
+
+    // get the percentage RGB components
+    var rgb = this.getPercentageRGB();
+
+    // return the CSS RGB colour value
+    return 'rgb(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%)';
+
+  };
+
+  /* Returns a string representing this Colour as a CSS percentage RGBA colour
+   * value - that is, a string of the form rgba(r%,g%,b%,a) where each of r, g,
+   * and b are in the range [0,100] and a is in the range [0,1].
+   */
+  this.getCSSPercentageRGBA = function(){
+
+    // get the percentage RGB components
+    var rgb = this.getPercentageRGB();
+
+    // return the CSS percentage RGBA colour value
+    return 'rgb(' + rgb.r + '%,' + rgb.g + '%,' + rgb.b + '%,' + rgb.a + ')';
+
+  };
+
+  /* Returns a string representing this Colour as a CSS HSL colour value - that
+   * is, a string of the form hsl(h,s%,l%) where h is in the range [0,100] and
+   * s and l are in the range [0,100].
+   */
+  this.getCSSHSL = function(){
+
+    // get the HSL components
+    var hsl = this.getHSL();
+
+    // return the CSS HSL colour value
+    return 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%)';
+
+  };
+
+  /* Returns a string representing this Colour as a CSS HSLA colour value - that
+   * is, a string of the form hsla(h,s%,l%,a) where h is in the range [0,100],
+   * s and l are in the range [0,100], and a is in the range [0,1].
+   */
+  this.getCSSHSLA = function(){
+
+    // get the HSL components
+    var hsl = this.getHSL();
+
+    // return the CSS HSL colour value
+    return 'hsl(' + hsl.h + ',' + hsl.s + '%,' + hsl.l + '%,' + hsl.a + ')';
+
+  };
+
+  /* Sets the colour of the specified node to this Colour. This functions sets
+   * the CSS 'color' property for the node. The parameter is:
+   *
+   * node - the node whose colour should be set
+   */
+  this.setNodeColour = function(node){
+
+    // set the colour of the node
+    node.style.color = this.getCSSHexadecimalRGB();
+
+  };
+
+  /* Sets the background colour of the specified node to this Colour. This
+   * functions sets the CSS 'background-color' property for the node. The
+   * parameter is:
+   *
+   * node - the node whose background colour should be set
+   */
+  this.setNodeBackgroundColour = function(node){
+
+    // set the background colour of the node
+    node.style.backgroundColor = this.getCSSHexadecimalRGB();
+
+  };
+
+}
+
+
+/* Creates a colour specified in the RGB colour space, with an optional alpha
+ * component. The parameters are:
+ *
+ * r - the red component, clipped to the range [0,255]
+ * g - the green component, clipped to the range [0,255]
+ * b - the blue component, clipped to the range [0,255]
+ * a - the alpha component, clipped to the range [0,1] - this parameter is
+ *     optional and defaults to 1
+ */
+Roo.lib.RGBColour = function (r, g, b, a){
+
+  // store the alpha component after clipping it if necessary
+  var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
+
+  // store the RGB components after clipping them if necessary
+  var rgb =
+      {
+        'r' : Math.max(0, Math.min(255, r)),
+        'g' : Math.max(0, Math.min(255, g)),
+        'b' : Math.max(0, Math.min(255, b))
+      };
+
+  // initialise the HSV and HSL components to null
+  var hsv = null;
+  var hsl = null;
+
+  /* Returns the HSV or HSL hue component of this RGBColour. The hue is in the
+   * range [0,360). The parameters are:
+   *
+   * maximum - the maximum of the RGB component values
+   * range   - the range of the RGB component values
+   */
+  function getHue(maximum, range){
+
+    // check whether the range is zero
+    if (range == 0){
+
+      // set the hue to zero (any hue is acceptable as the colour is grey)
+      var hue = 0;
+
+    }else{
+
+      // determine which of the components has the highest value and set the hue
+      switch (maximum){
+
+        // red has the highest value
+        case rgb.r:
+          var hue = (rgb.g - rgb.b) / range * 60;
+          if (hue < 0) hue += 360;
+          break;
+
+        // green has the highest value
+        case rgb.g:
+          var hue = (rgb.b - rgb.r) / range * 60 + 120;
+          break;
+
+        // blue has the highest value
+        case rgb.b:
+          var hue = (rgb.r - rgb.g) / range * 60 + 240;
+          break;
+
+      }
+
+    }
+
+    // return the hue
+    return hue;
+
+  }
+
+  /* Calculates and stores the HSV components of this RGBColour so that they can
+   * be returned be the getHSV function.
+   */
+  function calculateHSV(){
+
+    // get the maximum and range of the RGB component values
+    var maximum = Math.max(rgb.r, rgb.g, rgb.b);
+    var range   = maximum - Math.min(rgb.r, rgb.g, rgb.b);
+
+    // store the HSV components
+    hsv =
+        {
+          'h' : getHue(maximum, range),
+          's' : (maximum == 0 ? 0 : 100 * range / maximum),
+          'v' : maximum / 2.55
+        };
+
+  }
+
+  /* Calculates and stores the HSL components of this RGBColour so that they can
+   * be returned be the getHSL function.
+   */
+  function calculateHSL(){
+
+    // get the maximum and range of the RGB component values
+    var maximum = Math.max(rgb.r, rgb.g, rgb.b);
+    var range   = maximum - Math.min(rgb.r, rgb.g, rgb.b);
+
+    // determine the lightness in the range [0,1]
+    var l = maximum / 255 - range / 510;
+
+    // store the HSL components
+    hsl =
+        {
+          'h' : getHue(maximum, range),
+          's' : (range == 0 ? 0 : range / 2.55 / (l < 0.5 ? l * 2 : 2 - l * 2)),
+          'l' : 100 * l
+        };
+
+  }
+
+  /* Returns the RGB and alpha components of this RGBColour as an object with r,
+   * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
+   * the range [0,1].
+   */
+  this.getRGB = function(){
+
+    // return the RGB components
+    return {
+      'r' : rgb.r,
+      'g' : rgb.g,
+      'b' : rgb.b,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSV and alpha components of this RGBColour as an object with h,
+   * s, v, and a properties. h is in the range [0,360), s and v are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSV = function(){
+
+    // calculate the HSV components if necessary
+    if (hsv == null) calculateHSV();
+
+    // return the HSV components
+    return {
+      'h' : hsv.h,
+      's' : hsv.s,
+      'v' : hsv.v,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSL and alpha components of this RGBColour as an object with h,
+   * s, l, and a properties. h is in the range [0,360), s and l are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSL = function(){
+
+    // calculate the HSV components if necessary
+    if (hsl == null) calculateHSL();
+
+    // return the HSL components
+    return {
+      'h' : hsl.h,
+      's' : hsl.s,
+      'l' : hsl.l,
+      'a' : alpha
+    };
+
+  };
+
+}
+Roo.lib.RGBColour.prototype = new Colour();
+
+
+/* Creates a colour specified in the HSV colour space, with an optional alpha
+ * component. The parameters are:
+ *
+ * h - the hue component, wrapped to the range [0,360)
+ * s - the saturation component, clipped to the range [0,100]
+ * v - the value component, clipped to the range [0,100]
+ * a - the alpha component, clipped to the range [0,1] - this parameter is
+ *     optional and defaults to 1
+ */
+HSVColour.prototype = new Colour();
+function HSVColour(h, s, v, a){
+
+  // store the alpha component after clipping it if necessary
+  var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
+
+  // store the HSV components after clipping or wrapping them if necessary
+  var hsv =
+      {
+        'h' : (h % 360 + 360) % 360,
+        's' : Math.max(0, Math.min(100, s)),
+        'v' : Math.max(0, Math.min(100, v))
+      };
+
+  // initialise the RGB and HSL components to null
+  var rgb = null;
+  var hsl = null;
+
+  /* Calculates and stores the RGB components of this HSVColour so that they can
+   * be returned be the getRGB function.
+   */
+  function calculateRGB(){
+
+    // check whether the saturation is zero
+    if (hsv.s == 0){
+
+      // set the colour to the appropriate shade of grey
+      var r = hsv.v;
+      var g = hsv.v;
+      var b = hsv.v;
+
+    }else{
+
+      // set some temporary values
+      var f  = hsv.h / 60 - Math.floor(hsv.h / 60);
+      var p  = hsv.v * (1 - hsv.s / 100);
+      var q  = hsv.v * (1 - hsv.s / 100 * f);
+      var t  = hsv.v * (1 - hsv.s / 100 * (1 - f));
+
+      // set the RGB colour components to their temporary values
+      switch (Math.floor(hsv.h / 60)){
+        case 0: var r = hsv.v; var g = t; var b = p; break;
+        case 1: var r = q; var g = hsv.v; var b = p; break;
+        case 2: var r = p; var g = hsv.v; var b = t; break;
+        case 3: var r = p; var g = q; var b = hsv.v; break;
+        case 4: var r = t; var g = p; var b = hsv.v; break;
+        case 5: var r = hsv.v; var g = p; var b = q; break;
+      }
+
+    }
+
+    // store the RGB components
+    rgb =
+        {
+          'r' : r * 2.55,
+          'g' : g * 2.55,
+          'b' : b * 2.55
+        };
+
+  }
+
+  /* Calculates and stores the HSL components of this HSVColour so that they can
+   * be returned be the getHSL function.
+   */
+  function calculateHSL(){
+
+    // determine the lightness in the range [0,100]
+    var l = (2 - hsv.s / 100) * hsv.v / 2;
+
+    // store the HSL components
+    hsl =
+        {
+          'h' : hsv.h,
+          's' : hsv.s * hsv.v / (l < 50 ? l * 2 : 200 - l * 2),
+          'l' : l
+        };
+
+    // correct a division-by-zero error
+    if (isNaN(hsl.s)) hsl.s = 0;
+
+  }
+
+  /* Returns the RGB and alpha components of this HSVColour as an object with r,
+   * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
+   * the range [0,1].
+   */
+  this.getRGB = function(){
+
+    // calculate the RGB components if necessary
+    if (rgb == null) calculateRGB();
+
+    // return the RGB components
+    return {
+      'r' : rgb.r,
+      'g' : rgb.g,
+      'b' : rgb.b,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSV and alpha components of this HSVColour as an object with h,
+   * s, v, and a properties. h is in the range [0,360), s and v are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSV = function(){
+
+    // return the HSV components
+    return {
+      'h' : hsv.h,
+      's' : hsv.s,
+      'v' : hsv.v,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSL and alpha components of this HSVColour as an object with h,
+   * s, l, and a properties. h is in the range [0,360), s and l are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSL = function(){
+
+    // calculate the HSL components if necessary
+    if (hsl == null) calculateHSL();
+
+    // return the HSL components
+    return {
+      'h' : hsl.h,
+      's' : hsl.s,
+      'l' : hsl.l,
+      'a' : alpha
+    };
+
+  };
+
+}
+
+
+/* Creates a colour specified in the HSL colour space, with an optional alpha
+ * component. The parameters are:
+ *
+ * h - the hue component, wrapped to the range [0,360)
+ * s - the saturation component, clipped to the range [0,100]
+ * l - the lightness component, clipped to the range [0,100]
+ * a - the alpha component, clipped to the range [0,1] - this parameter is
+ *     optional and defaults to 1
+ */
+HSLColour.prototype = new Colour();
+function HSLColour(h, s, l, a){
+
+  // store the alpha component after clipping it if necessary
+  var alpha = (a === undefined ? 1 : Math.max(0, Math.min(1, a)));
+
+  // store the HSL components after clipping or wrapping them if necessary
+  var hsl =
+      {
+        'h' : (h % 360 + 360) % 360,
+        's' : Math.max(0, Math.min(100, s)),
+        'l' : Math.max(0, Math.min(100, l))
+      };
+
+  // initialise the RGB and HSV components to null
+  var rgb = null;
+  var hsv = null;
+
+  /* Calculates and stores the RGB components of this HSLColour so that they can
+   * be returned be the getRGB function.
+   */
+  function calculateRGB(){
+
+    // check whether the saturation is zero
+    if (hsl.s == 0){
+
+      // store the RGB components representing the appropriate shade of grey
+      rgb =
+          {
+            'r' : hsl.l * 2.55,
+            'g' : hsl.l * 2.55,
+            'b' : hsl.l * 2.55
+          };
+
+    }else{
+
+      // set some temporary values
+      var p = hsl.l < 50
+            ? hsl.l * (1 + hsl.s / 100)
+            : hsl.l + hsl.s - hsl.l * hsl.s / 100;
+      var q = 2 * hsl.l - p;
+
+      // initialise the RGB components
+      rgb =
+          {
+            'r' : (h + 120) / 60 % 6,
+            'g' : h / 60,
+            'b' : (h + 240) / 60 % 6
+          };
+
+      // loop over the RGB components
+      for (var key in rgb){
+
+        // ensure that the property is not inherited from the root object
+        if (rgb.hasOwnProperty(key)){
+
+          // set the component to its value in the range [0,100]
+          if (rgb[key] < 1){
+            rgb[key] = q + (p - q) * rgb[key];
+          }else if (rgb[key] < 3){
+            rgb[key] = p;
+          }else if (rgb[key] < 4){
+            rgb[key] = q + (p - q) * (4 - rgb[key]);
+          }else{
+            rgb[key] = q;
+          }
+
+          // set the component to its value in the range [0,255]
+          rgb[key] *= 2.55;
+
+        }
+
+      }
+
+    }
+
+  }
+
+  /* Calculates and stores the HSV components of this HSLColour so that they can
+   * be returned be the getHSL function.
+   */
+  function calculateHSV(){
+
+    // set a temporary value
+    var t = hsl.s * (hsl.l < 50 ? hsl.l : 100 - hsl.l) / 100;
+
+    // store the HSV components
+    hsv =
+        {
+          'h' : hsl.h,
+          's' : 200 * t / (hsl.l + t),
+          'v' : t + hsl.l
+        };
+
+    // correct a division-by-zero error
+    if (isNaN(hsv.s)) hsv.s = 0;
+
+  }
+
+  /* Returns the RGB and alpha components of this HSLColour as an object with r,
+   * g, b, and a properties. r, g, and b are in the range [0,255] and a is in
+   * the range [0,1].
+   */
+  this.getRGB = function(){
+
+    // calculate the RGB components if necessary
+    if (rgb == null) calculateRGB();
+
+    // return the RGB components
+    return {
+      'r' : rgb.r,
+      'g' : rgb.g,
+      'b' : rgb.b,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSV and alpha components of this HSLColour as an object with h,
+   * s, v, and a properties. h is in the range [0,360), s and v are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSV = function(){
+
+    // calculate the HSV components if necessary
+    if (hsv == null) calculateHSV();
+
+    // return the HSV components
+    return {
+      'h' : hsv.h,
+      's' : hsv.s,
+      'v' : hsv.v,
+      'a' : alpha
+    };
+
+  };
+
+  /* Returns the HSL and alpha components of this HSLColour as an object with h,
+   * s, l, and a properties. h is in the range [0,360), s and l are in the range
+   * [0,100], and a is in the range [0,1].
+   */
+  this.getHSL = function(){
+
+    // return the HSL components
+    return {
+      'h' : hsl.h,
+      's' : hsl.s,
+      'l' : hsl.l,
+      'a' : alpha
+    };
+
+  };
+
+}
\ No newline at end of file