2015-01-26 54 views
1

可以说我有一个导航菜单。并在该菜单中,链接到页面(令人震惊的权利)。我希望每个链接的背景颜色不同,但通过两个定义的颜色之间的百分比设置。如何自动计算导航项目背景颜色

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

下面是一个例证,以防万一我失去了任何人:

第一色阶代表4个菜单项。每个项目的位置从100%平分,并产生一个由此产生的颜色停止。该数字成为该项目的背景。

第二个颜色渐变表示5个菜单项。其他一切都适用,但现在已经为5件物品进行了计算。

enter image description here

我给这家使用自带不想手动键入吨:第n个孩子选择。如果他们添加/删除项目,那么:第n个颜色规则不再适用。如何用css和jQuery做到这一点?

+0

调整OP以更好地问问题,因为SCSS不能访问DOM。 – bmoneruxui 2015-01-26 19:37:54

+0

谢谢@rageandqq调整 – bmoneruxui 2015-01-26 19:44:05

+0

为什么不在菜单容器中只有一个渐变,并且没有任何菜单项的背景? – 2015-01-26 20:20:14

回答

1

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

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

好的,该怎么做。 首先,将值存储为rgb颜色,而不是十六进制。所以在你上面的例子中,你将存储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] 
1

好吧,这里是我的尝试,我会尽量注释代码尽可能:d 让我们假设你有4个格在HTML:

<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 #
     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

我希望我没有犯任何错误,并希望你能明白这个想法。正如你已经知道的,这不能通过SASS完成,只有JS(因为你想写更少的代码,呃?)