Как сделать заданный цвет немного темнее или светлее?

У меня есть эта картина:

цвета

Стрелки показывают два разных цвета, но на самом деле они должны быть одного цвета, но немного светлее или темнее.

Я сделал этот снимок экрана приложения, которое я делаю, и коричневатый цвет по краям - это просто синий цвет в сумме с 30. Как вы можете видеть, это не помогает, т.е. добавление 30 к фактическому цвету не будет работать для всех цвета.

фактические цвета

Как я могу просто затенить заданный цвет, т.е. сделать его ярче или темнее?

И что мне делать, если я хочу, чтобы он выглядел полупрозрачным с альфой?

Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что его следует задать в stackoverflow.
Технически это все еще вопрос графического дизайна, так как мы обсуждаем математику, лежащую в основе цветов и затенения цветов, создавая различные варианты цветов.
нет, мы обсуждаем шестнадцатеричное преобразование. Я был бы согласен с вопросом о цвете, но вы так сильно связали это со своей вычислительной средой, что это больше не удовлетворяет вашим требованиям. Таким образом, вы слишком указали, что это вопрос о javascript и разметке, а не о графическом дизайне.
Нет, вопрос говорит правильно, что я должен сделать, чтобы сделать цвет темнее или ярче. Преобразование в шестнадцатеричное значение является полезным дополнением, но не необходимостью.
тогда шестнадцатеричное число не имеет значения, и в этом случае ответ следует преобразовать в hsl asjust lighteness и преобразовать обратно в rgb. Помимо того, что вы задаете вопрос о программировании
Я не собираюсь спорить. Я не понимаю цвета и то, как они работают, я просил «как это сделать», а не кусок кода, который кто-то напишет для меня.

Ответы (3)

Крутой вопрос.

Чтобы работать с шестнадцатеричными значениями, вам нужно думать об относительной пропорции значений RGB.

Я буду использовать шкалу в цифрах, а не в буквах, чтобы мы могли видеть математику, стоящую за ней.

Представьте, что у вас есть апельсин.

Вы можете иметь значение R255 G128 B0

Если вы хотите получить более темный цвет, вам нужно уменьшить значения, например, на 50%.

Это даст вам R128 G64 B0 Обратите внимание, что все цвета были изменены с использованием пропорционального масштаба.

Более сложный цвет может быть R255 G200 B100 Затемним его, но не так сильно, как в предыдущем случае. Давайте просто затемним его на 80%.

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

Чтобы сделать один цвет светлее, идея почти такая же, но это более сложно, потому что цвета будут ограничены 255, поэтому вы можете подумать о разнице между 255 и вашими значениями.

Например тот же апельсин

R255 G128 B0

Вы больше не можете увеличить R, и вы не можете увеличить зеленый и синий с теми же значениями, например, еще на 100, потому что у вас будет

Р255 Г228 Б100

что слишком желто.

Математика была бы

1) Разница от 255 до текущего значения (R255 G128 B0) составляет: R0 G127 B255

2) Сделаем оранжевый светлее на 50%

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

4) Добавьте это к исходному значению: R255+0 G128+64 B0+128 = R255 G192 B128.

Я добавляю изображение, чтобы дать вам основную идею. Значения RGB не совпадают с моим текстом, просто потому, что это ленивая работа, но вы можете видеть, что оранжевые «лестницы» сохраняют свои внутренние пропорции.

введите описание изображения здесь

Отредактировано

Я такой тупой. Вы также можете использовать нотацию цвета HSL:

{background-color: hsl(45, 60%, 70%);} и измените третий цвет на более темные, а второй и третий на более светлые.

Вы также можете использовать вариант hsla для включения альфы.


Отредактировано: а вот и вторая часть о прозрачности.

Восстановление прозрачности, утраченной при наложении одноцветного изображения на белое

Конечно, если это браузер, он вполне способен вычислить это для вас.
Да приложение JS/браузер. Но Js не распознает форматированный цвет #345464. Я использую parseInt(hashString.replace('#', ''), 16); где hashString — это цвет в формате CSS, например #345464.
Вы переводите свои числа как вам угодно. Я сказал, что использовал числа, чтобы вы могли увидеть математику, стоящую за этим. Но принцип тот же. 8 — это половина F.
И вы всегда можете использовать нотацию rgba(255,128,0,1).
На самом деле я использую элемент Canvas, и это чистый JS, без использования CSS. Но у меня появилась идея, как решить это с помощью кода.
@Vlad Шестнадцатеричное значение представляет собой 3 числа, соединенных вместе, но логотип преобразования tge вы можете найти в stackoverflow, потому что это, по крайней мере, вопрос о stackoverflow. я опубликую код, как только вернусь домой.

Вы немного неправильно поняли, javaScript не моделирует цвет как шестнадцатеричный, как и система. Шестнадцатеричная нотация предназначена только для удобочитаемого документа. Внутри ваша система хранит три целочисленных значения. Вы можете запрашивать и манипулировать ими напрямую.

Но давайте просто скажем, что вы хотите манипулировать фактическим документом, а не внутренними компонентами системы. Тогда лучше отложить ваши вычисления в какую-нибудь библиотеку, которая сделает это за вас. Вы видите, что браузер может представлять цвета разными способами, поэтому вам нужно будет запрограммировать все виды случаев, таких как входные данные ad rgb и hsv. Поэтому я предлагаю вам использовать что-то вроде Color.js, это избавит вас от головной боли, так как вам не нужно самостоятельно реализовывать смешивание, затемнение, осветление и т. д.

Эдити:

В случае, если вы хотите сделать это самостоятельно, что я не рекомендую. Начните с преобразования шестнадцатеричного представления в числовые триплеты целых чисел или чисел с плавающей запятой в диапазоне 0-1, это упростит вычисления.

Теперь для простой манипуляции с цветом преобразуйте значения RGB в HSL или HSB, что делает вычисления яркости тривиальными (в Википедии есть формулировки). Тогда просто добавьте или уберите легкость или яркость. Для имитации реального освещения достаточно просто вычислить цвет света, умножив его на базовый цвет. Таким образом, для нейтрального света это просто:

Результат = Интенсивность*Цвет

Как объяснил Рафаэль, формула повторяется по цветовому каналу. Вы можете имитировать цветной свет, выполнив

Результат = Интенсивность * Цвет освещения * Цвет

Для этого лучше всего сначала преобразовать в число с плавающей запятой, возможно, также в линейное. Это позволяет освещать помещение теплым или холодным светом, что создает ощущение большей естественности.

Альфа-смешивание (наложение цвета поверх другого) просто

Результат = ColorTop * альфа + ColorBottom * (1-альфа)

Окончательное редактирование

Наконец, вот некоторый код, который делает что-то для того, что вы просите. Причина, по которой это трудно увидеть, заключается в том, что сейчас это своего рода абстрактная форма. Активный код доступен здесь

введите описание изображения здесь

Изображение 1 : Результат кода ниже см. также живую версию .

{
  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 вы должны спросить на stackoverflow, так как большую часть этого уже можно найти на stackoverfow.

Может ли эта библиотека быть автономной?
@ Влад, уверен, я не вижу причин, почему бы и нет.
Я пробовал, в нем используются некоторые модули NodeJS, но я не хочу перегружать приложение сторонними библиотеками. Попробую сделать свой код.
@Vlad добавил код для скальпирования
:D вау, фантастическая работа!

Вручную, если вы хотите изменить темноту/яркость цвета вручную и даже не глядя на него. в шестнадцатеричном формате или rgb очень легко просто добавить или вычесть равное количество света для каждого канала.
Скажем, в rgb у вас есть 132 145 167 лет, вы можете добавить 30 к каждому числу, чтобы получить более светлую версию того же цвета, то есть 162 175 207, и если вы понимаете, что немного перестарались, вычтите 2 из каждого, так что 160 173 205. То же самое с шестнадцатеричными, но в шестнадцатеричных числах. поэтому e4c3d5 равно e4 c3 d5, вы можете добавить 16, чтобы сделать его светлее f4d3e5, или вычесть 16, чтобы сделать более темную версию того же цвета d4b3c5.
Вы можете добавлять или вычитать столько, сколько хотите, и вы будете лучше угадывать правильную сумму, чтобы добавить и вычесть сверхурочно, пока вы добавляете одну и ту же сумму ко всем трем каналам (всем трем числам), вы только измените, как много белого вы добавляете или удаляете из смеси.

Прохладный! Это было так просто и полезно для не кодера!