cover_image

颜色转化在前端的实践与应用

浮生 Genebox研发团队
2021年05月25日 08:32

在前端研发领域,提到颜色可谓难分难舍,本篇内容将带你了解颜色的基本构成和相互转换的基础内容,以及在前端的应用实践。


解决了什么问题


正常情况下前端只需要按照设计师给出的UI稿复制粘贴颜色即可,但凡事总会有例外。

因为我们的UI稿中颜色标注使用的是 Hex code 模式,所以总会遇到一些与透明度相关的问题:


  • 半透明背景,父级如果整体设置透明度,会影响到内部元素,需要增加一个定位遮罩去兼容。

  • 不透明元素标注了透明度,设计师调色时只改了颜色的透明度,实际元素却不能透明,导致标注色和实际颜色有出入。


图片

半透明背景


图片

不透明元素标注了透明度


如果你也遇到了这些问题,那么本文带你从颜色转换的角度去解决这些标注上的bug。(ps:再也不用跟设计师去扯皮了~)


红绿蓝还是红黄蓝?


提到颜色最初的认知可能就是光的三原色了吧,三原色指色彩中不能再分解的三种基本颜色。可是问到三原色分别是什么却出现了两种答案,那这两种答案是怎么来的呢?


其实并不是说有人记错了,现实中确实存在两种颜色体系,只是所运用的领域不一样而已。


  • 光的三原色:红、绿、蓝。三色相加是白色,是加色模式,即黑色环境中用光后环境变亮了。用于电视机、电脑等领域。

  • 色的三原色:红、黄、蓝(又称:品、青、黄)。三色相加是黑色,是减色模式,即在白色材料上使用颜料后让它变暗了。用于印刷、染料等领域。


图片


颜色模式


作为前端来说日常使用中常用到的是 RGB 和 Hex code 的颜色模式因此其他模式这里不会去讲解。


  • RGB:rgb(x,x,x),其中 0 ≤ x ≤ 255 如(0,0,0)。三个 x 分别代表 红、绿、蓝。


  • Hex code:#FFFFFF,即# + 六位十六进制数。按两位一组分别代表红、绿、蓝。


对进制转换比较敏感的同学可能已经注意到了,Hex模式的十六进制 FF 换成十进制刚好等于 RGB 中的 255,因此会有如下所示:


图片


RGB 与 Hex code 互转


其实按上文规律已经可以实现两种颜色模式的相互转化了,为了让大家能更好的认识转化规则在这里贴上作者的转化代码供大家参考。


// Hex => RGBconst hexReg = /(.){2}/g;const hexStr = '#0A5FF0';const hexArr = hexStr.slice(1).match(hexReg);const RGBArr = hexArr.map(item => parseInt(item, 16));const RGBStr = `rgb(${RGBArr.join(',')})`;
// RGB => Hexconst RGBReg = /(\d){1, 3}/g;const RGBStr = 'rgb(10,95,240)';const RGBArr = RGBStr.match(RGBReg);const HexArr = RGBArr.map(item => {  // 以RGB第一位为例:'10' => 10 => 'A' => '0A'  return (item * 1).toString(16).toUpperCase().padStart(2, 0);});const HexStr = `#${HexArr.join('')}`;


图片


到此我们已经实现了两种颜色模式的相互转化,那么对于文章开头的问题好像还是没有解决哈~


RGB与RGBA


如果你了解 RGBA 的话其实本文第一个问题已经解决了!

RGBA是代表Red(红色)Green(绿色)Blue(蓝色)和Alpha的色彩空间。虽然它有的时候被描述为一个颜色空间,但是它其实仅仅是RGB模型的附加了额外的信息。


所以说 RGBA 只是比 RGB 多了一个Alpha(透明度)的信息(取值在 0-1之间),当我们将 Hex code 颜色转成RGB后就可以通过这个参数去控制透明度了。(eg:rgba(0,0,0,0.5))


颜色的叠加


叠加指在一个基础背景色(eg:#FFFFFF)上层覆盖另一个加了透明度(eg: 50%)的颜色(eg: #0A5FF0),两个颜色叠加区域产生新的颜色。直接上图:

图片


有些同学可能疑惑了,上图中前景色没有叠加到的地方跟叠加区域看着一样哈?我们试试在黑色背景上叠加的效果:


图片


如上所示,新生成的颜色由背景色、前景色、前景色透明度共同决定的。所以综上所示,如果我们可以通过计算得到叠加后的颜色,那么一些因为设计师对颜色只改透明度出现的标注误差就可以完美解决了。直接上公式:

// 颜色叠加计算const RGBReg = /(\d){1,3}/g;const opacity = 0.5;const upperColor = 'rgb(10,95,240)';const lowerColor = 'rgb(255,255,255)';const upperArr = upperColor.match(RGBReg);const lowerArr = lowerColor.match(RGBReg);const resultArr = upperArr.map((item, index) => {  // 将RGB三个系数分别进行计算得出结果  return upperArr[index] * opacity + lowerArr[index] * (1 - opacity)});const resultStr = `rgb(${resultArr.join(',')})`;

上边示例的最后结果是:rgb(132.5,175,247.5),所以我们在计算的时候应该加一个取整的操作,动手尝试一下吧!


总结


有了颜色计算后不仅解决了文章开头的这些问题,像我们和设计师相互沟通后对我们App的色调通过颜色计算生成了系列色去使用,不仅方便快捷还可以保证颜色的协调性。其他的适用地方就看大家怎么发掘了。

图片



继续滑动看下一个
Genebox研发团队
向上滑动看下一个