不知道大家在开发个人项目的时候,有没有遇到过以下的问题:
- 我的页面主色调用什么颜色?
- 背景色又用什么颜色?
- 辅助色呢?
- 对于可自定义主题的项目,如何根据用户选择的主色调生成其他辅助色呢?
- ...
前面3个问题,大家可以去参考专业的配色网站来,但是对于第4个问题,在页面颜色不确定的情况下,如何根据用户设置的主色调生成一整套的配色方案?而且还得保证不同颜色之间的辨识度。
...到最后,就只能使出配色终极大法:黑、白、灰,3个色调来搞了。
黑白灰虽是万能配色,但是对于有些类型的项目,黑白灰确实也显得有些不搭。例如,我目前正在做的一个小程序,其基本功能就是画图,然后在此基础之上增加更多的玩法。对于画图类的项目,本身就需要对各种颜色的支持和操控,如果主题色搞成黑白灰,那就显然不搭了。
当然,如果有专业的UI设计那就完全没有任何问题了。本篇文章只针对没有UI设计的项目,作为前端开发人员,怎么把页面的颜色搭配好。
配色原理
要配色,首先肯定要去了解颜色。可能你觉得自己写了这么多年的前端页面,颜色早就了解了。我看未必。
比如:
- 浏览器支持哪些颜色模型?
- 不同的颜色模型分别是怎么定义出来的?
- RGB是通过三原色按等级来定义的,那HSL呢?HSV呢?
- 不同颜色模型之间如何进行转换?
对于平时没怎么用过HSL的同学来说,可能都没想过这些问题。因为在平时开发中,根本就用不上,颜色全都是UI提供好的十六进制或RGB格式的,复制过来用就行了。
但如果要学会配色,肯定是要弄懂这几个问题的。当然,我也是非专业的UI,只是在做项目时遇到了这些问题,然后从一个前端开发者的角度,总结了一些个人经验,仅供参考。
为什么一定要弄懂这些问题呢?因为配色一般都不是根据RGB这种来的,而是根据HSV这种颜色模型来实现的。如果用RGB模型,配出来的的颜色基本都是乱的,很难人为去把控。而HSV就不会,它可以先确定一个色相,然后根据色相来生成一系列的颜色,这样配出来的颜色都是可以人为来掌控的。
关于这些问题的解答,大家可以参考我之前的一篇文章《如何封装一个颜色选择ColorPicker组件?》,有专门对颜色模型进行了一些介绍。
弄懂了上面的那些问题,接下来配色就不难了。
具体实现
比如,我要配一个红色系的主题:
- 首先将色相H设置为0°;
- 主题色:一般都是辨识度比较高而且看起来很鲜艳的颜色,主题嘛,就是为了突出,引起人的注意。所以,我们就可以将饱和度S设置高一些,70%到90%之间看起来就比较舒服。如果太低了,很难突出主题,太高了,又会显得刺眼。亮度V一般可以设置80%左右就好了。
- 辅助色:一般比主题色要低一个层次,可以用于置灰、禁用、背景、辅助说明等状态。那么,我们就可以把饱和度S设置低一些,10%到30%左右,根据不同场景来确定,亮度V基本也在80%左右。
- 如果还需要配置反色系,也很好办,直接将色相H旋转180°就好了。
文字描述显得无力,没有代入感,配出来的具体效果大家可以参考我的小程序来,小程序上面可以支持配置任意的主题色。
总结起来也就是:色系先由色相来确定,其他搭配色再根据色相来确定,这样搭出来的一套颜色基本不会太乱,也能很好的控制主次关系、保证不同颜色之间的辨识度。
看两个我封装的颜色生成函数(代码中用到了@moohng/dan
和color-convert
两个库):
/**
* 生成随机背景色
* @returns
*/
export function generalBgColor(s = 80, v = dan.random(80, 90) as number, a = 1) {
const h = dan.random(0, 360) as number; // 随机色相
const [r, g, b] = hsv.rgb([h, s, v]); // 转成RGB
return `rgba(${r},${g},${b},${a})`;
}
/**
* 根据指定颜色生成同色系的主题色
* @param color
* @returns
*/
export function generalThemeColor(color: string, s = 80, v = dan.random(80, 90) as number, a = 1) {
const rgbValue = color.match(/\d+/g) as unknown as RGB;
const [h] = rgb.hsv(rgbValue); // 得到色相值
const [r, g, b] = hsv.rgb([h, s, v]);
return `rgba(${r},${g},${b},${a})`;
}
总结
这套方案是我自己摸索出来的,从开发者角度来说确实很好用。最后,放一个我的小程序码,自行体验吧。
如果觉得不错,可以关注我的公众号【末日码农】,我会将开发中遇到的实际问题和一些好的技术知识分享给大家。
最后,感谢阅读。