conversion.uts 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. import { RGB,HSL,HSV } from '../utssdk/interface.uts';
  2. import { bound01, pad2 } from './util';
  3. /**
  4. * Handle bounds / percentage checking to conform to CSS color spec
  5. * 处理边界/百分比检查以符合 CSS 颜色规范
  6. * <http://www.w3.org/TR/css3-color/>
  7. * *Assumes:* r, g, b in [0, 255] or [0, 1]
  8. * *Returns:* { r, g, b } in [0, 255]
  9. */
  10. function rgbToRgb(r: string, g: string, b: string):RGB;
  11. function rgbToRgb(r: number, g: string, b: string):RGB;
  12. function rgbToRgb(r: number, g: number, b: string):RGB;
  13. function rgbToRgb(r: number, g: number, b: number):RGB;
  14. function rgbToRgb(r: any, g: any, b: any) : RGB {
  15. return {
  16. r: bound01(r, 255) * 255,
  17. g: bound01(g, 255) * 255,
  18. b: bound01(b, 255) * 255,
  19. } as RGB;
  20. }
  21. export {
  22. rgbToRgb
  23. }
  24. /**
  25. * Converts an RGB color value to HSL.
  26. * 将 RGB 颜色值转换为 HSL。
  27. * *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
  28. * *Returns:* { h, s, l } in [0,1]
  29. */
  30. function rgbToHsl(r: string, g: string, b: string):HSL;
  31. function rgbToHsl(r: number, g: string, b: string):HSL;
  32. function rgbToHsl(r: number, g: number, b: string):HSL;
  33. function rgbToHsl(r: number, g: number, b: number):HSL;
  34. function rgbToHsl(r : any, g : any, b : any) : HSL {
  35. r = bound01(r, 255);
  36. g = bound01(g, 255);
  37. b = bound01(b, 255);
  38. const max = Math.max(r, g, b);
  39. const min = Math.min(r, g, b);
  40. let h = 0;
  41. let s:number// = 0;
  42. const l = (max + min) / 2;
  43. if (max == min) {
  44. s = 0;
  45. h = 0; // achromatic
  46. } else {
  47. const d = max - min;
  48. s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
  49. switch (max) {
  50. case r:
  51. h = (g - b) / d + (g < b ? 6 : 0);
  52. break;
  53. case g:
  54. h = (b - r) / d + 2;
  55. break;
  56. case b:
  57. h = (r - g) / d + 4;
  58. break;
  59. default:
  60. console.log('h')
  61. break;
  62. }
  63. h /= 6;
  64. }
  65. return { h, s, l } as HSL;
  66. }
  67. export {
  68. rgbToHsl
  69. }
  70. export function hue2rgb(p : number, q : number, t : number) : number {
  71. let _t = t
  72. if (_t < 0) {
  73. _t += 1;
  74. }
  75. if (_t > 1) {
  76. _t -= 1;
  77. }
  78. if (_t < 1 / 6) {
  79. return p + (q - p) * (6 * _t);
  80. }
  81. if (_t < 1 / 2) {
  82. return q;
  83. }
  84. if (_t < 2 / 3) {
  85. return p + (q - p) * (2 / 3 - _t) * 6;
  86. }
  87. return p;
  88. }
  89. /**
  90. * Converts an HSL color value to RGB.
  91. * 将 HSL 颜色值转换为 RGB。
  92. * *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
  93. * *Returns:* { r, g, b } in the set [0, 255]
  94. */
  95. function hslToRgb(h : string,s : string,l : string) : RGB
  96. function hslToRgb(h : number,s : string,l : string) : RGB
  97. function hslToRgb(h : number,s : number,l : string) : RGB
  98. function hslToRgb(h : number,s : number,l : number) : RGB
  99. function hslToRgb(h : any,s : any,l : any) : RGB {
  100. let r : number;
  101. let g : number;
  102. let b : number;
  103. h = bound01(h, 360);
  104. s = bound01(s, 100);
  105. l = bound01(l, 100);
  106. if (s == 0) {
  107. // achromatic
  108. g = l;
  109. b = l;
  110. r = l;
  111. } else {
  112. const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
  113. const p = 2 * l - q;
  114. r = hue2rgb(p, q, h + 1 / 3);
  115. g = hue2rgb(p, q, h);
  116. b = hue2rgb(p, q, h - 1 / 3);
  117. }
  118. return { r: r * 255, g: g * 255, b: b * 255 } as RGB;
  119. }
  120. export {
  121. hslToRgb
  122. }
  123. /**
  124. * Converts an RGB color value to HSV
  125. * 将RGB颜色值转换为HSV颜色值
  126. * *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
  127. * *Returns:* { h, s, v } in [0,1]
  128. */
  129. export function rgbToHsv(r : number, g : number, b : number) : HSV {
  130. r = bound01(r, 255);
  131. g = bound01(g, 255);
  132. b = bound01(b, 255);
  133. const max = Math.max(r, g, b);
  134. const min = Math.min(r, g, b);
  135. let h = 0;
  136. const v = max;
  137. const d = max - min;
  138. const s = max == 0 ? 0 : d / max;
  139. if (max == min) {
  140. h = 0; // achromatic
  141. } else {
  142. switch (max) {
  143. case r:
  144. h = (g - b) / d + (g < b ? 6 : 0);
  145. break;
  146. case g:
  147. h = (b - r) / d + 2;
  148. break;
  149. case b:
  150. h = (r - g) / d + 4;
  151. break;
  152. default:
  153. console.log('1')
  154. break;
  155. }
  156. h /= 6;
  157. }
  158. return { h, s, v } as HSV;
  159. }
  160. /**
  161. * Converts an HSV color value to RGB.
  162. * 将HSV颜色值转换为RGB。
  163. * *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
  164. * *Returns:* { r, g, b } in the set [0, 255]
  165. */
  166. function hsvToRgb( h : string, s : string, v : string) : RGB
  167. function hsvToRgb( h : number, s : string, v : string) : RGB
  168. function hsvToRgb( h : number, s : number, v : string) : RGB
  169. function hsvToRgb( h : number, s : number, v : number) : RGB
  170. function hsvToRgb( h : any, s : any, v : any) : RGB {
  171. h = bound01(h, 360) * 6;
  172. s = bound01(s, 100);
  173. v = bound01(v, 100);
  174. const i = Math.floor(h);
  175. const f = h - i;
  176. const p = v * (1 - s);
  177. const q = v * (1 - f * s);
  178. const t = v * (1 - (1 - f) * s);
  179. const mod = i % 6;
  180. const r = [v, q, p, p, t, v][mod];
  181. const g = [t, v, v, q, p, p][mod];
  182. const b = [p, p, t, v, v, q][mod];
  183. return { r: r * 255, g: g * 255, b: b * 255 } as RGB;
  184. }
  185. export {
  186. hsvToRgb
  187. }
  188. /**
  189. * Converts an RGB color to hex
  190. * 将RGB颜色转换为十六进制。
  191. * Assumes r, g, and b are contained in the set [0, 255]
  192. * Returns a 3 or 6 character hex
  193. */
  194. export function rgbToHex(r : number, g : number, b : number, allow3Char : boolean = false) : string {
  195. const hex = [
  196. pad2(Math.round(r).toString(16)),
  197. pad2(Math.round(g).toString(16)),
  198. pad2(Math.round(b).toString(16)),
  199. ];
  200. // Return a 3 character hex if possible
  201. if (
  202. allow3Char &&
  203. hex[0].startsWith(hex[0].charAt(1)) &&
  204. hex[1].startsWith(hex[1].charAt(1)) &&
  205. hex[2].startsWith(hex[2].charAt(1))
  206. ) {
  207. return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
  208. }
  209. return hex.join('');
  210. }
  211. /**
  212. * Converts an RGBA color plus alpha transparency to hex
  213. * 将带有透明度的RGBA颜色转换为十六进制。
  214. * Assumes r, g, b are contained in the set [0, 255] and
  215. * a in [0, 1]. Returns a 4 or 8 character rgba hex
  216. */
  217. // eslint-disable-next-line max-params
  218. export function rgbaToHex(r : number, g : number, b : number, a : number, allow4Char : boolean = false) : string {
  219. const hex = [
  220. pad2(Math.round(r).toString(16)),
  221. pad2(Math.round(g).toString(16)),
  222. pad2(Math.round(b).toString(16)),
  223. pad2(convertDecimalToHex(a)),
  224. ];
  225. // Return a 4 character hex if possible
  226. if (
  227. allow4Char &&
  228. hex[0].startsWith(hex[0].charAt(1)) &&
  229. hex[1].startsWith(hex[1].charAt(1)) &&
  230. hex[2].startsWith(hex[2].charAt(1)) &&
  231. hex[3].startsWith(hex[3].charAt(1))
  232. ) {
  233. return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);
  234. }
  235. return hex.join('');
  236. }
  237. /**
  238. * Converts an RGBA color to an ARGB Hex8 string
  239. * 将RGBA颜色转换为ARGB十六进制字符串。
  240. * Rarely used, but required for "toFilter()"
  241. */
  242. export function rgbaToArgbHex(r : number, g : number, b : number, a : number) : string {
  243. const hex = [
  244. pad2(convertDecimalToHex(a)),
  245. pad2(Math.round(r).toString(16)),
  246. pad2(Math.round(g).toString(16)),
  247. pad2(Math.round(b).toString(16)),
  248. ];
  249. return hex.join('');
  250. }
  251. /** Converts a decimal to a hex value */
  252. /** 将十进制转换为十六进制值。 */
  253. function convertDecimalToHex(d : number) : string
  254. function convertDecimalToHex(d : string) : string
  255. function convertDecimalToHex(d : any) : string {
  256. return Math.round(parseFloat(`${d}`) * 255).toString(16);
  257. }
  258. export {convertDecimalToHex}
  259. /** Converts a hex value to a decimal */
  260. export function convertHexToDecimal(h : string) : number {
  261. return parseIntFromHex(h) / 255;
  262. }
  263. /** Parse a base-16 hex value into a base-10 integer */
  264. export function parseIntFromHex(val : string) : number {
  265. return parseInt(val, 16);
  266. }
  267. export function numberInputToObject(color : number) : RGB {
  268. return {
  269. r: color >> 16,
  270. g: (color & 0xff00) >> 8,
  271. b: color & 0xff,
  272. } as RGB;
  273. }