colorHelper.js

  1. // @formatter:off
  2. /**
  3. * Definition of CSS color names
  4. * @type {Array}
  5. */
  6. const colorNames = {
  7. aliceblue: "#f0f8ff", antiquewhite: "#faebd7", aqua: "#00ffff",
  8. aquamarine: "#7fffd4", azure: "#f0ffff", beige: "#f5f5dc",
  9. bisque: "#ffe4c4", black: "#000000", blanchedalmond: "#ffebcd",
  10. blue: "#0000ff", blueviolet: "#8a2be2", brown: "#a52a2a",
  11. burlywood: "#deb887", cadetblue: "#5f9ea0", chartreuse: "#7fff00",
  12. chocolate: "#d2691e", coral: "#ff7f50", cornflowerblue: "#6495ed",
  13. cornsilk: "#fff8dc", crimson: "#dc143c", cyan: "#00ffff",
  14. darkblue: "#00008b", darkcyan: "#008b8b", darkgoldenrod: "#b8860b",
  15. darkgray: "#a9a9a9", darkgreen: "#006400", darkkhaki: "#bdb76b",
  16. darkmagenta: "#8b008b", darkolivegreen: "#556b2f", darkorange: "#ff8c00",
  17. darkorchid: "#9932cc", darkred: "#8b0000", darksalmon: "#e9967a",
  18. darkseagreen: "#8fbc8f", darkslateblue: "#483d8b", darkslategray: "#2f4f4f",
  19. darkturquoise: "#00ced1", darkviolet: "#9400d3", deeppink: "#ff1493",
  20. deepskyblue: "#00bfff", dimgray: "#696969", dodgerblue: "#1e90ff",
  21. feldspar: "#d19275", firebrick: "#b22222", floralwhite: "#fffaf0",
  22. forestgreen: "#228b22", fuchsia: "#ff00ff", gainsboro: "#dcdcdc",
  23. ghostwhite: "#f8f8ff", gold: "#ffd700", goldenrod: "#daa520",
  24. gray: "#808080", green: "#008000", greenyellow: "#adff2f",
  25. honeydew: "#f0fff0", hotpink: "#ff69b4", indianred : "#cd5c5c",
  26. indigo : "#4b0082", ivory: "#fffff0", khaki: "#f0e68c",
  27. lavender: "#e6e6fa", lavenderblush: "#fff0f5", lawngreen: "#7cfc00",
  28. lemonchiffon: "#fffacd", lightblue: "#add8e6", lightcoral: "#f08080",
  29. lightcyan: "#e0ffff", lightgoldenrodyellow: "#fafad2", lightgrey: "#d3d3d3",
  30. lightgreen: "#90ee90", lightpink: "#ffb6c1", lightsalmon: "#ffa07a",
  31. lightseagreen: "#20b2aa", lightskyblue: "#87cefa", lightslateblue: "#8470ff",
  32. lightslategray: "#778899", lightsteelblue: "#b0c4de", lightyellow: "#ffffe0",
  33. lime: "#00ff00", limegreen: "#32cd32", linen: "#faf0e6",
  34. magenta: "#ff00ff", maroon: "#800000", mediumaquamarine: "#66cdaa",
  35. mediumblue: "#0000cd", mediumorchid: "#ba55d3", mediumpurple: "#9370d8",
  36. mediumseagreen: "#3cb371", mediumslateblue: "#7b68ee", mediumspringgreen: "#00fa9a",
  37. mediumturquoise: "#48d1cc", mediumvioletred: "#c71585", midnightblue: "#191970",
  38. mintcream: "#f5fffa", mistyrose: "#ffe4e1", moccasin: "#ffe4b5",
  39. navajowhite: "#ffdead", navy: "#000080", oldlace: "#fdf5e6",
  40. olive: "#808000", olivedrab: "#6b8e23", orange: "#ffa500",
  41. orangered: "#ff4500", orchid: "#da70d6", palegoldenrod: "#eee8aa",
  42. palegreen: "#98fb98", paleturquoise: "#afeeee", palevioletred: "#d87093",
  43. papayawhip: "#ffefd5", peachpuff: "#ffdab9", peru: "#cd853f",
  44. pink: "#ffc0cb", plum: "#dda0dd", powderblue: "#b0e0e6",
  45. purple: "#800080", red: "#ff0000", rosybrown: "#bc8f8f",
  46. royalblue: "#4169e1", saddlebrown: "#8b4513", salmon: "#fa8072",
  47. sandybrown: "#f4a460", seagreen: "#2e8b57", seashell: "#fff5ee",
  48. sienna: "#a0522d", silver: "#c0c0c0", skyblue: "#87ceeb",
  49. slateblue: "#6a5acd", slategray: "#708090", snow: "#fffafa",
  50. springgreen: "#00ff7f", steelblue: "#4682b4", tan: "#d2b48c",
  51. teal: "#008080", thistle: "#d8bfd8", tomato: "#ff6347",
  52. turquoise: "#40e0d0", violet: "#ee82ee", violetred: "#d02090",
  53. wheat: "#f5deb3", white: "#ffffff", whitesmoke: "#f5f5f5",
  54. yellow: "#ffff00", yellowgreen: "#9acd32"
  55. };
  56. // @formatter:on
  57. /**
  58. * Color Name to Hex
  59. *
  60. * @param {string} colorName
  61. * @returns {boolean|*}
  62. */
  63. function colourNameToHex(colorName) {
  64. if (typeof colorNames[colorName.toLowerCase()] !== "undefined") {
  65. return colorNames[colorName.toLowerCase()];
  66. }
  67. return false;
  68. }
  69. /**
  70. * Color Component to Hex
  71. *
  72. * @param {number} c
  73. * @returns {string}
  74. */
  75. function componentToHex(c) {
  76. const hex = c.toString(16);
  77. return hex.length === 1 ? "0" + hex : hex;
  78. }
  79. /**
  80. * Color RGB to Hex
  81. *
  82. * @param {number} r
  83. * @param {number} g
  84. * @param {number} b
  85. * @returns {string}
  86. */
  87. function rgbToHex(r, g, b) {
  88. return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
  89. }
  90. /**
  91. * RGB Colour to Hex Converter
  92. *
  93. * @param {string} rgbStr - RGB colour string (e.g. "rgb(155, 102, 102)").
  94. * @returns {string} - Hex Color (e.g. "#9b6666").
  95. */
  96. function rgb2Hex(rgbStr) {
  97. const [red, green, blue] = rgbStr.substring(4, rgbStr.length - 1).replace(/ /g, "").split(",");
  98. let rgb = blue | (green << 8) | (red << 16); // eslint-disable-line no-bitwise
  99. return "#" + (0x1000000 + rgb).toString(16).slice(1);
  100. }
  101. /**
  102. * Color Hex to RGB
  103. *
  104. * @param {string} hex
  105. * @returns {*}
  106. */
  107. function hexToRgb(hex) {
  108. const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  109. return result ? {
  110. r: parseInt(result[1], 16),
  111. g: parseInt(result[2], 16),
  112. b: parseInt(result[3], 16)
  113. } : null;
  114. }
  115. /**
  116. * Color Hex to X3D RGB
  117. *
  118. * @param {string} hex
  119. * @returns {string}
  120. */
  121. function hexToX3d(hex) {
  122. const rgb = hexToRgb(hex);
  123. return `${rgb.r / 255} ${rgb.g / 255} ${rgb.b / 255}`;
  124. }
  125. /**
  126. * Color Name to X3D RGB
  127. *
  128. * @param {string} colorName
  129. * @returns {string}
  130. */
  131. function colourNameToX3d(colorName) {
  132. const rgb = hexToRgb(colourNameToHex(colorName));
  133. return `${rgb.r / 255} ${rgb.g / 255} ${rgb.b / 255}`;
  134. }
  135. /**
  136. * X3D Color Parser
  137. *
  138. * @param {Rgb|Hsl|null} color
  139. * @returns {string}
  140. */
  141. export function colorParse(color) {
  142. let red = 0;
  143. let green = 0;
  144. let blue = 0;
  145. let alpha = 0;
  146. // Already matches X3D RGB
  147. const x3dMatch = /^(0+\.?\d*|1\.?0*)\s+(0+\.?\d*|1\.?0*)\s+(0+\.?\d*|1\.?0*)$/.exec(color);
  148. if (x3dMatch !== null) {
  149. red = +x3dMatch[1];
  150. green = +x3dMatch[2];
  151. blue = +x3dMatch[3];
  152. }
  153. // Matches CSS rgb() function
  154. const rgbMatch = /^rgb\((\d{1,3}),\s{0,1}(\d{1,3}),\s{0,1}(\d{1,3})\)$/.exec(color);
  155. if (rgbMatch !== null) {
  156. red = rgbMatch[1] / 255.0;
  157. green = rgbMatch[2] / 255.0;
  158. blue = rgbMatch[3] / 255.0;
  159. }
  160. // Matches CSS color name
  161. if (colorNames[color]) {
  162. color = colorNames[color];
  163. }
  164. // Hexadecimal color codes
  165. if (color.substr && color.substr(0, 1) === "#") {
  166. const hex = color.substr(1);
  167. const len = hex.length;
  168. if (len === 8) {
  169. red = parseInt("0x" + hex.substr(0, 2), 16) / 255.0;
  170. green = parseInt("0x" + hex.substr(2, 2), 16) / 255.0;
  171. blue = parseInt("0x" + hex.substr(4, 2), 16) / 255.0;
  172. alpha = parseInt("0x" + hex.substr(6, 2), 16) / 255.0;
  173. } else if (len === 6) {
  174. red = parseInt("0x" + hex.substr(0, 2), 16) / 255.0;
  175. green = parseInt("0x" + hex.substr(2, 2), 16) / 255.0;
  176. blue = parseInt("0x" + hex.substr(4, 2), 16) / 255.0;
  177. alpha = 1.0;
  178. } else if (len === 4) {
  179. red = parseInt("0x" + hex.substr(0, 1), 16) / 15.0;
  180. green = parseInt("0x" + hex.substr(1, 1), 16) / 15.0;
  181. blue = parseInt("0x" + hex.substr(2, 1), 16) / 15.0;
  182. alpha = parseInt("0x" + hex.substr(3, 1), 16) / 15.0;
  183. } else if (len === 3) {
  184. red = parseInt("0x" + hex.substr(0, 1), 16) / 15.0;
  185. green = parseInt("0x" + hex.substr(1, 1), 16) / 15.0;
  186. blue = parseInt("0x" + hex.substr(2, 1), 16) / 15.0;
  187. alpha = 1.0;
  188. }
  189. }
  190. red = red.toFixed(4);
  191. green = green.toFixed(4);
  192. blue = blue.toFixed(4);
  193. return `${red} ${green} ${blue}`;
  194. }