RN 获取渐变色的进度条当前滑动的进度色

672 阅读1分钟

原因

最近遇到这样一个需求,UI 设计图如下所示

截屏2022-10-13 10.32.42.png

需求分析

首页我们需要做一个渐变色背景的进度条,然后用户在滑动过程中要实时获取当前进度条上对应的颜色,并在展示在标题色温后面。我们都知道展示渐变色可以用组件 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;
    }
}