Jak sprawić, by dany kolor był nieco ciemniejszy lub jaśniejszy?

9

Mam to zdjęcie:

zabarwienie

Strzałki pokazują dwa różne kolory, ale w rzeczywistości powinny być tego samego koloru, ale nieco jaśniejsze lub ciemniejsze.

Zrobiłem zrzut ekranu z aplikacji, którą wykonuję, a brązowawy kolor na krawędziach to po prostu niebieski kolor zsumowany z 30. Jak widać, nie robi to sztuczki, tzn. Dodanie 30 do rzeczywistego koloru nie będzie działać dla wszystkich zabarwienie.

rzeczywiste kolory

Jak mogę tylko przyciemnić dany kolor, tzn. Uczynić go jaśniejszym lub ciemniejszym?

Co też powinienem zrobić Jeśli chcę, żeby wyglądało półprzezroczysto z alfa?

Vlad
źródło
Głosuję za zamknięciem tego pytania jako nie na temat, ponieważ należy je zadać przy przepływie stosu.
joojaa
3
Technicznie jest to wciąż pytanie projektowe, ponieważ omawiamy matematykę kolorów i cieniowania kolorów, tworząc różne warianty kolorów.
Vlad
1
nie, omawiamy konwersję szesnastkową. Byłbym w porządku z pytaniem dotyczącym koloru, ale tak mocno związałeś to ze środowiskiem obliczeniowym, że nie spełnia ono Twoich oczekiwań. Tak, jak już określiłeś, staje się pytaniem o javascript i znaczniki, a to nie jest projekt graficzny.
joojaa
1
Nie, pytanie brzmi dobrze, co powinienem zrobić, aby kolor był ciemniejszy lub jaśniejszy. Konwersja na wartość szesnastkową jest użytecznym dodatkiem, ale nie jest koniecznością.
Vlad
1
Nie zamierzam się kłócić. Nie rozumiem kolorów i tego, jak działają, prosiłem o „jak”, a nie o fragment kodu, który ktoś będzie dla mnie kodował.
Vlad

Odpowiedzi:

13

Fajne pytanie.

Aby pracować z wartościami szesnastkowymi, musisz pomyśleć w kategoriach względnej proporcji wartości RGB.

Użyję skali w liczbach, a nie liter, aby zobaczyć matematykę za nią.

Wyobraź sobie, że masz pomarańczę.

Możesz mieć wartość R255 G128 B0

Jeśli chcesz uzyskać ciemniejszy kolor, musisz zmniejszyć wartości, na przykład o 50%

To da ci R128 G64 B0 Zauważ, że wszystkie kolory zostały zmodyfikowane przy użyciu skali proporcjonalnej.

Bardziej złożonym kolorem może być R255 G200 B100 Przyciemnijmy go, ale nie tak bardzo jak w poprzednim przypadku. Po prostu przyciemnijmy to o 80%.

R255x0,8 G200x0,8 B100x0,8 = R204 G160 B80

Aby rozjaśnić jeden kolor, pomysł jest prawie taki sam, ale jest to trudniejsze, ponieważ kolory zmienią się na 255, więc możesz pomyśleć o różnicy między 255 do swoich wartości.

Na przykład ten sam pomarańczowy

R255 G128 B0

Nie możesz już powiększać R i nie możesz zwiększać Zielonego i Niebieskiego o te same wartości, na przykład o 100 więcej, ponieważ będziesz miał

R255 G228 B100

który jest zbyt żółty.

Matematyka byłaby

1) Różnica między wartością 255 a bieżącą (R255 G128 B0) wynosi: R0 G127 B255

2) Zróbmy jaśniejszy pomarańczowy o 50%

3) Rx50% Gx50% Bx50% = R0 G64 B128

4) Dodaj to do swojej wartości początkowej: R255 + 0 G128 + 64 B0 + 128 = R255 G192 B128.

Dodaję obraz, aby dać ci podstawowy pomysł. Wartości RGB nie są takie same jak w moim tekście, tylko dlatego, że leniwa praca, ale widać, że pomarańczowe „schody” zachowują swoje dokładne proporcje.

wprowadź opis zdjęcia tutaj

Edytowane

Jestem taki głupi. Możesz także użyć notacji HSL Color:

{kolor tła: hsl (45, 60%, 70%);} i zmodyfikuj trzeci kolor dla ciemniejszych kolorów, a drugi i trzeci dla jaśniejszych.

Możesz także użyć wariantu hsla, aby dołączyć alfa.

Rafael
źródło
Zjedź, jeśli jest to przeglądarka, która jest w stanie ją obliczyć
joojaa
Tak, aplikacja JS / przeglądarki. Ale Js nie rozpoznaje sformatowanego koloru # 345464. Używam parseInt (hashString.replace ('#', ''), 16); gdzie hashString to kolor sformatowany w CSS, taki jak # 345464.
Vlad
Tłumaczysz swoje liczby, jak chcesz. Powiedziałem, że używałem liczb, abyś mógł zobaczyć matematykę. Ale zasada jest taka sama. 8 to połowa F.
Rafael
I zawsze możesz użyć notacji rgba (255,128,0,1).
Rafael
Właściwie używam elementu Canvas i jest to czysty JS, bez wpuszczania CSS. Ale wpadłem na pomysł, jak rozwiązać ten problem za pomocą kodu.
Vlad
2

Trochę źle zrozumiałeś, javaScript nie modeluje kolorów jako szesnastkowych, podobnie jak system. Notacja szesnastkowa jest przeznaczona tylko dla dokumentu czytelnego dla człowieka. Wewnętrznie twój system przechowuje trzy wartości całkowite. Możesz je odprawiać i manipulować nimi bezpośrednio.

Powiedzmy jednak, że chcesz manipulować rzeczywistym dokumentem zamiast wewnętrznych elementów systemu. Następnie najlepiej odłożyć obliczenia na bibliotekę, która robi to za Ciebie. Widzisz, że przeglądarka może reprezentować kolory na wiele sposobów, więc musisz zaprogramować wszelkiego rodzaju przypadki, takie jak dane wejściowe ad rgb i hsv. Sugeruję więc użycie czegoś takiego jak Color.js , dzięki czemu oszczędzasz dużo bólu głowy, ponieważ nie musisz samodzielnie mieszać, przyciemniać, rozjaśniać itp.

Edycja:

Jeśli chcesz to zrobić sam, czego nie polecam. Zacznij od przekształcenia prezentacji szesnastkowej w tryplety liczbowe liczb całkowitych lub liczb zmiennoprzecinkowych z zakresu 0-1, co ułatwia obliczenia.

Teraz w celu łatwej manipulacji konwersją kolorów wartości RGB na HSL lub HSB sprawia, że ​​obliczenia jasności są trywialne (Wikipedia ma formuły). Więc po prostu dodaj lub odejmij jasność lub jasność. Do symulacji prawdziwego światła obliczenia są dość proste - wystarczy pomnożyć kolor światła przez kolor podstawowy. Zatem dla światła neutralnego jest to po prostu:

Wynik = Intensywność * Kolor

Jak wyjaśnił Rafael, formuła powtórzona przez kanał kolorów. W ten sposób możesz symulować kolorowe światło

Wynik = Intensywność * LigtColor * Kolor

Aby to najlepiej przekonwertować na najpierw zmiennoprzecinkowe, może także liniowe. Pozwala to na ciepłe lub chłodne światło w Twojej okolicy, które może zapewnić bardziej naturalny efekt.

Mieszanie alfa (nakładanie warstw na inne) jest po prostu

Wynik = ColorTop * alpha + ColorBottom * (1-alfa)

Ostateczna edycja

Wreszcie, oto kod, który robi coś w stosunku do tego, o co pytasz. Powodem, dla którego trudno to dostrzec, jest to, że jest to teraz rodzaj abstrakcyjnej formy. Aktywny kod dostępny tutaj

wprowadź opis zdjęcia tutaj

Zdjęcie 1 : Wynik kodu poniżej patrz także wersja na żywo .

{
  var canvas = document.getElementById('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    var Color = function(r, g, b) {
      this.r = r;
      this.g = g;
      this.b = b;
    }
    Color.prototype.asHex = function() {
      return "#" + ((1 << 24) + (this.r << 16) + (this.g << 8) + this.b).toString(16).slice(1);
    }
    Color.prototype.asRGB = function() {
      return 'rgb(' + this.r + ',' + this.g + ',' + this.b + ')';
    }
    Color.prototype.blendWith = function(col, a) {
      r = Math.round(col.r * (1 - a) + this.r * a);
      g = Math.round(col.g * (1 - a) + this.g * a);
      b = Math.round(col.b * (1 - a) + this.b * a);
      return new Color(r, g, b);
    }
    Color.prototype.Mul = function(col, a) {
      r = Math.round(col.r/255 * this.r * a);
      g = Math.round(col.g/255 * this.g * a);
      b = Math.round(col.b/255 * this.b * a);
      return new Color(r, g, b);
    }
    Color.prototype.fromHex = function(hex) {
      // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
      hex = hex.substring(1,7)
      var bigint = parseInt(hex, 16);
      this.r = (bigint >> 16) & 255;
      this.g = (bigint >> 8) & 255;
      this.b = bigint & 255;
    }

    ctx.font = "16px Arial";
    ctx.fillText("Manual Alpha Blend", 18, 20);

    var a = new Color(220, 0, 150);

    var b = new Color();
    b.fromHex('#00C864');

    //Alpha blend
    ctx.fillStyle = a.asHex();
    ctx.fillRect(25, 25, 100, 100);
    ctx.fillStyle = '#FFFFFF';
    ctx.fillText(a.asHex(), 30, 45);
    ctx.fillStyle = b.asRGB()
    ctx.fillRect(50, 50, 100, 100);
    ctx.fillStyle = '#FFFFFF';
    ctx.fillText(a.asHex(), 55, 145);
    var bl = a.blendWith(b, 0.3);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(50, 50, 75, 75);
    ctx.fillStyle = '#FFFFFF';
    ctx.fillText(bl.asHex(), 55, 70);

    // lighten 1

    ctx.fillStyle = '#000000';
    ctx.fillText('Neutral Light', 200, 20);

    var c = new Color(100, 100, 100);
    var purelight= new Color(255, 255, 255);

    ctx.fillStyle = c.asRGB();
    ctx.fillRect(200, 25, 100, 100);

    var bl = c.Mul(purelight,1.2);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(225, 50, 100, 100);

    var bl = c.Mul(purelight, 0.8);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(250, 75, 100, 100);

     // lighten 2

    ctx.fillStyle = '#000000';
    ctx.fillText('Yellowish Light', 400, 20);

    var c = new Color(100, 100, 100);
    var yellowlight= new Color(255, 255, 220);

    var bl = c.Mul(yellowlight,1.0);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(400, 25, 100, 100);

    var bl = c.Mul(yellowlight,1.2);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(425, 50, 100, 100);

    var bl = c.Mul(yellowlight, 0.8);
    ctx.fillStyle = bl.asRGB();
    ctx.fillRect(450, 75, 100, 100);
  }
}

PS, powinieneś zapytać o przepływie stosów, ponieważ większość z nich można już znaleźć w przepływie stosów.

joojaa
źródło
Czy ta biblioteka może być samodzielna?
Vlad
@Vlad na pewno nie widzę powodu, dla którego nie.
joojaa
Próbowałem, używa niektórych modułów NodeJS, ale nie chcę obciążać aplikacji bibliotekami stron trzecich. Spróbuję stworzyć własny kod.
Vlad
@Vlad dodał kod do skalpu
joojaa
: D wow, fantastyczna robota!
Vlad
1

Ręcznie, jeśli chcesz ręcznie zmienić ciemność / jasność koloru, nawet na niego nie patrząc. w trybie szesnastkowym lub rgb jest naprawdę łatwe, wystarczy dodać lub odjąć równą ilość światła dla każdego kanału.
Powiedz, że w rgb masz 132 145 165, możesz dodać 30 do każdej liczby, aby uzyskać jaśniejszą wersję tego samego koloru, więc 162 175 155, a jeśli uznasz, że to zrobiłeś, to odejmij 2 od każdej 160,173,205. To samo z hexem, ale w liczbach hex. więc e4c3d5 to e4 c3 d5, możesz dodać 16, aby rozjaśnić f4d3e5 lub odjąć 16, aby uzyskać ciemniejszą wersję tego samego koloru d4b3c5.
Możesz dodawać lub odejmować tyle, ile chcesz, a będziesz lepiej odgadywać odpowiednią kwotę do dodawania i odejmowania w czasie, o ile dodasz tę samą kwotę do wszystkich trzech kanałów (wszystkich trzech liczb), zmienisz tylko sposób, w jaki dużo bieli dodajesz lub usuwasz z mieszaniny.

Ricardex mistrz
źródło
Fajne! To było tak łatwe i pomocne dla niekodującego!
brookdancer