У меня есть эта картина:
Стрелки показывают два разных цвета, но на самом деле они должны быть одного цвета, но немного светлее или темнее.
Я сделал этот снимок экрана приложения, которое я делаю, и коричневатый цвет по краям - это просто синий цвет в сумме с 30. Как вы можете видеть, это не помогает, т.е. добавление 30 к фактическому цвету не будет работать для всех цвета.
Как я могу просто затенить заданный цвет, т.е. сделать его ярче или темнее?
И что мне делать, если я хочу, чтобы он выглядел полупрозрачным с альфой?
Крутой вопрос.
Чтобы работать с шестнадцатеричными значениями, вам нужно думать об относительной пропорции значений 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 для включения альфы.
Отредактировано: а вот и вторая часть о прозрачности.
Восстановление прозрачности, утраченной при наложении одноцветного изображения на белое
Вы немного неправильно поняли, 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.
Вручную, если вы хотите изменить темноту/яркость цвета вручную и даже не глядя на него. в шестнадцатеричном формате или rgb очень легко просто добавить или вычесть равное количество света для каждого канала.
Скажем, в rgb у вас есть 132 145 167 лет, вы можете добавить 30 к каждому числу, чтобы получить более светлую версию того же цвета, то есть 162 175 207, и если вы понимаете, что немного перестарались, вычтите 2 из каждого, так что 160 173 205. То же самое с шестнадцатеричными, но в шестнадцатеричных числах. поэтому e4c3d5 равно e4 c3 d5, вы можете добавить 16, чтобы сделать его светлее f4d3e5, или вычесть 16, чтобы сделать более темную версию того же цвета d4b3c5.
Вы можете добавлять или вычитать столько, сколько хотите, и вы будете лучше угадывать правильную сумму, чтобы добавить и вычесть сверхурочно, пока вы добавляете одну и ту же сумму ко всем трем каналам (всем трем числам), вы только измените, как много белого вы добавляете или удаляете из смеси.
джуджа
Влад
джуджа
Влад
джуджа
Влад