原因
最近遇到这样一个需求,UI 设计图如下所示
需求分析
首页我们需要做一个渐变色背景的进度条,然后用户在滑动过程中要实时获取当前进度条上对应的颜色,并在展示在标题色温后面。我们都知道展示渐变色可以用组件 react-native-linear-gradient,但是我看了这个组件提供的 api 并没有获取对应进度上面的颜色,所以我们需要想一个办法,自己去根据比例和对应的渐变色去获取到对应进度的颜色
实现原理
我们假设上面对应的渐变色是由红 绿 蓝三种颜色组成,而且是一种线性渐变,那我们就可以按照比例去计算了。假设我们当前进度是 0.8, 那我们就需要考虑到转换下,因为是由三种颜色组成,真正的线性渐变应该是分成两段,红到绿,和绿到蓝,然后对应进度 0.8就落在了绿到蓝的渐变中,然后我们就可以按照 (0.8 - 0.5)/0.5 这个转换比例,就可以获取到 0.8 在 绿到蓝真正的比例了。最后我们还要在计算的过程中需要将颜色转换成 rgb 这种格式,并按照比例计算对应的 r,g,b,的值,最后组合起来就是对应 0.8 进度对应的颜色了。
代码展示
// 16 进制颜色转成 rgb
function hexToRgb(hex)
{
let rgb = [];
for(let i=1; i<7; i+=2){
rgb.push(parseInt("0x" + hex.slice(i,i+2)));
}
return rgb;
}
// rgb 转换成 16 进制颜色
function rgbToHex(r, g, b)
{
let hex = ((r<<16) | (g<<8) | b).toString(16);
return "#" + new Array(Math.abs(hex.length-7)).join("0") + hex;
}
//计算两个颜色之间的线性颜色
function gradient (startColor,endColor, num)
{
//将hex转换为rgb
let sColor = hexToRgb(startColor),
eColor = hexToRgb(endColor);
//计算R\G\B
let rStep = Math.floor((eColor[0] - sColor[0])*num) + sColor[0];
let gStep = Math.floor((eColor[1] - sColor[1])*num) + sColor[1];
let bStep = Math.floor((eColor[2] - sColor[2])*num) + sColor[2];
return rgbToHex(rStep, gStep, bStep);
}
//传入三种 16 进制颜色比如'#B3DEFF', '#FBFBFB', '#FFD7B3'和进度条当前进度
function getColor (start, center, end, per){
//进度小于 0.5
if(per <0.5){
return gradient(start, center, per/0.5);
}else if( per > 0.5){ // 进度大于 0.5
return gradient(center, end, (per-0.5)/0.5);
}else{ //如果等于 0.5 直接返回中间颜色
return center;
}
}