2017-07-24 4 views
2

Ich habe x Mengen von Arrays, die Geschwindigkeitswerte enthalten.Berechnen von Farbwert (r, g, b) mit Javascript

Die Werte sind in m/s und ich weiß nicht, wie viele es sind und wie groß sie sind. Ich muss eine Funktion erstellen, um zu entscheiden, welche Farbe verwendet werden soll.

war meine Idee, den max und min Wert des Arrays zu finden (die Geschwindigkeiten), und da ich die Werte sind alle teilbaren mit 0,25 wissen wollte ich die mögliche Menge von „Stufen“ zählen, indem var steps = (max - min)/0.25

tun

Da ich ein RGB-Spektrum habe, dachte ich, ich könnte irgendwie berechnen, welchen Wert ich verwenden soll, aber ich kann mir einfach nicht vorstellen, was ich tun soll.

Was ich erreichen möchte, war, langsamere Geschwindigkeiten red'ish, mittlere Geschwindigkeiten grün'ish und schnelle Geschwindigkeiten blau'ish zu haben.

könnte ein Beispiel sein, dass ich ein Array habe:

speeds = [0.5, 0.5, 0.75, 1.25, 0.50, 0.75, 1.00, 4.00, 4.50, 8.00, 7.50, 8.50, 6.50, 6.00, 5.00, 5.25, 4.75, 4.00, 3.25, 2.50, 1.25, 0.00] 

Nun, für jeden Wert, den ich mich eine Farbe berechnen will, wo die größten Werte, je größer sie sind (in den blauen intensiver sein werden Spektrum - etwas wie (0, 0, 255)), während die kleineren Werte intensiver sind (im roten Spektrum - (255, 0, 0)), desto niedriger sind sie. Und für die mittleren Werte dachte ich, sie könnten intensiver in der grünen Farbe (0, 255, 0) sein, wenn sie absolut in der Mitte ist, und dann entweder ein bisschen rot oder blau hinzufügen, basierend auf welcher Seite sie sich neigen.

Ich habe versucht, nach einem Plugin zu suchen, das dies für mich tun könnte, aber ich bin nicht in der Lage, solche zu finden und ich habe auch versucht, für einen Weg zu googeln, aber ohne Glück.

Antwort

1

Eine andere Möglichkeit wäre, den Wert hsl einfach zu berechnen, da Sie die genauen Farben bereits kennen. Konvertieren von HSL zu RGB sollte nicht zu schwer sein, es gibt viele Bibliotheken da draußen, die das sehr gut machen.

Hier ist ein Beispiel.

var speeds = [0.5, 0.5, 0.75, 1.25, 0.50, 0.75, 1.00, 4.00, 4.50, 8.00, 7.50, 8.50, 6.50, 6.00, 5.00, 5.25, 4.75, 4.00, 3.25, 2.50, 1.25, 0.00]; 
 
var fragment = document.createDocumentFragment(); 
 
var list = document.querySelector('ul'); 
 
var speedsMin = Math.min(...speeds); 
 
var speedsMax = Math.max(...speeds); 
 
var hslMin = 0; 
 
var hslMax = 240; 
 

 
var hslValues = speeds.map(function(value) { 
 
    return { 
 
    h: Math.ceil(((value - speedsMin)/(speedsMax - speedsMin)) * (hslMax - hslMin) + hslMin), 
 
    s: 100, 
 
    l: 50 
 
    } 
 
}) 
 

 
hslValues.forEach(function(value) { 
 
    var item = document.createElement('li'); 
 
    var color = 'hsl(' + value.h + ',' + value.s + '%,' + value.l + '%)'; 
 
    item.style.backgroundColor = color; 
 
    fragment.appendChild(item) 
 
}) 
 

 
list.appendChild(fragment)
ul { 
 
    list-style-type: none 
 
    margin: 0; 
 
    padding: 0; 
 
} 
 

 
ul li { 
 
    width: 20px; 
 
    height: 20px; 
 
    border-radius: 10px; 
 
    display: inline-block; 
 
    margin: 0 4px 
 
}
<ul></ul>

+0

Das sieht gut aus. Allerdings muss ich meine Geschwindigkeit in der Reihenfolge verwenden, in der sie ankommen, also ist es keine gute Idee für mich, sie zu sortieren. Aber ich denke, dass ich deine Funktion immer noch verwenden kann, wenn ich die Min- und Max-Werte anders bekommen kann – Zeliax

+0

Keine Notwendigkeit, sie zu sortieren, nur gedacht, dass es besser aussieht;). Ich habe einen Schnitt gemacht. – DavidDomain

+0

Ich stimme zu, dass es besser aussieht, aber ich verwende die Farbe für Punkte auf einer Karte und sie werden nicht vollständig in Ordnung kommen. Danke trotzdem. Das hat einwandfrei funktioniert! : D – Zeliax

1

Wenn Sie nicht dagegen sind, eine Bibliothek zu verwenden, können Sie D3.js, speziell das Dienstprogramm zum Erstellen benutzerdefinierter Maßstäbe, auschecken. Ein Beispiel für dieses can be found here

Beispiel

Sie benötigen würden Ihre Farbskala mit Ihrer Geschwindigkeit Array als domain und die Farben als die Ausgabe range einzurichten:

let colors = d3.scale.linear().domain([0, Math.max(...speeds)]) 
    .interpolate(d3.interpolateHcl) 
    .range([d3.rgb('#FF0000'), d3.rgb('#0000FF')]); 

colors jetzt ist eine Funktion, die bei Eingabe eines Indexes eine Farbe ausgibt. Danach eingerichtet, Schleife durch die speeds Array die entsprechende Farbe zu erhalten:

for (let i = 0; i < speeds.length; i++) { 
    // colors(i) 
} 
1
var min...,max...; 
var mid=(min+max)/2; 

speeds.foreach(function(x,idx){ 
    var r,g,b; 
    if(x<mid){ 
    b=0; 
    g=255*(x-min)/(mid-min); 
    r=255-g; 
    }else{ 
    r=0; 
    g=255*(max-x)/(max-mid); 
    b=255-g; 
    } 
    // do something with r-g-b here. 
}); 

Die Idee so etwas wie das ist, aber ich habe eine harte Zeit Biege mein Gehirn es nach dem Schreiben zu überprüfen. Ich denke, es ist jetzt ein korrekter Rot-> Grün-> Blau 2-Segment-Gradient.

Über 2-3 Gradient-Segmenten, würde ich nur wirklich eine Palette erstellen.

var r=[];g=[];b=[]; 
// black-red 
for(var i=0;i<256;i++){ 
    r.push(i); 
    g.push(0); 
    b.push(0); 
} 
// red-green 
for(var i=1;i<256;i++){ 
    r.push(255-i); 
    g.push(i); 
    b.push(0); 
} 
// green-blue 
for(var i=1;i<256;i++){ 
    r.push(0); 
    g.push(255-i); 
    b.push(i); 
} 
// blue-white 
for(var i=1;i<256;i++){ 
    r.push(i); 
    g.push(i); 
    b.push(255); 
} 

Dann Sie eine Palette von 1021 Elemente haben, ist Index x*r.length/(max-min)|0.

Eine JavaScript-isch Iteration des letzteren:

var colors=[]; 
// black-red 
for(var i=0;i<256;i++)colors.push({r:i,g:0,b:0}); // black-red 
for(var i=1;i<256;i++)colors.push({r:255-i,g:i,b:0}); // red-green 
for(var i=1;i<256;i++)colors.push({r:0,g:255-i,b:i}); // green-blue 
for(var i=1;i<256;i++)colors.push({r:i,g:i,b:255}); // blue-white 

speeds.foreacy(function(x,idx){ 
    var color=colors[x*colors.length/(max-min)|0]; // r-g-b fields with values 0-255 
    ... 
} 
+0

Denken an Ihre zweite Lösung, wie würde der Ausgang den gewünschten Wert für eine Geschwindigkeit von 4,25 erhalten? Sollte 'x' 4,25 sein? – Zeliax

+0

@Zeliax ja, 'x' ist der tatsächliche Geschwindigkeitswert – tevemadar

+0

Okay.Soweit ich weiß, würde ich für jeden der "Farbbereiche" eine Farbpalette haben (schwarz-rot, rot-grün usw.), aber der Index, den Sie vorschlagen, verwendet nur das rote Array? Wie würde ich eine tatsächliche Farbe erhalten? 'var Farbe = x * r.Länge/(max-min) | 0'? – Zeliax

0

Ich würde diese Anordnung sortieren, und nach diesem teile Array in 3 kleinere Arrays. Nach dieser Operation sollten Sie Ihre Arrays normalisieren. Sie können dies tun, indem Sie jedes Element in der Liste mit der Formel multiplizieren:

(xi - min)/(max - min).

Sie müssen Ihre neuen Arrays nicht die alte normalisieren. Für das erste Array (der kleinste Wert) können Sie rot intensiv durch k=(max-xi)*255.0 zählen. Diese Farben werden (k, 0, 0) sein. Das Array mit den größten Geschwindigkeiten, die Sie mit der Formel färben: k=xi*255.0 [Farben sind (0,0, k)]. Die Formel für mittlere Werte hängt von Ihrer Wahl ab. (Höhere Geschwindigkeit = mehr Grün oder Höhere Geschwindigkeit = weniger Geschwindigkeit).

Entschuldigung für komplizierte Beschreibung. Viel Glück.

+0

Es tut mir leid. Ich kann dieses Verfahren nicht verwenden, da ich die Geschwindigkeiten in der Reihenfolge brauche, in der sie kommen. Vielen Dank für die Freigabe – Zeliax

+0

Sie können sie in ein anderes Array kopieren und ihre Indizes merken. Aber ich habe ein anderes Problem gefunden. Sie sollten 255.0 zu 128.0 ändern und der Formel 128.0 hinzufügen (zum Beispiel: (max-xi) * 128.0 + 128.0), da das Ergebnis in allen Arrays schwarz ist, wenn Sie den kleinsten Wert in den Arrays haben. – gryxon

2

Angenommen min ist die minimale Geschwindigkeit und max ist die maximale Geschwindigkeit, dann werden alle Geschwindigkeiten zwischen min und max:

min |---------------------------| max 
       speeds 

Sie haben dieses Intervall in zwei kleinere Intervalle zu unterteilen, wie folgt aus:

|-------------|--------------| 
min   mid   max 

Sie ordnen können vollen Red auf min, bis Mitte voller Grün und bis max voll Blau:

R    G    B 
|-------------|--------------| 
min   mid   max 

Jetzt muss man für jeden Geschwindigkeitswert seine Farbe berechnen. Nehmen wir an, dass s ist der Wert eines Ihrer Geschwindigkeiten:

r = g = b = 0; 

if (s <= mid) { 
    r = 255 - (s - min)/(mid - min) * 255; // r is 255 when s = min and 0 when s = mid 
    g = 255 - (mid - s)/(mid - min) * 255; // g is 255 when s = mid and 0 when s = min 

} else { 
    b = 255 - (s - mid)/(max - mid) * 255; 
    g = 255 - (max - s)/(max - mid) * 255; 
} 

Angesichts Ihrer Reihe von Geschwindigkeiten, können Sie wie folgt vorgehen:

var speeds = [0.5, 0.5, 0.75, 1.25, 0.50, 0.75, 1.00, 4.00, 4.50, 8.00, 7.50, 8.50, 6.50, 6.00, 5.00, 5.25, 4.75, 4.00, 3.25, 2.50, 1.25, 0.00] 
var max = Math.max(...speeds); 
var min = Math.min(...speeds); 
var mid = (max - min)/2; 

var colors = speeds.map((s) => { 
    var r, g, b; 
    r = g = b = 0; 

    if (s <= mid) { 
     r = 255 - (s - min)/(mid - min) * 255; 
     g = 255 - (mid - s)/(mid - min) * 255; 

    } else { 
     b = 255 - (s - mid)/(max - mid) * 255; 
     g = 255 - (max - s)/(max - mid) * 255; 
    } 

    return [r, g, b]; 
}); 

console.log(colors); 

Das Array colors wird eine [r, g, b] Liste für jede Geschwindigkeit enthalten in speeds.

+0

Dies ist ein sehr gepflegtes Beispiel. Ich werde es versuchen und umsetzen. Vielen Dank! : D – Zeliax

+0

@Zeliax, herzlich willkommen! Ich habe am Ende des Beitrags weitere Informationen hinzugefügt, um weitere Hilfe zu geben. – ninjin

1

Sie können die Farbe der beiden Bereiche berechnen und mit den drei Farben für die Gradienten zu erzeugen.

function getColor(v, min, max) { 
 

 
    function getC(f, l, r) { 
 
     return { 
 
      r: Math.floor((1 - f) * l.r + f * r.r), 
 
      g: Math.floor((1 - f) * l.g + f * r.g), 
 
      b: Math.floor((1 - f) * l.b + f * r.b), 
 
     }; 
 
    } 
 

 
    var left = { r: 255, g: 0, b: 0 }, 
 
     middle = { r: 0, g: 255, b: 0 }, 
 
     right = { r: 0, g: 0, b: 255 }, 
 
     mid = (max - min)/2; 
 

 
    return v < min + mid ? 
 
     getC((v - min)/mid, left, middle) : 
 
     getC((v - min - mid)/mid, middle, right); 
 
} 
 

 
var speeds = [0.5, 0.5, 0.75, 1.25, 0.50, 0.75, 1.00, 4.00, 4.50, 8.00, 7.50, 8.50, 6.50, 6.00, 5.00, 5.25, 4.75, 4.00, 3.25, 2.50, 1.25, 0.00], 
 
    min = Math.min(...speeds), 
 
    max = Math.max(...speeds); 
 

 
speeds.forEach(function (a) { 
 
    var color = getColor(a, min, max); 
 
    document.body.innerHTML += '<span style="color: #fff; background-color: rgb(' + color.r + ',' + color.g + ',' + color.b + ');">' + a + '</span> '; 
 
});

Verwandte Themen