JAVASCRIPT 29
Color.js Guest on 22nd April 2021 01:09:42 AM
  1. /*
  2.  
  3. This file is part of Ext JS 4
  4.  
  5. Copyright (c) 2011 Sencha Inc
  6.  
  7. Contact:  http://www.sencha.com/contact
  8.  
  9. GNU General Public License Usage
  10. This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
  11.  
  12. If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
  13.  
  14. */
  15. /**
  16.  * Represents an RGB color and provides helper functions get
  17.  * color components in HSL color space.
  18.  */
  19. Ext.define('Ext.draw.Color', {
  20.  
  21.     /* Begin Definitions */
  22.  
  23.     /* End Definitions */
  24.  
  25.     colorToHexRe: /(.*?)rgb\((\d+),\s*(\d+),\s*(\d+)\)/,
  26.     rgbRe: /\s*rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*/,
  27.     hexRe: /\s*#([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)\s*/,
  28.  
  29.     /**
  30.      * @cfg {Number} lightnessFactor
  31.      *
  32.      * The default factor to compute the lighter or darker color. Defaults to 0.2.
  33.      */
  34.     lightnessFactor: 0.2,
  35.  
  36.     /**
  37.      * Creates new Color.
  38.      * @param {Number} red Red component (0..255)
  39.      * @param {Number} green Green component (0..255)
  40.      * @param {Number} blue Blue component (0..255)
  41.      */
  42.     constructor : function(red, green, blue) {
  43.         var me = this,
  44.             clamp = Ext.Number.constrain;
  45.         me.r = clamp(red, 0, 255);
  46.         me.g = clamp(green, 0, 255);
  47.         me.b = clamp(blue, 0, 255);
  48.     },
  49.  
  50.     /**
  51.      * Get the red component of the color, in the range 0..255.
  52.      * @return {Number}
  53.      */
  54.     getRed: function() {
  55.         return this.r;
  56.     },
  57.  
  58.     /**
  59.      * Get the green component of the color, in the range 0..255.
  60.      * @return {Number}
  61.      */
  62.     getGreen: function() {
  63.         return this.g;
  64.     },
  65.  
  66.     /**
  67.      * Get the blue component of the color, in the range 0..255.
  68.      * @return {Number}
  69.      */
  70.     getBlue: function() {
  71.         return this.b;
  72.     },
  73.  
  74.     /**
  75.      * Get the RGB values.
  76.      * @return {Number[]}
  77.      */
  78.     getRGB: function() {
  79.         var me = this;
  80.         return [me.r, me.g, me.b];
  81.     },
  82.  
  83.     /**
  84.      * Get the equivalent HSL components of the color.
  85.      * @return {Number[]}
  86.      */
  87.     getHSL: function() {
  88.         var me = this,
  89.             r = me.r / 255,
  90.             g = me.g / 255,
  91.             b = me.b / 255,
  92.             max = Math.max(r, g, b),
  93.             min = Math.min(r, g, b),
  94.             delta = max - min,
  95.             h,
  96.             s = 0,
  97.             l = 0.5 * (max + min);
  98.  
  99.         // min==max means achromatic (hue is undefined)
  100.         if (min != max) {
  101.             s = (l < 0.5) ? delta / (max + min) : delta / (2 - max - min);
  102.             if (r == max) {
  103.                 h = 60 * (g - b) / delta;
  104.             } else if (g == max) {
  105.                 h = 120 + 60 * (b - r) / delta;
  106.             } else {
  107.                 h = 240 + 60 * (r - g) / delta;
  108.             }
  109.             if (h < 0) {
  110.                 h += 360;
  111.             }
  112.             if (h >= 360) {
  113.                 h -= 360;
  114.             }
  115.         }
  116.         return [h, s, l];
  117.     },
  118.  
  119.     /**
  120.      * Return a new color that is lighter than this color.
  121.      * @param {Number} factor Lighter factor (0..1), default to 0.2
  122.      * @return Ext.draw.Color
  123.      */
  124.     getLighter: function(factor) {
  125.         var hsl = this.getHSL();
  126.         factor = factor || this.lightnessFactor;
  127.         hsl[2] = Ext.Number.constrain(hsl[2] + factor, 0, 1);
  128.         return this.fromHSL(hsl[0], hsl[1], hsl[2]);
  129.     },
  130.  
  131.     /**
  132.      * Return a new color that is darker than this color.
  133.      * @param {Number} factor Darker factor (0..1), default to 0.2
  134.      * @return Ext.draw.Color
  135.      */
  136.     getDarker: function(factor) {
  137.         factor = factor || this.lightnessFactor;
  138.         return this.getLighter(-factor);
  139.     },
  140.  
  141.     /**
  142.      * Return the color in the hex format, i.e. '#rrggbb'.
  143.      * @return {String}
  144.      */
  145.     toString: function() {
  146.         var me = this,
  147.             round = Math.round,
  148.             r = round(me.r).toString(16),
  149.             g = round(me.g).toString(16),
  150.             b = round(me.b).toString(16);
  151.         r = (r.length == 1) ? '0' + r : r;
  152.         g = (g.length == 1) ? '0' + g : g;
  153.         b = (b.length == 1) ? '0' + b : b;
  154.         return ['#', r, g, b].join('');
  155.     },
  156.  
  157.     /**
  158.      * Convert a color to hexadecimal format.
  159.      *
  160.      * **Note:** This method is both static and instance.
  161.      *
  162.      * @param {String/String[]} color The color value (i.e 'rgb(255, 255, 255)', 'color: #ffffff').
  163.      * Can also be an Array, in this case the function handles the first member.
  164.      * @returns {String} The color in hexadecimal format.
  165.      * @static
  166.      */
  167.     toHex: function(color) {
  168.         if (Ext.isArray(color)) {
  169.             color = color[0];
  170.         }
  171.         if (!Ext.isString(color)) {
  172.             return '';
  173.         }
  174.         if (color.substr(0, 1) === '#') {
  175.             return color;
  176.         }
  177.         var digits = this.colorToHexRe.exec(color);
  178.  
  179.         if (Ext.isArray(digits)) {
  180.             var red = parseInt(digits[2], 10),
  181.                 green = parseInt(digits[3], 10),
  182.                 blue = parseInt(digits[4], 10),
  183.                 rgb = blue | (green << 8) | (red << 16);
  184.             return digits[1] + '#' + ("000000" + rgb.toString(16)).slice(-6);
  185.         }
  186.         else {
  187.             return '';
  188.         }
  189.     },
  190.  
  191.     /**
  192.      * Parse the string and create a new color.
  193.      *
  194.      * Supported formats: '#rrggbb', '#rgb', and 'rgb(r,g,b)'.
  195.      *
  196.      * If the string is not recognized, an undefined will be returned instead.
  197.      *
  198.      * **Note:** This method is both static and instance.
  199.      *
  200.      * @param {String} str Color in string.
  201.      * @returns Ext.draw.Color
  202.      * @static
  203.      */
  204.     fromString: function(str) {
  205.         var values, r, g, b,
  206.             parse = parseInt;
  207.  
  208.         if ((str.length == 4 || str.length == 7) && str.substr(0, 1) === '#') {
  209.             values = str.match(this.hexRe);
  210.             if (values) {
  211.                 r = parse(values[1], 16) >> 0;
  212.                 g = parse(values[2], 16) >> 0;
  213.                 b = parse(values[3], 16) >> 0;
  214.                 if (str.length == 4) {
  215.                     r += (r * 16);
  216.                     g += (g * 16);
  217.                     b += (b * 16);
  218.                 }
  219.             }
  220.         }
  221.         else {
  222.             values = str.match(this.rgbRe);
  223.             if (values) {
  224.                 r = values[1];
  225.                 g = values[2];
  226.                 b = values[3];
  227.             }
  228.         }
  229.  
  230.         return (typeof r == 'undefined') ? undefined : Ext.create('Ext.draw.Color', r, g, b);
  231.     },
  232.  
  233.     /**
  234.      * Returns the gray value (0 to 255) of the color.
  235.      *
  236.      * The gray value is calculated using the formula r*0.3 + g*0.59 + b*0.11.
  237.      *
  238.      * @returns {Number}
  239.      */
  240.     getGrayscale: function() {
  241.         // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
  242.         return this.r * 0.3 + this.g * 0.59 + this.b * 0.11;
  243.     },
  244.  
  245.     /**
  246.      * Create a new color based on the specified HSL values.
  247.      *
  248.      * **Note:** This method is both static and instance.
  249.      *
  250.      * @param {Number} h Hue component (0..359)
  251.      * @param {Number} s Saturation component (0..1)
  252.      * @param {Number} l Lightness component (0..1)
  253.      * @returns Ext.draw.Color
  254.      * @static
  255.      */
  256.     fromHSL: function(h, s, l) {
  257.         var C, X, m, i, rgb = [],
  258.             abs = Math.abs,
  259.             floor = Math.floor;
  260.  
  261.         if (s == 0 || h == null) {
  262.             // achromatic
  263.             rgb = [l, l, l];
  264.         }
  265.         else {
  266.             // http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSL
  267.             // C is the chroma
  268.             // X is the second largest component
  269.             // m is the lightness adjustment
  270.             h /= 60;
  271.             C = s * (1 - abs(2 * l - 1));
  272.             X = C * (1 - abs(h - 2 * floor(h / 2) - 1));
  273.             m = l - C / 2;
  274.             switch (floor(h)) {
  275.                 case 0:
  276.                     rgb = [C, X, 0];
  277.                     break;
  278.                 case 1:
  279.                     rgb = [X, C, 0];
  280.                     break;
  281.                 case 2:
  282.                     rgb = [0, C, X];
  283.                     break;
  284.                 case 3:
  285.                     rgb = [0, X, C];
  286.                     break;
  287.                 case 4:
  288.                     rgb = [X, 0, C];
  289.                     break;
  290.                 case 5:
  291.                     rgb = [C, 0, X];
  292.                     break;
  293.             }
  294.             rgb = [rgb[0] + m, rgb[1] + m, rgb[2] + m];
  295.         }
  296.         return Ext.create('Ext.draw.Color', rgb[0] * 255, rgb[1] * 255, rgb[2] * 255);
  297.     }
  298. }, function() {
  299.     var prototype = this.prototype;
  300.  
  301.     //These functions are both static and instance. TODO: find a more elegant way of copying them
  302.     this.addStatics({
  303.         fromHSL: function() {
  304.             return prototype.fromHSL.apply(prototype, arguments);
  305.         },
  306.         fromString: function() {
  307.             return prototype.fromString.apply(prototype, arguments);
  308.         },
  309.         toHex: function() {
  310.             return prototype.toHex.apply(prototype, arguments);
  311.         }
  312.     });
  313. });

Paste-bin is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.