Model HSV nawiązuje do sposobu, w jakim widzi ludzki narząd wzroku, gdzie wszystkie barwy postrzegane są jako światło pochodzące z oświetlenia. Według tego modelu wszelkie barwy wywodzą się ze światła białego, gdzie część widma zostaje wchłonięta a część odbita od oświetlanych przedmiotów.
H – odcień światła (ang. Hue) wyrażona kątem na kole barw przyjmująca wartości od 0° do 360°;
S – nasycenie koloru jako promień podstawy (wartości od 0 do 1);
V – moc światła białego (wartości od 0 do 1)
Tyle teorii, jak narysować pełen zakres kolorów HSV (tęcza) w CANVAS?
W pierwszej kolejności potrzebna nam będzie funkcja zamieniająca kolor HSV na RGB, który może być użyty w generowaniu grafiki (javascript “nie rozumie” kolorów w formacie HSV):
<script type="text/javascript"> function hsvToRgb(h, s, v){ var r, g, b; if (s == 0){ r = v;g = v;b = v; return {r:Math.round(r * 255), g:Math.round(g * 255), b:Math.round(b * 255)}; } h /= 60; var i = Math.floor(h); var f = h - i; var p = v * (1 - s); var q = v * (1 - s * f); var t = v * (1 - s * (1 - f)); switch( i ) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; default: r = v; g = p; b = q; break; } return {r:Math.round(r * 255), g:Math.round(g * 255), b:Math.round(b * 255)}; }//-------------------------------- </script>
Czas przygotować obszar roboczy – np. o wymiarach 360 x 100 px, tak aby każda barwa (stopnień obrotu – wartość H) miała swoją reprezentacje na grafice. Następnie w pętli przeglądamy wszystkie kolory HSV zgodnie z zasadą:
H – od 0 do 360
S = 1
V = 1
Tak więc pętla będzie mieć 360 iteracji a w każdej będzie generowany kolor RGB odpowiadający kolejnym stopniom (parametr H) koloru HSV.
Do rysowania kolorów wykorzystamy standardową funkcję CANVAS – createLinearGradient, co pozwoli ograniczyć liczbę operacji w pętli z 360 do 72 – próbkowanie koloru będzie następować co 5 pikseli, pozostałe miejsce wypełni za nas funkcja, tworząc gradient.
<canvas id="bitmap" width="360" height="100">brak obslugi canvas</canvas> <script type="text/javascript"> var bitmap = document.getElementById('bitmap'); if ( ! bitmap.getContext) { alert('brak obslugi getContent'); return false; } var c = bitmap.getContext('2d'); var rgb; c.beginPath(); //1 grad = c.createLinearGradient(0, 0, 360, 0); // 1 for (i=0;i<=360;i+=5) { rgb = hsvToRgb(i, 1, 1); grad.addColorStop(i/360, "rgb("+rgb.r+", "+rgb.g+","+rgb.b+")"); } c.fillStyle = grad; c.fillRect(0, 0, 360, 100); c.stroke(); //1 </script>
Rezultat: