如何自动计算背景颜色导航项目

时间:2015-01-26 19:28:52

标签: jquery html css

让我们说我有一个导航菜单。在该菜单中,链接到页面(震撼右)。我希望每个链接的背景颜色不同,但要通过两种定义颜色之间的百分比设置。

例如,假设我选择#000和#fff作为我的颜色。我想通过SASS说第一项背景颜色总是#000,最后一项背景颜色总是#fff。但是,根据导航菜单中的项目数量,将拉动百分比,并且相应的颜色停止将用于"之间的"项目背景。

以下是一个例子,以防我失去任何人:

第一个颜色渐变代表4个菜单项。每个项目的位置从100%平均分配,并产生颜色停止。该数字成为所述项目的背景。

第二个颜色渐变表示5个菜单项。其他一切都适用,但现在计算了5个项目。

enter image description here

我的用途是不想手动输入大量的:n-child选择器。如果他们添加/删除项目,那么:第n种颜色规则不再适用。如何用css和jQuery做到这一点?

2 个答案:

答案 0 :(得分:2)

好的,这是我的尝试,我会尝试尽可能地评论代码:D 假设您在HTML中有4个div:

<div data-color-start=#000" data-color-end="#fff" id="wrapper">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
</div>

然后我们需要jQuery代码来计算div的数量,计算背景颜色然后将添加到我们的div中:

(在潜入之前,可以优化)

// returns an array (so we can use easily in getColors)
function parseHex( hexCode ) {
    var returned;
    if( hexCode.length === '4' ) {
        returned[0] = parseInt( hexCode[1], 16 ); // transforsm in a normal number, lie you would use in rgb()
        returned[1] = parseInt( hexCode[2], 16 );
        returned[2] = parseInt( hexCode[3], 16 );
    }
    else {
        //i suppose this is the case like #012345
        returned[0] = parseInt( hexCode.substring( 1,3 ), 16 ); //same thing like above but we substring'ed the hexCode
        returned[1] = parseInt( hexCode.substring( 3,5 ), 16 );
        returned[2] = parseInt( hexCode.substring( 5 ), 16 );
    }

    return returned; // so we return the array
}


// gets the colors based on the parameters, returns array
function getColors( startColor, endColor, number ) {
    var startArr = parseHex( startColor );
    var endArr = parseHex( endColor );
    var ratioOne, ratioTwo, ratioThree;
    var i=0;
    var colors; // the returned array
    var temp; //used as temporary variable in for loop
    var one, two, three; // this will store bool values
    // let's say we have rgb(100,0,20) to rgb(10,200,10)
    // we have for RED to decrease the value of our gradient
    // for GREEN to increase it
    // for BLUE to decrease it
    one = startArr[0] < endArr[0]; //so true if we have to increase it
    two = startArr[1] < endArr[1];
    three = startArr[2] < endArr[2];

    // now basically we will find the ratio of each R, G, B, and make the gradient based on it
    ratioOne = Math.floor( (Math.abs( (startArr[0] - endArr[0] ) )+1) / (number-1) );
    ratioTwo = Math.floor( (Math.abs( (startArr[1] - endArr[1] ) )+1) / (number-1) );
    ratioThree = Math.floor( (Math.abs( (startArr[2] - endArr[2] ) )+1) / (number-1) );

    // store the first gradient
    colors[0] = 'rgba(' + startArr[0] + ',' + startArr[1] + ',' + startArr[2] + ')';
    for( i=1; i<(number-1); i+=1 ) {
        colors[i] = 'rgba(';
        if( one ) {
            temp = startArr[0] + ratioOne*i;
        }
        else {
            temp = startArr[0] - ratioOne*i;
        }
        colors[i] += temp;
        colors[i] += ',';

        if( two ) {
            temp = startArr[1] + ratioTwo*i;
        }
        else {
            temp = startArr[1] - ratioTwo*i;
        }
        // we modify the temp variable each time, so this is not a problem
        colors[i] += temp;
        colors[i] += ',';

        if( three ) {
            temp = startArr[2] + ratioThree*i;
        }
        else {
            temp = startArr[2] - ratioThree*i;
        }
        colors[i] += temp;
        colors[i] += ')';
    }

     // i will be just one more than the i which our for loop ended
    colors[i] = 'rgba(' + endArr[0] + ',' + endArr[1] + ',' + endArr[2] + ')';

    return colors; // we now have all the colors from our gradient
}

var wrapper = $('#wrapper'); // store this, will be used later
var startColor = wrapper.data('color-start'); // remember the HTML ?
var endColor = wrapper.data('color-end');
var elements = wrapper.find('.child'); // now store the links from the header
var elLength = elements.length; // get the number of links in the menu

var colors = getColors( startColor, endColor, elLength );

for( var i=0; i<elLength; i+=1 ) {
    elements[i].style('background-color', colors[i]);
}

所以你在html中存储第一种颜色和最后一种颜色,然后js代码将内联样式附加到每个链接/ div /无论背景颜色(通过rgb颜色)。你向我们展示的渐变是通过数学函数完成的(例如f(x)= x;或类似的smth)。这就是为什么你可以用ratioOneratioTworatioThree来计算rgb颜色

我希望我没有犯任何错误,希望你能得到这个想法。如你所知,这不能通过SASS完成,只有JS(因为你想写更少的代码,嗯?)

答案 1 :(得分:1)

首先,我认为最好用Javascript而不是通过css或SASS实现。我不太熟悉SASS的所有功能,但我的理解是SASS在运行时被编译成CSS,因此你无法动态更新页面上的列表。

使用javascript,您可以动态添加或删除列表中的项目并更新颜色。

好的,怎么做。 首先,将值存储为rgb颜色,而不是Hex。因此,在上面的示例中,您将为黑色存储0,0,0,为白色存储255,255,255。

然后在渲染页面时,找到中间值就像计算你拥有的元素数一样简单 - 这就是你需要的步数,并除以每个值对之间的距离,开始和结束r,g,和b。

使用background-color:rgba(x,x,x,1)设置背景颜色,你应该好好去。

这里有一些快速而又脏的javascript代码,可以为你计算步骤

var startingRGB = [0,0,0];
var endingRGB = [255, 255, 255];
var steps = 5;

var eachStep = [
    (endingRGB[0] - startingRGB[0])/(steps-1),
    (endingRGB[1] - startingRGB[1])/(steps-1),
    (endingRGB[2] - startingRGB[2])/(steps-1)
];

var backgrounds = [];

for(var i = 0; i < steps; i++){
    backgrounds.push([
        Math.abs(startingRGB[0] + (eachStep[0] * i)),
        Math.abs(startingRGB[1] + (eachStep[1] * i)),
        Math.abs(startingRGB[2] + (eachStep[2] * i))
    ]);
}   

运行此步骤,背景将为每个步骤提供一组rgb值。

[0,0,0], [63.75,63.75,63.75], [127.5,127.5,127.5], [191.25,191.25,191.25],      
[255,255,255]