OLD | NEW |
1 // | 1 // |
2 // Copyright 2014 Google Inc. All rights reserved. | 2 // Copyright 2014 Google Inc. All rights reserved. |
3 // | 3 // |
4 // Use of this source code is governed by a BSD-style | 4 // Use of this source code is governed by a BSD-style |
5 // license that can be found in the LICENSE file or at | 5 // license that can be found in the LICENSE file or at |
6 // https://developers.google.com/open-source/licenses/bsd | 6 // https://developers.google.com/open-source/licenses/bsd |
7 // | 7 // |
8 | 8 |
9 part of charted.core.utils; | 9 part of charted.core.utils; |
10 | 10 |
11 /// Represents a single color for use in visualizations. Currently, supports | 11 /// Represents a single color for use in visualizations. Currently, supports |
12 /// representing and conversion between RGB, RGBA, HSL, HSLA and hex formats. | 12 /// representing and conversion between RGB, RGBA, HSL, HSLA and hex formats. |
13 class Color { | 13 class Color { |
14 // Internal representation of RGB | 14 // Internal representation of RGB |
15 int _r = 0; | 15 int _r = 0; |
16 int _g = 0; | 16 int _g = 0; |
17 int _b = 0; | 17 int _b = 0; |
18 | 18 |
19 // Internal representation of HSL | 19 // Internal representation of HSL |
20 int _h = 0; // 0 <= _h <= 360 | 20 int _h = 0; // 0 <= _h <= 360 |
21 int _s = 0; // 0 <= _s <= 100 | 21 int _s = 0; // 0 <= _s <= 100 |
22 int _l = 0; // 0 <= _l <= 100 | 22 int _l = 0; // 0 <= _l <= 100 |
23 | 23 |
24 // Alpha value for this color | 24 // Alpha value for this color |
25 double _a = 0.0; | 25 double _a = 0.0; |
26 | 26 |
27 // Flags to indicate the color-space for which values are readily available. | 27 // Flags to indicate the color-space for which values are readily available. |
28 bool _hasRgbColors = false; | 28 bool _hasRgbColors = false; |
29 bool _hasHslColors = false; | 29 bool _hasHslColors = false; |
30 | 30 |
31 /// Create an instance from RGB colors. | 31 /// Create an instance from RGB colors. |
32 Color.fromRgba(this._r, this._g, this._b, this._a) : _hasRgbColors = true; | 32 Color.fromRgba(this._r, this._g, this._b, this._a) : _hasRgbColors = true; |
33 | 33 |
34 /// Create an instance using a string representing color in RGB color space. | 34 /// Create an instance using a string representing color in RGB color space. |
35 /// The input string, [value], can be one of the following formats: | 35 /// The input string, [value], can be one of the following formats: |
36 /// | 36 /// |
37 /// #RGB | 37 /// #RGB |
38 /// #RRGGBB | 38 /// #RRGGBB |
39 /// | 39 /// |
40 /// rgb(R, G, B) | 40 /// rgb(R, G, B) |
41 /// rgba(R, G, B, A) | 41 /// rgba(R, G, B, A) |
42 /// | 42 /// |
43 /// R, G and B represent intensities of Red, Green and Blue channels and A | 43 /// R, G and B represent intensities of Red, Green and Blue channels and A |
44 /// represents the alpha channel (transparency) | 44 /// represents the alpha channel (transparency) |
45 /// | 45 /// |
46 /// When using these formats: | 46 /// When using these formats: |
47 /// 0 <= R,G,B <= 255 | 47 /// 0 <= R,G,B <= 255 |
48 /// 0 <= A <= 1.0 | 48 /// 0 <= A <= 1.0 |
49 factory Color.fromRgbString(String value) => | 49 factory Color.fromRgbString(String value) => |
50 isHexColorString(value) ? _fromHexString(value) : _fromRgbString(value); | 50 isHexColorString(value) ? _fromHexString(value) : _fromRgbString(value); |
51 | 51 |
52 /// Create an instance from HSL colors. | 52 /// Create an instance from HSL colors. |
53 Color.fromHsla(this._h, this._s, this._l, this._a) : _hasHslColors = true; | 53 Color.fromHsla(this._h, this._s, this._l, this._a) : _hasHslColors = true; |
54 | 54 |
55 /// Create an instance using a string representing color in HSL color space. | 55 /// Create an instance using a string representing color in HSL color space. |
56 /// The input string, [value], can be in one of the following formats: | 56 /// The input string, [value], can be in one of the following formats: |
57 /// | 57 /// |
58 /// hsl(H, S%, L%) | 58 /// hsl(H, S%, L%) |
59 /// hsla(H, S%, L%, A) | 59 /// hsla(H, S%, L%, A) |
60 /// | 60 /// |
61 /// H, S and L represent Hue, Saturation and Luminosity respectively. | 61 /// H, S and L represent Hue, Saturation and Luminosity respectively. |
62 /// | 62 /// |
63 /// When using these formats: | 63 /// When using these formats: |
64 /// 0 <= H <= 360 | 64 /// 0 <= H <= 360 |
65 /// 0 <= S,L <= 100 | 65 /// 0 <= S,L <= 100 |
66 /// 0 <= A <= 1.0 | 66 /// 0 <= A <= 1.0 |
67 factory Color.fromHslString(String value) => _fromHslString(value); | 67 factory Color.fromHslString(String value) => _fromHslString(value); |
68 | 68 |
69 /// Ensures that the RGB values are available. If they aren't already | 69 /// Ensures that the RGB values are available. If they aren't already |
70 /// available, they are computed from the HSA values. | 70 /// available, they are computed from the HSA values. |
71 /// | 71 /// |
72 /// Based on color.js from Google Closure library | 72 /// Based on color.js from Google Closure library |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 static bool isRgbColorString(String str) => | 242 static bool isRgbColorString(String str) => |
243 isHexColorString(str) || rgbaColorRegExp.hasMatch(str); | 243 isHexColorString(str) || rgbaColorRegExp.hasMatch(str); |
244 | 244 |
245 /// RegExp to test if a given string is hsl() or hsla() color. | 245 /// RegExp to test if a given string is hsl() or hsla() color. |
246 static final RegExp hslaColorRegExp = new RegExp( | 246 static final RegExp hslaColorRegExp = new RegExp( |
247 r'^(hsl|hsla)?\(\d+,\s?\d+%,\s?\d+%(,\s?(0|1)?(\.\d)?\d*)?\)$', | 247 r'^(hsl|hsla)?\(\d+,\s?\d+%,\s?\d+%(,\s?(0|1)?(\.\d)?\d*)?\)$', |
248 caseSensitive: false); | 248 caseSensitive: false); |
249 | 249 |
250 /// Tests if [str] is a color represented by hsl() or hsla() | 250 /// Tests if [str] is a color represented by hsl() or hsla() |
251 static bool isHslColorString(String str) => hslaColorRegExp.hasMatch(str); | 251 static bool isHslColorString(String str) => hslaColorRegExp.hasMatch(str); |
252 | 252 |
253 /// Create an instance using the passed RGB string. | 253 /// Create an instance using the passed RGB string. |
254 static Color _fromRgbString(String value) { | 254 static Color _fromRgbString(String value) { |
255 int pos = | 255 int pos = (value.startsWith('rgb(') || value.startsWith('RGB(')) |
256 (value.startsWith('rgb(') || value.startsWith('RGB(')) ? 4 : | 256 ? 4 |
257 (value.startsWith('rgba(') || value.startsWith('RGBA(')) ? 5 : 0; | 257 : (value.startsWith('rgba(') || value.startsWith('RGBA(')) ? 5 : 0; |
258 if (pos != 0) { | 258 if (pos != 0) { |
259 final params = value.substring(pos, value.length - 1).split(','); | 259 final params = value.substring(pos, value.length - 1).split(','); |
260 int r = int.parse(params[0]), | 260 int r = int.parse(params[0]), |
261 g = int.parse(params[1]), | 261 g = int.parse(params[1]), |
262 b = int.parse(params[2]); | 262 b = int.parse(params[2]); |
263 double a = params.length == 3 ? 1.0 : double.parse(params[3]); | 263 double a = params.length == 3 ? 1.0 : double.parse(params[3]); |
264 return new Color.fromRgba(r, g, b, a); | 264 return new Color.fromRgba(r, g, b, a); |
265 } | 265 } |
266 return new Color.fromRgba(0, 0, 0, 0.0); | 266 return new Color.fromRgba(0, 0, 0, 0.0); |
267 } | 267 } |
268 | 268 |
269 /// Create an instance using the passed HEX string. | 269 /// Create an instance using the passed HEX string. |
270 /// Assumes that the string starts with a '#' before HEX chars. | 270 /// Assumes that the string starts with a '#' before HEX chars. |
271 static Color _fromHexString(String hex) { | 271 static Color _fromHexString(String hex) { |
272 if (isNullOrEmpty(hex) || (hex.length != 4 && hex.length != 7)) { | 272 if (isNullOrEmpty(hex) || (hex.length != 4 && hex.length != 7)) { |
273 return new Color.fromRgba(0, 0, 0, 0.0); | 273 return new Color.fromRgba(0, 0, 0, 0.0); |
274 } | 274 } |
275 int rgb = 0; | 275 int rgb = 0; |
276 | 276 |
277 hex = hex.substring(1); | 277 hex = hex.substring(1); |
278 if (hex.length == 3) { | 278 if (hex.length == 3) { |
279 for (final char in hex) { | 279 for (final char in hex) { |
280 final val = int.parse(char, radix: 16); | 280 final val = int.parse(char, radix: 16); |
281 rgb = (rgb * 16 + val ) * 16 + val; | 281 rgb = (rgb * 16 + val) * 16 + val; |
282 } | 282 } |
283 } | 283 } else if (hex.length == 6) { |
284 else if (hex.length == 6){ | |
285 rgb = int.parse(hex, radix: 16); | 284 rgb = int.parse(hex, radix: 16); |
286 } | 285 } |
287 | 286 |
288 return new Color.fromRgba( | 287 return new Color.fromRgba( |
289 (rgb & 0xff0000) >> 0x10, (rgb & 0xff00) >> 8, (rgb & 0xff), 1.0); | 288 (rgb & 0xff0000) >> 0x10, (rgb & 0xff00) >> 8, (rgb & 0xff), 1.0); |
290 } | 289 } |
291 | 290 |
292 /// Create an instance using the passed HSL color string. | 291 /// Create an instance using the passed HSL color string. |
293 static Color _fromHslString(String value) { | 292 static Color _fromHslString(String value) { |
294 int pos = | 293 int pos = (value.startsWith('hsl(') || value.startsWith('HSL(')) |
295 (value.startsWith('hsl(') || value.startsWith('HSL(')) ? 4 : | 294 ? 4 |
296 (value.startsWith('hsla(') || value.startsWith('HSLA(')) ? 5 : 0; | 295 : (value.startsWith('hsla(') || value.startsWith('HSLA(')) ? 5 : 0; |
297 if (pos != 0) { | 296 if (pos != 0) { |
298 final params = value.substring(pos, value.length - 1).split(','); | 297 final params = value.substring(pos, value.length - 1).split(','); |
299 int h = int.parse(params[0]), | 298 int h = int.parse(params[0]), |
300 s = int.parse(params[1]), | 299 s = int.parse(params[1]), |
301 l = int.parse(params[2]); | 300 l = int.parse(params[2]); |
302 double a = params.length == 3 ? 1.0 : double.parse(params[3]); | 301 double a = params.length == 3 ? 1.0 : double.parse(params[3]); |
303 return new Color.fromHsla(h, s, l, a); | 302 return new Color.fromHsla(h, s, l, a); |
304 } | 303 } |
305 return new Color.fromHsla(0, 0, 0, 0.0); | 304 return new Color.fromHsla(0, 0, 0, 0.0); |
306 } | 305 } |
307 } | 306 } |
OLD | NEW |