Je devais créer un éventail suffisamment large d'options de couleurs pour un ensemble inconnu d'éléments dynamiques, mais j'avais besoin que chaque élément s'incrémente en passant par une couleur de début et une couleur de fin. Cela suit en quelque sorte l'approche du "pourcentage de fondu", sauf que j'ai eu du mal à suivre cette logique. Voici comment je l'ai abordé en utilisant des entrées de deux valeurs de couleur rgb et en calculant le nombre d'éléments sur la page.
Voici un lien vers un codepen qui démontre le concept.
Vous trouverez ci-dessous un extrait de code illustrant le problème.
<style>
#test {
width:200px;
height:100px;
border:solid 1px #000;
}
.test {
width:49%;
height:100px;
border:solid 1px #000;
display: inline-block;
}
</style>
</head>
<body>
<div id="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<script>
var GColor = function(r,g,b) {
r = (typeof r === 'undefined')?0:r;
g = (typeof g === 'undefined')?0:g;
b = (typeof b === 'undefined')?0:b;
return {r:r, g:g, b:b};
};
// increases each channel by the difference of the two
// divided by 255 (the number of colors stored in the range array)
// but only stores a whole number
// This should respect any rgb combinations
// for start and end colors
var createColorRange = function(c1) {
var colorList = [], tmpColor, rr = 0, gg = 0, bb = 0;
for (var i=0; i<255; i++) {
tmpColor = new GColor();
if (rExp >= 0) {
tmpColor.r = Math.floor(c1.r - rr);
rr += rAdditive;
} else {
tmpColor.r = Math.floor(c1.r + rr);
rr += rAdditive;
}
if (gExp >= 0) {
tmpColor.g = Math.floor(c1.g - gg);
gg += gAdditive;
} else {
tmpColor.g = Math.floor(c1.g + gg);
gg += gAdditive;
}
if (bExp >= 0) {
tmpColor.b = Math.floor(c1.b - bb);
bb += bAdditive;
} else {
tmpColor.b = Math.floor(c1.b + bb);
bb += bAdditive;
}
console.log(tmpColor);
colorList.push(tmpColor);
}
return colorList;
};
/* ==================
Testing Code Below
================== */
var firstColor = new GColor(255, 24, 0);
var secondColor = new GColor(255, 182, 0);
// Determine the difference
var rExp = firstColor.r - secondColor.r;
// Divide that difference by length of the array
// you would like to create (255 in this case)
var rAdditive = Math.abs(rExp)/255;
var gExp = firstColor.g - secondColor.g;
var gAdditive = Math.abs(gExp)/255;
var bExp = firstColor.b - secondColor.b;
var bAdditive = Math.abs(bExp)/255;
var range = createColorRange(firstColor, secondColor);
console.log(range);
var pointer = 0;
// This gently cycles through
// all the colors on a single element
function rotateColors() {
var currentColor = range[pointer];
document.getElementById("test").style.backgroundColor = "rgb("+currentColor.r+","+currentColor.g+","+currentColor.b+")";
pointer++;
if (pointer < range.length) window.setTimeout(rotateColors, 5);
}
rotateColors();
// say I have 5 elements
// so I need 5 colors
// I already have my first and last colors
// but I need to locate the colors between
// my start color and my end color
// inside of this range
// so I divide the range's length by the
// number of colors I need
// and I store the index values of the middle values
// those index numbers will then act as my keys to retrieve those values
// and apply them to my element
var myColors = {};
var objects = document.querySelectorAll('.test');
myColors.num = objects.length;
var determineColors = function(numOfColors, colorArray) {
var colors = numOfColors;
var cRange = colorArray;
var distance = Math.floor(cRange.length/colors);
var object = document.querySelectorAll('.test');
var j = 0;
for (var i = 0; i < 255; i += distance) {
if ( (i === (distance*colors)) ) {
object[j].style.backgroundColor = "rgb(" + range[255].r + ", " + range[255].g + ", " + range[255].b + ")";
j = 0;
// console.log(range[i]);
} else {
// Apply to color to the element
object[j].style.backgroundColor = "rgb(" + range[i].r + ", " + range[i].g + ", " + range[i].b + ")";
// Have each element bleed into the next with a gradient
// object[j].style.background = "linear-gradient( 90deg, rgb(" + range[i].r + ", " + range[i].g + ", " + range[i].b + "), rgb(" + range[i+distance].r + ", " + range[i+distance].g + ", " + range[i+distance].b + "))";
j++;
}
}
};
setTimeout( determineColors(myColors.num, range), 2000);
</script>
</body>
1 votes
Ce que vous décrivez est la façon dont je le ferais : il suffit de faire une interpolation linéaire entre les points de départ et d'arrivée pour chacune des trois composantes de couleur.
2 votes
Veuillez noter qu'il existe différents types de dégradés : si vous souhaitez réaliser un dégradé qui passe par le rouge -> jaune -> vert -> bleu, vous devrez probablement obtenir les valeurs HSL plutôt que les valeurs RGB.