我们在做主题订制的时候,一般都会选一种主题色,该颜色以主题色为主导,颜色依次变浅,用于做主题色下的关联色统一,例如文字激活、激活的背景色、菜单背景色等
在项目中主题色的应用:
如果你在项目中允许用户自定义主题,那么我们就需要计算出用户自定义的主题,并且为主题分档,最后生成的效果如下:
我们对颜色进行加深减淡就是通过更改rgb
的色值来实现的,先将hex
转换rgb
色值,然后对色值系数进行调整来实现。
1、hex
转rgb
2、调整rgb
系数实现加深减淡
3、rgb
转hex
hex转rgb
先接收色值,例如:#409EFF
将色值转换为rgb
模式,在这里用到了正则匹配和parseInt
在正则中 . 标识匹配除换行外的任意字符,这里两个一组进行匹配,/g
标识全部匹配,match
会返回匹配成功的数组
parseInt(string, radix)
解析一个字符串并返回指定基数的十进制整数,radix
是2-36
之间的整数,表示被解析字符串的基数。
在这里parseInt
指定 16
表示被解析值是十六进制数,返回10
进制数
参考:parseInt
/**
* hex转rgb
* @param {string} str 色值,如:#409EFF
* @returns rgb数组[64, 158, 255]
*/
const hexToRgb = (str) => {
let hexs = null;
let reg = /^\#?[0-9A-Fa-f]{6}$/;
if (!reg.test(str)) return alert('色值不正确')
str = str.replace('#', '') // 去掉#
hexs = str.match(/../g) // 切割成数组 409EFF => ['40','9E','FF']
// 将切割的色值转换为16进制
for (let i = 0; i < hexs.length; i++) hexs[i] = parseInt(hexs[i], 16)
return hexs // 返回rgb色值[64, 158, 255]
}
色值变浅
颜色变浅的原理:rgb
中0~255
是暗到亮的过程,0
是最暗,255
是最亮
对rgb
的色值调大即可让颜色变量,便亮就是减淡的过程
通过代码实现:
/**
* 颜色减淡
* @param {string} color 色值,如:##409EFF
* @param {number} level 调整幅度,0~1之间
* @returns {array} 最终颜色减淡的rgb数组
*/
const getLightColor = (color, level) => {
let reg = /^\#?[0-9A-Fa-f]{6}$/;
if (!reg.test(color)) return alert('色值不正确')
let rgb = hexToRgb(color);
// 循环对色值进行调整
for(let i = 0 ; i < 3 ; i++){
rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]) // 始终保持在0-255之间
}
return rgb // [159, 206, 255]
}
getLightColor('#409EFF',0.5)
在循环中调整每个rgb
的色值,调整的色值不能超过255
,公式:
色彩最大值 - 原本值 = 可调整幅度
可调整幅度 * 涨幅 + 原本的值 = 最终变浅的值
在上面的代码中:Math.floor((255 - rgb[i]) * level + rgb[i])
(255 - 100) * 0.5 + 100 = 177.5
// 始终保持在0-255之间,调整幅度0.5
色值变暗
将rgb
值调小就是变暗的过程,颜色变暗是对色值本身进行调整,范围0~255
,0
表示黑色,255
表示白色
公式:本身值 - 本身值 * 调整幅度 = 最终值
/**
* 颜色加深
* @param {string} color 色值,如:##409EFF
* @param {number} level 调整幅度,0~1之间
* @returns 最终颜色加深的rgb数组
*/
const getDarkColor = (color, level) => {
let reg = /^\#?[0-9A-Fa-f]{6}$/;
if (!reg.test(color)) return alert('色值不正确')
let rgb = hexToRgb(color);
for(let i = 0 ; i < 3 ; i++){
rgb[i] = Math.floor(rgb[i] - (rgb[i] * level)) // 始终保持在0-255之间
}
return rgb // [32, 79, 127]
}
rgb转hex色值
在这里通过toString
实现rgb
转hex
,对于 Number
值,toString
方法返回数字值指定基数的字符串表示。
参考:toString
/**
* rgb转hex
* @param {number} r 红色色值,如:64
* @param {number} g 绿色色值,如:158
* @param {number} b 蓝色色值,如:255
* @returns 最终rgb转hex的值,如:64,158,255 -> #409EFF
*/
const rgbToHex = (r,g,b) => {
let reg = /^\d{1,3}$/; // 限定1-3位 -> 0~255
if(!reg.test(r) || !reg.test(g) || !reg.test(b)) return alert('色值不正确')
let hex =[r.toString(16), g.toString(16), b.toString(16)]
// 转换的值如果只有一位则补0
for(let i = 0 ; i < 3 ; i++){
if(hex[i].length === 1) hex[i] = `0${hex[i]}`
}
return `#${hex.join('')}` // #409eff
}
rgbToHex(64,158,255)
颜色分档
可以通过遍历将颜色由浓变淡,修改颜色是以系数生成的,系数0 ~ 1
这里起始下标为1
,结束下标为9
,避免了系数的 0
和1
,如果系数是0
则会生成黑色,1
会生成白色
// 1~9避免最暗和最亮,0最暗(黑),10最亮(白)
// 1~9避免最暗和最亮,0最暗(黑),10最亮(白)
for (let i = 1; i <= 9; i++) {
let light = getLightColor(theme, i / 10)
// 可以通过遍历将颜色分为9档
}
如果你觉得本文章不错,欢迎点赞👍、收藏💖、转发✨哦~
阅读其它:
Git提交规范
微信小程序动态生成表单来啦!你再也不需要手写表单了!
微信小程序用户隐私API
所见即所得的动画效果:Animate.css
前端换肤,聊一聊主题切换那些事