PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/packages/closure-library/src/main/resources/com/github/urmuzov/closuremaven/closurelibrarypackage/javascript/goog/color/alpha.js

https://github.com/urmuzov/closure-maven
JavaScript | 467 lines | 174 code | 63 blank | 230 comment | 39 complexity | b125dbff1996aa44e57e6e9f195f0147 MD5 | raw file
  1. // Copyright 2006 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Utilities related to alpha/transparent colors and alpha color
  16. * conversion.
  17. */
  18. goog.provide('goog.color.alpha');
  19. goog.require('goog.color');
  20. /**
  21. * Parses an alpha color out of a string.
  22. * @param {string} str Color in some format.
  23. * @return {Object} Contains two properties: 'hex', which is a string containing
  24. * a hex representation of the color, as well as 'type', which is a string
  25. * containing the type of color format passed in ('hex', 'rgb', 'named').
  26. */
  27. goog.color.alpha.parse = function(str) {
  28. var result = {};
  29. str = String(str);
  30. var maybeHex = goog.color.prependHashIfNecessaryHelper(str);
  31. if (goog.color.alpha.isValidAlphaHexColor_(maybeHex)) {
  32. result.hex = goog.color.alpha.normalizeAlphaHex_(maybeHex);
  33. result.type = 'hex';
  34. return result;
  35. } else {
  36. var rgba = goog.color.alpha.isValidRgbaColor_(str);
  37. if (rgba.length) {
  38. result.hex = goog.color.alpha.rgbaArrayToHex(rgba);
  39. result.type = 'rgba';
  40. return result;
  41. } else {
  42. var hsla = goog.color.alpha.isValidHslaColor_(str);
  43. if (hsla.length) {
  44. result.hex = goog.color.alpha.hslaArrayToHex(hsla);
  45. result.type = 'hsla';
  46. return result;
  47. }
  48. }
  49. }
  50. throw Error(str + ' is not a valid color string');
  51. };
  52. /**
  53. * Converts a hex representation of a color to RGBA.
  54. * @param {string} hexColor Color to convert.
  55. * @return {string} string of the form 'rgba(R,G,B,A)' which can be used in
  56. * styles.
  57. */
  58. goog.color.alpha.hexToRgbaStyle = function(hexColor) {
  59. return goog.color.alpha.rgbaStyle_(goog.color.alpha.hexToRgba(hexColor));
  60. };
  61. /**
  62. * Gets the hex color part of an alpha hex color. For example, from '#abcdef55'
  63. * return '#abcdef'.
  64. * @param {string} colorWithAlpha The alpha hex color to get the hex color from.
  65. * @return {string} The hex color where the alpha part has been stripped off.
  66. */
  67. goog.color.alpha.extractHexColor = function(colorWithAlpha) {
  68. if (goog.color.alpha.isValidAlphaHexColor_(colorWithAlpha)) {
  69. var fullColor = goog.color.prependHashIfNecessaryHelper(colorWithAlpha);
  70. var normalizedColor = goog.color.alpha.normalizeAlphaHex_(fullColor);
  71. return normalizedColor.substring(0, 7);
  72. } else {
  73. throw Error(colorWithAlpha + ' is not a valid 8-hex color string');
  74. }
  75. };
  76. /**
  77. * Gets the alpha color part of an alpha hex color. For example, from
  78. * '#abcdef55' return '55'. The result is guaranteed to be two characters long.
  79. * @param {string} colorWithAlpha The alpha hex color to get the hex color from.
  80. * @return {string} The hex color where the alpha part has been stripped off.
  81. */
  82. goog.color.alpha.extractAlpha = function(colorWithAlpha) {
  83. if (goog.color.alpha.isValidAlphaHexColor_(colorWithAlpha)) {
  84. var fullColor = goog.color.prependHashIfNecessaryHelper(colorWithAlpha);
  85. var normalizedColor = goog.color.alpha.normalizeAlphaHex_(fullColor);
  86. return normalizedColor.substring(7, 9);
  87. } else {
  88. throw Error(colorWithAlpha + ' is not a valid 8-hex color string');
  89. }
  90. };
  91. /**
  92. * Regular expression for extracting the digits in a hex color quadruplet.
  93. * @type {RegExp}
  94. * @private
  95. */
  96. goog.color.alpha.hexQuadrupletRe_ = /#(.)(.)(.)(.)/;
  97. /**
  98. * Normalize a hex representation of an alpha color.
  99. * @param {string} hexColor an alpha hex color string.
  100. * @return {string} hex color in the format '#rrggbbaa' with all lowercase
  101. * literals.
  102. * @private
  103. */
  104. goog.color.alpha.normalizeAlphaHex_ = function(hexColor) {
  105. if (!goog.color.alpha.isValidAlphaHexColor_(hexColor)) {
  106. throw Error("'" + hexColor + "' is not a valid alpha hex color");
  107. }
  108. if (hexColor.length == 5) { // of the form #RGBA
  109. hexColor = hexColor.replace(goog.color.alpha.hexQuadrupletRe_,
  110. '#$1$1$2$2$3$3$4$4');
  111. }
  112. return hexColor.toLowerCase();
  113. };
  114. /**
  115. * Converts an 8-hex representation of a color to RGBA.
  116. * @param {string} hexColor Color to convert.
  117. * @return {Array} array containing [r, g, b] as ints in [0, 255].
  118. */
  119. goog.color.alpha.hexToRgba = function(hexColor) {
  120. // TODO(user): Enhance code sharing with goog.color, for example by
  121. // adding a goog.color.genericHexToRgb method.
  122. hexColor = goog.color.alpha.normalizeAlphaHex_(hexColor);
  123. var r = parseInt(hexColor.substr(1, 2), 16);
  124. var g = parseInt(hexColor.substr(3, 2), 16);
  125. var b = parseInt(hexColor.substr(5, 2), 16);
  126. var a = parseInt(hexColor.substr(7, 2), 16);
  127. return [r, g, b, a / 255];
  128. };
  129. /**
  130. * Converts a color from RGBA to hex representation.
  131. * @param {number} r Amount of red, int between 0 and 255.
  132. * @param {number} g Amount of green, int between 0 and 255.
  133. * @param {number} b Amount of blue, int between 0 and 255.
  134. * @param {number} a Amount of alpha, float between 0 and 1.
  135. * @return {string} hex representation of the color.
  136. */
  137. goog.color.alpha.rgbaToHex = function(r, g, b, a) {
  138. var intAlpha = Math.floor(a * 255);
  139. if (isNaN(intAlpha) || intAlpha < 0 || intAlpha > 255) {
  140. // TODO(user): The CSS spec says the value should be clamped.
  141. throw Error('"(' + r + ',' + g + ',' + b + ',' + a +
  142. '") is not a valid RGBA color');
  143. }
  144. var hexA = goog.color.prependZeroIfNecessaryHelper(intAlpha.toString(16));
  145. return goog.color.rgbToHex(r, g, b) + hexA;
  146. };
  147. /**
  148. * Converts a color from HSLA to hex representation.
  149. * @param {number} h Amount of hue, int between 0 and 360.
  150. * @param {number} s Amount of saturation, int between 0 and 100.
  151. * @param {number} l Amount of lightness, int between 0 and 100.
  152. * @param {number} a Amount of alpha, float between 0 and 1.
  153. * @return {string} hex representation of the color.
  154. */
  155. goog.color.alpha.hslaToHex = function(h, s, l, a) {
  156. var intAlpha = Math.floor(a * 255);
  157. if (isNaN(intAlpha) || intAlpha < 0 || intAlpha > 255) {
  158. // TODO(user): The CSS spec says the value should be clamped.
  159. throw Error('"(' + h + ',' + s + ',' + l + ',' + a +
  160. '") is not a valid HSLA color');
  161. }
  162. var hexA = goog.color.prependZeroIfNecessaryHelper(intAlpha.toString(16));
  163. return goog.color.hslToHex(h, s / 100, l / 100) + hexA;
  164. };
  165. /**
  166. * Converts a color from RGBA to hex representation.
  167. * @param {Array.<number>} rgba Array of [r, g, b, a], with r, g, b in [0, 255]
  168. * and a in [0, 1].
  169. * @return {string} hex representation of the color.
  170. */
  171. goog.color.alpha.rgbaArrayToHex = function(rgba) {
  172. return goog.color.alpha.rgbaToHex(rgba[0], rgba[1], rgba[2], rgba[3]);
  173. };
  174. /**
  175. * Converts a color from RGBA to an RGBA style string.
  176. * @param {number} r Value of red, in [0, 255].
  177. * @param {number} g Value of green, in [0, 255].
  178. * @param {number} b Value of blue, in [0, 255].
  179. * @param {number} a Value of alpha, in [0, 1].
  180. * @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule.
  181. */
  182. goog.color.alpha.rgbaToRgbaStyle = function(r, g, b, a) {
  183. if (isNaN(r) || r < 0 || r > 255 ||
  184. isNaN(g) || g < 0 || g > 255 ||
  185. isNaN(b) || b < 0 || b > 255 ||
  186. isNaN(a) || a < 0 || a > 1) {
  187. throw Error('"(' + r + ',' + g + ',' + b + ',' + a +
  188. ')" is not a valid RGBA color');
  189. }
  190. return goog.color.alpha.rgbaStyle_([r, g, b, a]);
  191. };
  192. /**
  193. * Converts a color from RGBA to an RGBA style string.
  194. * @param {(Array.<number>|Float32Array)} rgba Array of [r, g, b, a],
  195. * with r, g, b in [0, 255] and a in [0, 1].
  196. * @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule.
  197. */
  198. goog.color.alpha.rgbaArrayToRgbaStyle = function(rgba) {
  199. return goog.color.alpha.rgbaToRgbaStyle(rgba[0], rgba[1], rgba[2], rgba[3]);
  200. };
  201. /**
  202. * Converts a color from HSLA to hex representation.
  203. * @param {Array.<number>} hsla Array of [h, s, l, a], where h is an integer in
  204. * [0, 360], s and l are integers in [0, 100], and a is in [0, 1].
  205. * @return {string} hex representation of the color, such as '#af457eff'.
  206. */
  207. goog.color.alpha.hslaArrayToHex = function(hsla) {
  208. return goog.color.alpha.hslaToHex(hsla[0], hsla[1], hsla[2], hsla[3]);
  209. };
  210. /**
  211. * Converts a color from HSLA to an RGBA style string.
  212. * @param {Array.<number>} hsla Array of [h, s, l, a], where h is and integer in
  213. * [0, 360], s and l are integers in [0, 100], and a is in [0, 1].
  214. * @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule.
  215. */
  216. goog.color.alpha.hslaArrayToRgbaStyle = function(hsla) {
  217. return goog.color.alpha.hslaToRgbaStyle(hsla[0], hsla[1], hsla[2], hsla[3]);
  218. };
  219. /**
  220. * Converts a color from HSLA to an RGBA style string.
  221. * @param {number} h Amount of hue, int between 0 and 360.
  222. * @param {number} s Amount of saturation, int between 0 and 100.
  223. * @param {number} l Amount of lightness, int between 0 and 100.
  224. * @param {number} a Amount of alpha, float between 0 and 1.
  225. * @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule.
  226. * styles.
  227. */
  228. goog.color.alpha.hslaToRgbaStyle = function(h, s, l, a) {
  229. return goog.color.alpha.rgbaStyle_(goog.color.alpha.hslaToRgba(h, s, l, a));
  230. };
  231. /**
  232. * Converts a color from HSLA color space to RGBA color space.
  233. * @param {number} h Amount of hue, int between 0 and 360.
  234. * @param {number} s Amount of saturation, int between 0 and 100.
  235. * @param {number} l Amount of lightness, int between 0 and 100.
  236. * @param {number} a Amount of alpha, float between 0 and 1.
  237. * @return {Array.<number>} [r, g, b, a] values for the color, where r, g, b
  238. * are integers in [0, 255] and a is a float in [0, 1].
  239. */
  240. goog.color.alpha.hslaToRgba = function(h, s, l, a) {
  241. return goog.color.hslToRgb(h, s / 100, l / 100).concat(a);
  242. };
  243. /**
  244. * Converts a color from RGBA color space to HSLA color space.
  245. * Modified from {@link http://en.wikipedia.org/wiki/HLS_color_space}.
  246. * @param {number} r Value of red, in [0, 255].
  247. * @param {number} g Value of green, in [0, 255].
  248. * @param {number} b Value of blue, in [0, 255].
  249. * @param {number} a Value of alpha, in [0, 255].
  250. * @return {Array.<number>} [h, s, l, a] values for the color, with h an int in
  251. * [0, 360] and s, l and a in [0, 1].
  252. */
  253. goog.color.alpha.rgbaToHsla = function(r, g, b, a) {
  254. return goog.color.rgbToHsl(r, g, b).concat(a);
  255. };
  256. /**
  257. * Converts a color from RGBA color space to HSLA color space.
  258. * @param {Array.<number>} rgba [r, g, b, a] values for the color, each in
  259. * [0, 255].
  260. * @return {Array.<number>} [h, s, l, a] values for the color, with h in
  261. * [0, 360] and s, l and a in [0, 1].
  262. */
  263. goog.color.alpha.rgbaArrayToHsla = function(rgba) {
  264. return goog.color.alpha.rgbaToHsla(rgba[0], rgba[1], rgba[2], rgba[3]);
  265. };
  266. /**
  267. * Helper for isValidAlphaHexColor_.
  268. * @type {RegExp}
  269. * @private
  270. */
  271. goog.color.alpha.validAlphaHexColorRe_ = /^#(?:[0-9a-f]{4}){1,2}$/i;
  272. /**
  273. * Checks if a string is a valid alpha hex color. We expect strings of the
  274. * format #RRGGBBAA (ex: #1b3d5f5b) or #RGBA (ex: #3CAF == #33CCAAFF).
  275. * @param {string} str String to check.
  276. * @return {boolean} Whether the string is a valid alpha hex color.
  277. * @private
  278. */
  279. // TODO(user): Support percentages when goog.color also supports them.
  280. goog.color.alpha.isValidAlphaHexColor_ = function(str) {
  281. return goog.color.alpha.validAlphaHexColorRe_.test(str);
  282. };
  283. /**
  284. * Helper for isNormalizedAlphaHexColor_.
  285. * @type {RegExp}
  286. * @private
  287. */
  288. goog.color.alpha.normalizedAlphaHexColorRe_ = /^#[0-9a-f]{8}$/;
  289. /**
  290. * Checks if a string is a normalized alpha hex color.
  291. * We expect strings of the format #RRGGBBAA (ex: #1b3d5f5b)
  292. * using only lowercase letters.
  293. * @param {string} str String to check.
  294. * @return {boolean} Whether the string is a normalized hex color.
  295. * @private
  296. */
  297. goog.color.alpha.isNormalizedAlphaHexColor_ = function(str) {
  298. return goog.color.alpha.normalizedAlphaHexColorRe_.test(str);
  299. };
  300. /**
  301. * Regular expression for matching and capturing RGBA style strings. Helper for
  302. * isValidRgbaColor_.
  303. * @type {RegExp}
  304. * @private
  305. */
  306. goog.color.alpha.rgbaColorRe_ =
  307. /^(?:rgba)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|1|0\.\d{0,10})\)$/i;
  308. /**
  309. * Regular expression for matching and capturing HSLA style strings. Helper for
  310. * isValidHslaColor_.
  311. * @type {RegExp}
  312. * @private
  313. */
  314. goog.color.alpha.hslaColorRe_ =
  315. /^(?:hsla)\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\%,\s?(0|[1-9]\d{0,2})\%,\s?(0|1|0\.\d{0,10})\)$/i;
  316. /**
  317. * Checks if a string is a valid rgba color. We expect strings of the format
  318. * '(r, g, b, a)', or 'rgba(r, g, b, a)', where r, g, b are ints in [0, 255]
  319. * and a is a float in [0, 1].
  320. * @param {string} str String to check.
  321. * @return {Array.<number>} the integers [r, g, b, a] for valid colors or the
  322. * empty array for invalid colors.
  323. * @private
  324. */
  325. goog.color.alpha.isValidRgbaColor_ = function(str) {
  326. // Each component is separate (rather than using a repeater) so we can
  327. // capture the match. Also, we explicitly set each component to be either 0,
  328. // or start with a non-zero, to prevent octal numbers from slipping through.
  329. var regExpResultArray = str.match(goog.color.alpha.rgbaColorRe_);
  330. if (regExpResultArray) {
  331. var r = Number(regExpResultArray[1]);
  332. var g = Number(regExpResultArray[2]);
  333. var b = Number(regExpResultArray[3]);
  334. var a = Number(regExpResultArray[4]);
  335. if (r >= 0 && r <= 255 &&
  336. g >= 0 && g <= 255 &&
  337. b >= 0 && b <= 255 &&
  338. a >= 0 && a <= 1) {
  339. return [r, g, b, a];
  340. }
  341. }
  342. return [];
  343. };
  344. /**
  345. * Checks if a string is a valid hsla color. We expect strings of the format
  346. * 'hsla(h, s, l, a)', where s in an int in [0, 360], s and l are percentages
  347. * between 0 and 100 such as '50%' or '70%', and a is a float in [0, 1].
  348. * @param {string} str String to check.
  349. * @return {Array.<number>} the integers [h, s, l, a] for valid colors or the
  350. * empty array for invalid colors.
  351. * @private
  352. */
  353. goog.color.alpha.isValidHslaColor_ = function(str) {
  354. // Each component is separate (rather than using a repeater) so we can
  355. // capture the match. Also, we explicitly set each component to be either 0,
  356. // or start with a non-zero, to prevent octal numbers from slipping through.
  357. var regExpResultArray = str.match(goog.color.alpha.hslaColorRe_);
  358. if (regExpResultArray) {
  359. var h = Number(regExpResultArray[1]);
  360. var s = Number(regExpResultArray[2]);
  361. var l = Number(regExpResultArray[3]);
  362. var a = Number(regExpResultArray[4]);
  363. if (h >= 0 && h <= 360 &&
  364. s >= 0 && s <= 100 &&
  365. l >= 0 && l <= 100 &&
  366. a >= 0 && a <= 1) {
  367. return [h, s, l, a];
  368. }
  369. }
  370. return [];
  371. };
  372. /**
  373. * Takes an array of [r, g, b, a] and converts it into a string appropriate for
  374. * CSS styles.
  375. * @param {Array.<number>} rgba [r, g, b, a] with r, g, b in [0, 255] and a
  376. * in [0, 1].
  377. * @return {string} string of the form 'rgba(r,g,b,a)'.
  378. * @private
  379. */
  380. goog.color.alpha.rgbaStyle_ = function(rgba) {
  381. return 'rgba(' + rgba.join(',') + ')';
  382. };
  383. /**
  384. * Converts from h,s,v,a values to a hex string
  385. * @param {number} h Hue, in [0, 1].
  386. * @param {number} s Saturation, in [0, 1].
  387. * @param {number} v Value, in [0, 255].
  388. * @param {number} a Alpha, in [0, 1].
  389. * @return {string} hex representation of the color.
  390. */
  391. goog.color.alpha.hsvaToHex = function(h, s, v, a) {
  392. var alpha = Math.floor(a * 255);
  393. return goog.color.hsvArrayToHex([h, s, v]) +
  394. goog.color.prependZeroIfNecessaryHelper(alpha.toString(16));
  395. };
  396. /**
  397. * Converts from an HSVA array to a hex string
  398. * @param {Array} hsva Array of [h, s, v, a] in
  399. * [[0, 1], [0, 1], [0, 255], [0, 1]].
  400. * @return {string} hex representation of the color.
  401. */
  402. goog.color.alpha.hsvaArrayToHex = function(hsva) {
  403. return goog.color.alpha.hsvaToHex(hsva[0], hsva[1], hsva[2], hsva[3]);
  404. };