ColorPicker.hx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. package h2d.comp;
  2. import h2d.css.Defs;
  3. import h2d.css.Fill;
  4. private enum RGBA {
  5. R;
  6. G;
  7. B;
  8. A;
  9. }
  10. private enum ChangeState {
  11. SNone;
  12. SColor;
  13. SPalette;
  14. SChart;
  15. SRed;
  16. SGreen;
  17. SBlue;
  18. SAlpha;
  19. }
  20. private enum CompStyle {
  21. GaugeLabel;
  22. GaugeInput;
  23. ColorLabel;
  24. ColorInput;
  25. }
  26. private class Style {
  27. public function new () {
  28. }
  29. public static function get(kind:CompStyle) {
  30. var style = new h2d.css.Style();
  31. switch(kind) {
  32. case GaugeLabel: style.fontSize = 11;
  33. case GaugeInput: style.width = 24;
  34. style.height = 10;
  35. style.fontSize = 11;
  36. case ColorLabel: style.fontSize = 14;
  37. case ColorInput: style.width = 50;
  38. style.height = 10;
  39. style.fontSize = 11;
  40. }
  41. return style;
  42. }
  43. }
  44. private class Arrow extends h2d.css.Fill {
  45. public function new (parent, x:Float, y:Float, ang = 0., color = 0xff000000) {
  46. super(parent);
  47. addPoint(-5, -4, color);
  48. addPoint(-5, 4, color);
  49. addPoint(0, 0, color);
  50. addPoint(0, 0, color);
  51. rotation = -ang;
  52. this.x = x;
  53. this.y = y;
  54. }
  55. }
  56. private class Cross extends h2d.css.Fill {
  57. var size:Float;
  58. public function new (parent, size:Float, color = 0xff000000) {
  59. super(parent);
  60. this.size = size;
  61. lineRect(FillStyle.Color(color), 0, 0, size, size, 1);
  62. }
  63. public function setColor(color:Int) {
  64. reset();
  65. lineRect(FillStyle.Color(color), 0, 0, size, size, 1);
  66. }
  67. }
  68. private class Color extends h2d.Sprite {
  69. var picker : ColorPicker;
  70. public var width :Float;
  71. public var height :Float;
  72. public var color(default, set):Int = 0xFFFFFFFF;
  73. public var preview(default, set):Int = 0xFFFFFFFF;
  74. public var alpha(default, set):Float = 1.;
  75. var canvas:h2d.css.Fill;
  76. var label : h2d.comp.Label;
  77. var input : h2d.comp.Input;
  78. public function new (picker,ix, iy, iw, ih, parent) {
  79. super(parent);
  80. this.picker = picker;
  81. x = ix;
  82. y = iy;
  83. width = iw;
  84. height = ih;
  85. init();
  86. }
  87. function set_color(v:Int) {
  88. if(v != color) {
  89. color = v;
  90. drawAll();
  91. }
  92. return color;
  93. }
  94. function set_preview(v:Int) {
  95. if(v != preview) {
  96. preview = v;
  97. drawAll();
  98. }
  99. return color;
  100. }
  101. function set_alpha(v:Float) {
  102. alpha = v;
  103. drawAll();
  104. return color;
  105. }
  106. public function updateColor(v:Int) {
  107. color = v;
  108. input.value = StringTools.hex(preview, 6).substr(2);
  109. }
  110. function init() {
  111. label = new h2d.comp.Label("#", this);
  112. label.setStyle(Style.get(ColorLabel));
  113. input = new h2d.comp.Input(this);
  114. input.setStyle(Style.get(ColorInput));
  115. input.value = "FFFFFF";
  116. input.x = 15; input.y = 3;
  117. input.onChange = function (e) {
  118. input.value = input.value.toUpperCase();
  119. if(input.value.length > 6) {
  120. input.value = input.value.substr(0, 6);
  121. return;
  122. }
  123. var v = Std.parseInt("0x" + input.value);
  124. if (v != null) {
  125. color = 255 << 24 | v;
  126. picker.change = SColor;
  127. }
  128. };
  129. canvas = new h2d.css.Fill(this);
  130. canvas.y = 2 + height * 0.5;
  131. drawAll();
  132. }
  133. public function drawAll() {
  134. canvas.reset();
  135. canvas.fillRectColor(0, 0, width, height * 0.5, preview);
  136. canvas.fillRectColor(0, 0, width * 0.5, height * 0.5, color);
  137. canvas.fillRectColor(0, height * 0.5 - 4, width, 4, 0xFF000000);
  138. canvas.fillRectColor(0, height * 0.5 - 4, width * alpha, 4, 0xFFFFFFFF);
  139. canvas.lineRect(FillStyle.Color(ColorPicker.borderColor), 0, 0, width, height * 0.5, 1);
  140. }
  141. }
  142. private class Palette extends h2d.Sprite {
  143. public var width :Float;
  144. public var height :Float;
  145. public var color(default, set):Int;
  146. var picker : ColorPicker;
  147. var canvas:h2d.css.Fill;
  148. var interact:h2d.Interactive;
  149. var cursor:h2d.Sprite;
  150. public function new (picker, ix, iy, iw, ih, parent) {
  151. super(parent);
  152. this.picker = picker;
  153. x = ix;
  154. y = iy;
  155. width = iw;
  156. height = ih;
  157. init();
  158. }
  159. function init() {
  160. canvas = new h2d.css.Fill(this);
  161. cursor = new h2d.Sprite(this);
  162. var larrow = new Arrow(cursor, 0, 0, 0, 0xffcccccc);
  163. var rarrow = new Arrow(cursor, width, 0, Math.PI, 0xffcccccc);
  164. interact = new h2d.Interactive(width + 16, height, canvas);
  165. interact.x = -8;
  166. interact.onPush = function(e) {
  167. setCursor(e.relY);
  168. interact.startDrag(function(e) {
  169. if( e.kind == EMove )
  170. setCursor(e.relY);
  171. });
  172. picker.change = SPalette;
  173. }
  174. interact.onRelease = function(e) {
  175. interact.stopDrag();
  176. picker.change = SNone;
  177. }
  178. color = getColor(0);
  179. drawAll();
  180. }
  181. function set_color(v:Int) {
  182. color = v;
  183. if(!picker.change.equals(SPalette))
  184. updateCursor();
  185. drawAll();
  186. return color;
  187. }
  188. function updateCursor() {
  189. var hsl = ColorPicker.INTtoHSL(color);
  190. cursor.y = Math.round(Math.max(0, Math.min(height, (1 - hsl[0]) * height)));
  191. }
  192. public function drawAll() {
  193. var s = 1;
  194. var l = 0.5;
  195. var seg = height / 6;
  196. canvas.reset();
  197. for (i in 0...6) {
  198. var up = ColorPicker.HSLtoINT(1 - i / 6, s, l);
  199. var down = ColorPicker.HSLtoINT(1 - (i + 1) / 6, s, l);
  200. canvas.fillRectGradient(0, i * seg, width, seg, up, up, down, down);
  201. }
  202. canvas.lineRect(FillStyle.Color(ColorPicker.borderColor), 0, 0, width, height, 1);
  203. }
  204. public function setCursor(dy:Float) {
  205. cursor.y = Math.round(Math.max(0, Math.min(height, dy)));
  206. color = getColor(cursor.y);
  207. }
  208. public function getColor(py:Float) {
  209. var h = 1 - (py / height);
  210. var s = 1;
  211. var l = 0.5;
  212. return(ColorPicker.HSLtoINT(h, s, l));
  213. }
  214. public function setColorFrom(newColor:Int) {
  215. var rgb = ColorPicker.INTtoRGB(newColor);
  216. var hsl = ColorPicker.RGBtoHLS(rgb[0], rgb[1], rgb[2]);
  217. hsl[1] = 1; hsl[2] = 0.5;
  218. rgb = ColorPicker.HSLtoRGB(hsl[0], hsl[1], hsl[2]);
  219. color = ColorPicker.RGBtoINT(rgb[0], rgb[1], rgb[2]);
  220. }
  221. }
  222. private class Chart extends h2d.Sprite{
  223. public var width :Int;
  224. public var height :Int;
  225. public var refColor(default, set):Int = 0xffffffff;
  226. public var color:Int = 0xffffffff;
  227. var picker : ColorPicker;
  228. var ray :Float;
  229. var canvas:h2d.css.Fill;
  230. var interact:h2d.Interactive;
  231. var cursor:h2d.Sprite;
  232. var lastPos:h3d.Vector;
  233. var cross:Cross ;
  234. public function new (picker,ix, iy, iw, ih, ray, parent) {
  235. super(parent);
  236. this.picker = picker;
  237. x = ix;
  238. y = iy;
  239. width = iw;
  240. height = ih;
  241. this.ray = ray;
  242. init();
  243. }
  244. function init() {
  245. canvas = new h2d.css.Fill(this);
  246. cursor = new h2d.Sprite(this);
  247. cross = new Cross(cursor, ray * 2);
  248. cross.x = cross.y = -ray;
  249. interact = new h2d.Interactive(width, height, canvas);
  250. interact.onPush = function(e) {
  251. setCursor(e.relX, e.relY);
  252. interact.startDrag(function(e) {
  253. if( e.kind == EMove )
  254. setCursor(e.relX, e.relY);
  255. });
  256. picker.change = SChart;
  257. }
  258. interact.onRelease = function(e) {
  259. interact.stopDrag();
  260. picker.change = SNone;
  261. }
  262. drawAll();
  263. setCursor(0, 0);
  264. }
  265. public function setCursor(dx:Float, dy:Float) {
  266. cursor.x = Math.max(ray + 1, Math.min(width - ray - 1, dx));
  267. cursor.y = Math.max(ray + 1, Math.min(height - ray - 1, dy));
  268. lastPos = normalizePos(dx, dy);
  269. color = getColor(lastPos.x, lastPos.y);
  270. cross.setColor(ColorPicker.complementaryColor(color));
  271. }
  272. function set_refColor(v:Int) {
  273. refColor = v;
  274. color = getColor(lastPos.x, lastPos.y);
  275. cross.setColor(ColorPicker.complementaryColor(color));
  276. drawAll();
  277. return refColor;
  278. }
  279. function normalizePos(dx:Float, dy:Float) {
  280. var px = 1 - Math.min(width, Math.max(0, dx)) / width;
  281. var py = 1 - Math.min(height, Math.max(0, dy)) / height;
  282. return new h3d.Vector(px, py);
  283. }
  284. public function drawAll() {
  285. canvas.reset();
  286. var rgb = [(refColor >> 16) & 0xFF, (refColor >> 8) & 0xFF, refColor & 0xFF];
  287. for (i in 0...width>>1) {
  288. for (j in 0...height>>1) {
  289. var di = Math.max(0, Math.min(width, i * 2));
  290. var dj = Math.max(0, Math.min(width, j * 2));
  291. var dw = (1 - di / width);
  292. var dh = (1 - dj / height);
  293. var r = Math.round(rgb[0] * dh);
  294. var g = Math.round(rgb[1] * dh);
  295. var b = Math.round(rgb[2] * dh);
  296. var max = Math.max(r, Math.max(g, b));
  297. r = Math.round(r + (max - r) * dw);
  298. g = Math.round(g + (max - g) * dw);
  299. b = Math.round(b + (max - b) * dw);
  300. var c = (255 << 24) | (r << 16) | (g << 8) | b;
  301. canvas.fillRectColor(i * 2, j * 2, 2, 2, c);
  302. }
  303. }
  304. canvas.lineRect(FillStyle.Color(ColorPicker.borderColor), 0, 0, width, height, 1);
  305. }
  306. function getColor(dw:Float, dh:Float) {
  307. var rgb = [(refColor >> 16) & 0xFF, (refColor >> 8) & 0xFF, refColor & 0xFF];
  308. var r = Math.round(rgb[0] * dh);
  309. var g = Math.round(rgb[1] * dh);
  310. var b = Math.round(rgb[2] * dh);
  311. var max = Math.max(r, Math.max(g, b));
  312. r = Math.round(r + (max - r) * dw);
  313. g = Math.round(g + (max - g) * dw);
  314. b = Math.round(b + (max - b) * dw);
  315. return ColorPicker.RGBtoINT(r, g, b);
  316. }
  317. public function setColorFrom(newColor:Int) {
  318. var rgb = ColorPicker.INTtoRGB(newColor);
  319. var hsl = ColorPicker.RGBtoHLS(rgb[0], rgb[1], rgb[2]);
  320. hsl[1] = 1; hsl[2] = 0.5;
  321. rgb = ColorPicker.HSLtoRGB(hsl[0], hsl[1], hsl[2]);
  322. refColor = ColorPicker.RGBtoINT(rgb[0], rgb[1], rgb[2]);
  323. var rgb = ColorPicker.INTtoRGB(newColor);
  324. var min = Math.min(rgb[0], Math.min(rgb[1], rgb[2]));
  325. var max = Math.max(rgb[0], Math.max(rgb[1], rgb[2]));
  326. var dx = 1 - min / max;
  327. var dy = 1 - max / 255;
  328. setCursor(dx * width, dy * height);
  329. }
  330. }
  331. private class ColorGauge extends h2d.Sprite{
  332. public var width :Int;
  333. public var height :Int;
  334. public var color(default, set):Int = 0xffffffff;
  335. public var ratio(get, null):Float;
  336. var picker : ColorPicker;
  337. var canvas:h2d.css.Fill;
  338. var interact:h2d.Interactive;
  339. var cursor:h2d.Sprite;
  340. var bindTo:RGBA;
  341. var label : h2d.comp.Label;
  342. var input : h2d.comp.Input;
  343. var isFinal:Bool;
  344. public function new (picker,ix, iy, iw, ih, rgba, parent) {
  345. super(parent);
  346. this.picker = picker;
  347. x = ix;
  348. y = iy;
  349. width = iw;
  350. height = ih;
  351. bindTo = rgba;
  352. init();
  353. }
  354. function init() {
  355. label = new h2d.comp.Label(bindTo.getName(), this);
  356. label.setStyle(Style.get(GaugeLabel));
  357. label.x = -45;
  358. label.y = 2;
  359. input = new h2d.comp.Input(this);
  360. input.setStyle(Style.get(GaugeInput));
  361. input.value = "255";
  362. input.x = -30; input.y = 3;
  363. input.onChange = function(e) {
  364. setCursor(cursor.x);
  365. };
  366. canvas = new h2d.css.Fill(this);
  367. cursor = new h2d.Sprite(this);
  368. cursor.x = width;
  369. var larrow = new Arrow(cursor, 0, 0, -Math.PI / 2, 0xffcccccc);
  370. var rarrow = new Arrow(cursor, 0, height, Math.PI / 2, 0xffcccccc);
  371. interact = new h2d.Interactive(width, height + 8, canvas);
  372. interact.y = -4;
  373. interact.onPush = function(e) {
  374. setCursor(e.relX);
  375. interact.startDrag(function(e) {
  376. if( e.kind == EMove )
  377. setCursor(e.relX);
  378. });
  379. setState();
  380. }
  381. interact.onRelease = function(e) {
  382. interact.stopDrag();
  383. picker.change = SNone;
  384. }
  385. drawAll();
  386. }
  387. function set_color(v:Int) {
  388. color = v;
  389. if(!bindTo.equals(RGBA.A))
  390. updateCursor();
  391. drawAll();
  392. return color;
  393. }
  394. function setState() {
  395. picker.change = switch(bindTo) {
  396. case RGBA.R: SRed;
  397. case RGBA.G: SGreen;
  398. case RGBA.B: SBlue;
  399. case RGBA.A: SAlpha;
  400. }
  401. }
  402. public function get_ratio() {
  403. return cursor.x / width;
  404. }
  405. public function updateCursor() {
  406. var a = color >>> 24;
  407. var r = (color >> 16) & 0xFF;
  408. var g = (color >> 8) & 0xFF;
  409. var b = color & 0xFF;
  410. cursor.x = Math.round(switch(bindTo) {
  411. case RGBA.R: r * width / 255;
  412. case RGBA.G: g * width / 255;
  413. case RGBA.B: b * width / 255;
  414. case RGBA.A: a * width / 255;
  415. });
  416. input.value = Std.string(Std.int(255 * ratio));
  417. }
  418. public function setCursor(dx:Float) {
  419. cursor.x = Math.round(Math.max(0, Math.min(width, dx)));
  420. var r = (color >> 16) & 0xFF;
  421. var g = (color >> 8) & 0xFF;
  422. var b = color & 0xFF;
  423. color = switch(bindTo) {
  424. case RGBA.R: ColorPicker.RGBtoINT(Math.round(255 * ratio), g, b);
  425. case RGBA.G: ColorPicker.RGBtoINT(r, Math.round(255 * ratio), b);
  426. case RGBA.B: ColorPicker.RGBtoINT(r, g, Math.round(255 * ratio));
  427. case RGBA.A: color;
  428. }
  429. input.value = Std.string(Math.round(255 * ratio));
  430. }
  431. public function drawAll() {
  432. var r = (color >> 16) & 0xFF;
  433. var g = (color >> 8) & 0xFF;
  434. var b = color & 0xFF;
  435. var left:Int;
  436. var right:Int;
  437. switch(bindTo) {
  438. case RGBA.R: left = ColorPicker.RGBtoINT(0, g, b); right = ColorPicker.RGBtoINT(255, g, b);
  439. case RGBA.G: left = ColorPicker.RGBtoINT(r, 0, b); right = ColorPicker.RGBtoINT(r, 255, b);
  440. case RGBA.B: left = ColorPicker.RGBtoINT(r, g, 0); right = ColorPicker.RGBtoINT(r, g, 255);
  441. case RGBA.A: left = 0xFF000000; right = 0xFFFFFFFF;
  442. }
  443. canvas.reset();
  444. canvas.fillRectGradient(0, 0, width, height, left, right, left, right);
  445. canvas.lineRect(FillStyle.Color(ColorPicker.borderColor), 0, 0, width, height, 1);
  446. }
  447. }
  448. /////////////////////////////////////////////////////////////////
  449. @:allow(h2d.comp)
  450. class ColorPicker extends h2d.comp.Component {
  451. public static var borderColor = 0xFFaaaaaa;
  452. var finalColor : Color;
  453. var palette : Palette;
  454. var chart : Chart;
  455. var gaugeRed : ColorGauge;
  456. var gaugeGreen : ColorGauge;
  457. var gaugeBlue : ColorGauge;
  458. var gaugeAlpha : ColorGauge;
  459. var timer : haxe.Timer;
  460. var change : ChangeState;
  461. public var color(get, set) : Int;
  462. public function new(?parent) {
  463. super("colorpicker", parent);
  464. init();
  465. }
  466. inline function get_color() {
  467. return (finalColor.color&0xFFFFFF) | Std.int(finalColor.alpha*255) << 24;
  468. }
  469. function set_color(v) {
  470. finalColor.color = v;
  471. finalColor.alpha = (v >>> 24) / 255;
  472. palette.setColorFrom(v);
  473. chart.setColorFrom(v);
  474. gaugeRed.color = chart.color;
  475. gaugeGreen.color = chart.color;
  476. gaugeBlue.color = chart.color;
  477. gaugeAlpha.setCursor(finalColor.alpha * gaugeAlpha.width);
  478. return v;
  479. }
  480. override function onAlloc() {
  481. super.onAlloc();
  482. if( timer == null ) {
  483. timer = new haxe.Timer(10);
  484. timer.run = doUpdate;
  485. }
  486. }
  487. override function onDelete() {
  488. super.onDelete();
  489. if( timer != null ) {
  490. timer.stop();
  491. timer = null;
  492. }
  493. }
  494. function init() {
  495. finalColor = new Color(this, 15, 8, 175, 45, this);
  496. palette = new Palette(this, 16, 65, 20, 140, this);
  497. chart = new Chart(this,50, 65, 140, 140, 3.5, this);
  498. gaugeRed = new ColorGauge(this, 50, 220, 140, 15, RGBA.R, this);
  499. gaugeGreen = new ColorGauge(this, 50, 245, 140, 15, RGBA.G, this);
  500. gaugeBlue = new ColorGauge(this, 50, 270, 140, 15, RGBA.B, this);
  501. gaugeAlpha = new ColorGauge(this, 50, 295, 140, 15, RGBA.A, this);
  502. chart.refColor = palette.color;
  503. change = SNone;
  504. var close = new Button("", this);
  505. close.addClass(":close");
  506. // close.addStyleString("layout:absolute;font-size:12px;height:10px;width:10px;");
  507. close.x = 175;
  508. close.y = 10;
  509. close.onClick = function() {
  510. onClose();
  511. };
  512. }
  513. function doUpdate() {
  514. finalColor.preview = chart.color;
  515. if(change.equals(SNone)) {
  516. if(finalColor.color != chart.color) {
  517. finalColor.updateColor(chart.color);
  518. onChange(color);
  519. }
  520. return;
  521. }
  522. switch(change) {
  523. case SColor: palette.setColorFrom(finalColor.color);
  524. chart.setColorFrom(finalColor.color);
  525. // require another change event since we have finalColor == chartColor
  526. onChange(color);
  527. case SPalette: chart.refColor = palette.color;
  528. case SRed: chart.setColorFrom(gaugeRed.color);
  529. palette.color = chart.refColor;
  530. case SGreen: chart.setColorFrom(gaugeGreen.color);
  531. palette.color = chart.refColor;
  532. case SBlue: chart.setColorFrom(gaugeBlue.color);
  533. palette.color = chart.refColor;
  534. case SAlpha: finalColor.alpha = gaugeAlpha.ratio;
  535. onChange(color);
  536. default:
  537. }
  538. gaugeRed.color = chart.color;
  539. gaugeGreen.color = chart.color;
  540. gaugeBlue.color = chart.color;
  541. }
  542. public dynamic function onClose() {
  543. }
  544. public dynamic function onChange( value : Int ) {
  545. }
  546. //////////////////
  547. public static function INTtoRGB(color:Int) {
  548. return [(color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF];
  549. }
  550. public static function INTtoHSL(color:Int) {
  551. var rgb = INTtoRGB(color);
  552. return RGBtoHLS(rgb[0], rgb[1], rgb[2]);
  553. }
  554. public static function RGBtoINT(r:Int, g:Int, b:Int, a:Int = 255) {
  555. return (a << 24) | (r << 16) | (g << 8) | b;
  556. }
  557. public static function RGBtoHLS(r:Float, g:Float, b:Float) {
  558. r /= 255;
  559. g /= 255;
  560. b /= 255;
  561. var max = Math.max(r, Math.max(g, b));
  562. var min = Math.min(r, Math.min(g, b));
  563. var med = (max + min) / 2;
  564. var h = med;
  565. var s = med;
  566. var l = med;
  567. if(max == min)
  568. h = s = 0;
  569. else {
  570. var d = max - min;
  571. s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
  572. if(max == r) h = (g - b) / d + (g < b ? 6 : 0);
  573. else if(max == g) h = (b - r) / d + 2;
  574. else if(max == b) h = (r - g) / d + 4;
  575. h /= 6;
  576. }
  577. return [h, s, l];
  578. }
  579. public static function HSLtoINT(h:Float, s:Float, l:Float) {
  580. var rgb = HSLtoRGB(h, s, l);
  581. return RGBtoINT(rgb[0], rgb[1], rgb[2]);
  582. }
  583. public static function HSLtoRGB(h:Float, s:Float, l:Float) {
  584. var r, g, b;
  585. if(s == 0)
  586. r = g = b = l;
  587. else {
  588. function hue2rgb(p:Float, q:Float, t:Float) {
  589. if(t < 0) t += 1;
  590. if(t > 1) t -= 1;
  591. if(t < 1 / 6) return p + (q - p) * 6 * t;
  592. if(t < 1 / 2) return q;
  593. if(t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
  594. return p;
  595. }
  596. var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
  597. var p = 2 * l - q;
  598. r = hue2rgb(p, q, h + 1 / 3);
  599. g = hue2rgb(p, q, h);
  600. b = hue2rgb(p, q, h - 1 / 3);
  601. }
  602. return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
  603. }
  604. public static function complementaryColor (color:Int) {
  605. var rgb = INTtoRGB(color);
  606. var r = rgb[0] ^ 0xFF;
  607. var g = rgb[1] ^ 0xFF;
  608. var b = rgb[2] ^ 0xFF;
  609. return (255 << 24) | (r << 16) | (g << 8) | b;
  610. }
  611. }