-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.ts
136 lines (128 loc) · 3.61 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import { addLight, subtractLight, contrast } from '../.helper'
/**
* 判断是否十六进制颜色值
* @param color 十六进制颜色值
* @category Color
* @example
* ``` typescript
* isHexColor('#fff')
* ```
*/
export const isHexColor = (color: string): boolean => {
const reg = /^#([0-9a-fA-F]{3}|[0-9a-fA-f]{6})$/
return reg.test(color);
}
/**
* RGB颜色值转换为十六进制颜色值
* r, g, 和 b 需要在 [0, 255] 范围内
* @param r 0-255 之间的数值
* @param g 0-255 之间的数值
* @param b 0-255 之间的数值
* @category Color
* @example
* ``` typescript
* rgbToHex(23, 46, 176)
* ```
*/
export const rgbToHex = (r: number, g: number, b: number): string => {
// tslint:disable-next-line:no-bitwise
const hex = ((r << 16) | (g << 8) | b).toString(16)
return '#' + new Array(Math.abs(hex.length - 7)).join('0') + hex
}
/**
* 十六进制颜色值转RGB颜色值
* @param hex 十六进制颜色值
* @param opacity 透明度 0 - 1之间的值
* @category Color
* @example
* ``` typescript
* hexToRGB('#fff', 0.5)
* ```
*/
export const hexToRGB = (hex: string, opacity?: number): string => {
let sHex = hex.toLowerCase()
if (isHexColor(hex)) {
if (sHex.length === 4) {
let sColorNew = '#'
for (let i = 1; i < 4; i += 1) {
sColorNew += sHex.slice(i, i + 1).concat(sHex.slice(i, i + 1))
}
sHex = sColorNew
}
const sColorChange: number[] = []
for (let i = 1; i < 7; i += 2) {
sColorChange.push(parseInt('0x' + sHex.slice(i, i + 2)))
}
return opacity
? 'RGBA(' + sColorChange.join(',') + ',' + opacity + ')'
: 'RGB(' + sColorChange.join(',') + ')'
}
return sHex
}
/**
* 是否是暗色系颜色,只支持六十进制颜色值
* @param color 需要判断的颜色值
* @category Color
* @example
* ``` typescript
* colorIsDark('#fff')
* ```
*/
export const colorIsDark = (color: string): boolean => {
if (!isHexColor(color)) return false
const [r, g, b] = hexToRGB(color)
.replace(/(?:\(|\)|rgb|RGB)*/g, '')
.split(',')
.map((item) => Number(item))
return r * 0.299 + g * 0.578 + b * 0.114 < 192
}
/**
* 加深颜色
* @param color 需要加深的颜色值
* @param amount 需要加深的程度
* @category Color
* @example
* ``` typescript
* darken('#fff', 6)
* ```
*/
export const darken = (color: string, amount: number) => {
color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color
amount = Math.trunc((255 * amount) / 100)
return `#${subtractLight(color.substring(0, 2), amount)}${subtractLight(
color.substring(2, 4),
amount
)}${subtractLight(color.substring(4, 6), amount)}`
}
/**
* 减少颜色
* @param color 需要减少的颜色值
* @param amount 需要减少的程度
* @category Color
* @example
* ``` typescript
* lighten('#333', 6)
* ```
*/
export const lighten = (color: string, amount: number) => {
color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color
amount = Math.trunc((255 * amount) / 100)
return `#${addLight(color.substring(0, 2), amount)}${addLight(
color.substring(2, 4),
amount
)}${addLight(color.substring(4, 6), amount)}`
}
/**
* 根据与背景的对比度确定最佳文本颜色(黑色或白色)
* @param hexColor 需要转换的颜色值
* @category Color
* @example
* ``` typescript
* calculateBestTextColor('#333')
* ```
*/
export const calculateBestTextColor = (hexColor: string): "#000000" | "#FFFFFF" => {
const rgbColor = hexToRGB(hexColor.substring(1))
const contrastWithBlack = contrast(rgbColor.split(','), [0, 0, 0])
return contrastWithBlack >= 12 ? '#000000' : '#FFFFFF'
}