В процессе разработки библиотеки компонентов пользовательского интерфейса компании цветовой компонент ColorPicker не был подробно изучен из-за нехватки времени.Глядя на цветную хроматограмму, я подумал, что это будет очень сложно реализовать, поэтому я напрямую инкапсулировал палитру цветов с открытым исходным кодом. . Это было где-то пол года назад, и эта статья тоже есть в черновике у меня в блоге (только заголовок не имеет содержания, запись я сделал тогда, думая, что потом успею ее изучить, там еще много такие сквозняки на данный момент 😂) Хранится пол года. Некоторое время назад я спросил у коллег из компании по пользовательскому интерфейсу некоторые концепции, связанные с цветом, и искал знания в этой области.Урожай все еще довольно большой, особенно Zhihu.В чем разница между HSL, HSV, HSB в цветовом пространстве?В этом вопросе@ForrestОтвет почти на просторечии, отлично 👍.
После понимания концепций иди посмотри на этот компонент, у нас не было бы такого странного чувства конфликта промышленности. В конце концов понял, что этот компонент,DEMO, и запишите процесс реализации следующим образом:
[Анализ Photoshop Colorizer] Небольшая глава представляет собой краткое изложение некоторых концепций цвета, основанное на статьях Wikipedia и Zhihu. Краткое изложение перспективы развития может быть не очень профессиональным, просто поймите это.
Разбор тонеров Photoshop
Разница между HSL, HSV, HSB
Как внешний интерфейс, мы знаем HEX и RGB, но цветовые понятия HSL, HSV и HSB часто расплывчаты. Как показано на картинке выше, цветовая палитра Photoshop, нижняя часть имеетH,S,B,R,G,BПодождите несколько полей ввода,R,G,BПредставляя цветовые каналы трех основных цветов красного, зеленого и синего, различные цвета могут быть получены путем изменения трех цветовых каналов и наложения друг на друга, что нам хорошо известно. ТакH,S,BЧто это такое?
Фактически,HSBтакой жеRGBТочно так же это также цветовой режим, где H (оттенок) представляет оттенок (какой цвет), S (насыщенность) представляет насыщенность (чистоту цвета), а B (яркость) представляет яркость (яркость цвета). ). По сравнению с режимом RGB цветовой режим HSB более удобен для пользователя.Он определяет цвет "какой цвет? Цвет яркий? Цвет яркий?".
что такое оттенок
Оттенок – это цвет, воспринимаемый человеческим глазом при различных условиях освещения.«Красные, оранжевые, желтые, зеленые, синие, синие и фиолетовые, кто занимается танцами в небе с цветом?», - давно описаны стихи великих людей. В цветовом режиме HSV/HSL оттенок составляет 0 градусов (360 градусов) для красного, 60 градусов для желтого, 120 градусов для зеленого, 180 градусов для голубого, 240 градусов для синего и 300 градусов для пурпурного.Его диапазон значений составляет 0 - 360 градусов.,Как показано ниже:
что такое насыщенность
Насыщенность относится к интенсивности или чистоте цвета.. Насыщенность представляет собой долю компонентов цвета в оттенке, измеряемую в процентах от 0 (прозрачный) до 100% (полностью насыщенный). Чистота является признаком силы восприятия цвета.Цвета с высокой чистотой кажутся человеческому глазу более яркими.
Что такое легкость
Светлота – это относительная светлота и темнота цвета. Обычно измеряется в процентах от 0 (черный) до 100% (белый).
такой же,HSL,HSVа такжеHSBТочно так же интерпретация цвета основана на трех аспектах оттенка, насыщенности и светлоты. Среди них HSB и HSV — это одно и то же, но название другое. Мы будем использовать HSV для его представления позже.
Разница между тремя цветовыми рисунком, почти известным (конец прилагаемой ссылке) имеет очень легко понять ответы:
В принципе и производительности H (оттенок) в HSL и HSB абсолютно одинаковы, но S (насыщенность) у них разные, а также L и B (яркость):
- S в HSB контролирует количество белого, смешиваемого с сплошным цветом, чем больше значение, тем меньше белого и тем чище цвет;
- B в HSB управляет количеством черного, подмешанного к сплошному цвету, чем больше значение, тем меньше черного и выше яркость.
- S в HSL не имеет ничего общего с черным и белым, и насыщенность не контролирует количество черного и белого, смешанных с цветом;
- L в HSL управляет смешиванием черного и белого цветов в сплошном цвете.
Три диапазона выражений значений HSV: H [0-360] float S [0-1] float V [0-1] float
Приведенные выше концепции могут быть не очень профессиональными, просто поймите.Если мы используем процедурное мышление для объяснения вышеупомянутых концепций, это означает, что если мы смешаем различные степени черного и белого в цвет, мы можем изменить его на другое значение цвета, как показано ниже:
R,G,BВ дополнение к трем цветовым каналам вы также можете передать оттенокH,насыщенностьS, яркостьVОстальные три канала используются для передачи цвета.
Процесс реализации
HSVоснование для стоимости.
«Мой муж в руках, у меня есть мир». Исходя из изложенных выше концепций и идей, нам нужно только рассчитать цветовую фазу через координатыH,насыщенностьS, яркостьVТри значения, вы можете преобразовать его в цвет в указанном формате.- Насыщенность/яркость, насыщенность и значение из панели, состоящей из двух слоев. Значения левой координаты, используемые для расчета значений насыщенности ползунка, Верхнее значение, используемое для расчета яркости;
- Левое значение значения координат слайдера цветной фазной панели используется для расчета значения цветного фазы;
- Левое значение координаты ползунка панели прозрачности используется для расчета прозрачности.Прозрачность является дополнением к цвету и не имеет ничего общего с самим цветом;
- в конечном итоге произвел
HSVAЧетыре значения будут преобразованы в разные цветовые форматы по разным алгоритмам;
Реализация панели насыщенности/яркости
С точки зрения непрофессионала, насыщенность — это то, сколько белого «примешано» к сплошному цвету, а яркость — это то, сколько черного «примешано» к сплошному цвету; эти величины выражаются в процентах, а их значения варьируются в0% ~ 100%.
Насыщенность идет слева направо, чем меньше белого примешивается, тем выше чистота цвета. То есть белый, смешанный в крайнем левом углу панели, достигает пика чистого белого, в то время как белый, смешанный в крайнем правом углу, почти прозрачен, что представляет собой радиальный градиент слева направо, от белого к прозрачному; по той же причине можно получить Out, легкость может быть представлена радиальным градиентом снизу вверх, от чисто черного до полностью прозрачного. Поскольку большинство областей этих двух градиентов прозрачны, когда различные оттенки, такие как красный, оранжевый, желтый, зеленый, синий, синий и фиолетовый, устанавливаются ниже этих двух слоев, вся область будет формировать цветовой спектр. Как показано ниже:
::before/::afterПсевдоэлементы для реализации слоев насыщенности и осветления.
макет
<div class="mo-color-sat-val">
<!-- 饱和度渐变元素 -->
::before
<!-- 滑块 -->
<div class="mo-color-thumb" role="slider" tabindex="0">
<span></span>
</div>
<!-- 明度渐变元素 -->
::after
</div>
.mo-color-sat-val {
position: relative;
// 色相将直接作用于面板的背景色上
background: transparent;
&::before,
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
// 饱和度 一条从左往右,由纯白到透明的径向渐变
&::before {
background: linear-gradient(to right, white, transparent);
}
// 明度 一条从下往上,由纯黑到透明的径向渐变
&::after {
background: linear-gradient(to top, black, transparent);
}
}
Рассчитать значения S и V по координатам
Когда ползунок свободно скользит по панели, положение ползунка является значением координат, необходимым для вычисления значений S и V. Как скользить и вычислять координаты не является предметом этой статьи, вы можете напрямуюСправочный исходный код, который я инкапсулировал какDraggableКласс, который генерирует координату во время процесса скольжения и возвращает экземпляр через ряд функций-ловушек.
// 初始化$sat面板的Draggable类
states.satDragIns = new Draggable(states.$sat, {
drag: satDrag,
end: satDrag
})
function satDrag (coordinate: Coordinate) {
// satWidth 面板的宽度
// satHeight 面板的高度
// 饱和度和明度的范围都是从 0 - 100 的一个百分比值,为了便于计算,这里直接保存为小数, 坐标原点是左下角
const saturation = Math.round(coordinate.left / satWidth * 100) / 100
const value = Math.round((1 - coordinate.top / satHeight) * 100) / 100
}
Сбросить цвет фона панели при изменении оттенка
Последнее кольцо панели «Насыщенность/Яркость» предназначено для установки цвета фона панели при изменении оттенка таким образом, чтобы формировался окончательный цветовой спектр (как на видео выше). Вам нужно только сгенерировать цвет в формате hsl из значения H, сгенерированного после изменения оттенка (обратитесь к реализации оттенка):
states.$sat.style.background = `hsl(${h}, 100%, 50%)`
реализация оттенка
0 deg: 红色
1/6 deg: 黄色
2/6 deg: 绿色
...
5/6 deg: 品红色
360 deg: 红色
макет
Преобразуется в окончательный код CSS следующим образом:
// 色相
.mo-color-hue>.mo-color-rail {
background: linear-gradient(to right, #f00 0%, #ff0 16.66%, #0f0 33.33%, #0ff 50%, #00f 66.66%, #f0f 83.33%, #f00 100%);
}
<div class="mo-color-hue">
<!-- 渐变条 -->
<div class="mo-color-rail"></div>
<!-- 滑块 -->
<div class="mo-color-thumb" role="slider" tabindex="0">
<span></span>
</div>
</div>
Рассчитать значение H по координатам
// 通过left坐标和hue元素宽度计算出比例值,然后乘以360度计算出当前位置所处的度数
hue = Math.round((left / hueWidth) * 360 * 100) / 100
Достижение прозрачности
Реализация панели прозрачности самая простая, а фоновая сетка также генерируется с помощью CSS-градиентов.Подробности можно найти в этой статье CSS God Zhang Xinxu "Введение в CSS Paint API".
макет
<!-- 格子背景直接作用在容器上 -->
<div class="mo-color-alpha">
<!-- 颜色背景层 -->
<div class="mo-color-rail"></div>
<div class="mo-color-thumb" role="slider" tabindex="0">
<span></span>
</div>
</div>
.mo-color-alpha {
background-color: white;
background-image: linear-gradient(45deg, #c5c5c5 25%, transparent 0, transparent 75%, #c5c5c5 0, #c5c5c5), linear-gradient(45deg, #c5c5c5 25%, transparent 0, transparent 75%, #c5c5c5 0, #c5c5c5);
background-size: 10px 10px;
background-position: 0 0, 5px 5px;
}
Рассчитать значение прозрачности по координатам
alpha = Math.round(left / alpWidth * 100) / 100
Измените цвет фона цветного слоя при изменении оттенка
const hsl = hsv2hsl(h, s, v)
states.$alpRail.style.background = `linear-gradient(to right, transparent, hsl(${hsl.h}, ${hsl.s * 100}%, ${hsl.l * 100}%))`
Как и выше, мы получаем то, что необходимо для генерации цветаH,S,VТри важных параметра. С этими тремя параметрами можно передать алгоритм преобразования цвета, такой какhsv2rgbи т. д., конвертировать три параметра hsv в значения цвета в разных форматах.Что касается алгоритма конвертации, то эта статья расширяться не будет.этот сайтПодробный список алгоритмов преобразования различных цветов можно найти здесь.
Совет: как проверить допустимость цвета
Нельзя не учитывать, что палитра цветов может получать входящие значения от пользователя, а сам компонент ColorPicker имеет встроенныйsetValueметод, мы не можем гарантировать, что пользователь передал допустимое значение цвета, так как же проверить, является ли цвет допустимым? Сначала я рассматривал возможность использования регулярных выражений для проверки, но, поскольку это потребовало бы передачиrgb(260, 260, 260)Такое значение, выходящее за пределы допустимого диапазона для определенного канала, сложнее проверить. Затем я установил неправильный цвет для элемента в браузере Chrome и обнаружил, что Chrome автоматически понизил цвет до белого, затем, если цветовому стилю DOM назначен неправильный цвет, а затем получить цвет, а затем проверить, полученный цвет соответствует входящему цвету, можно ли его использовать как основу для проверки? Chrome прошел этот тест, другие браузеры — нет.
При меньшем количестве тестов этот трюк может быть проблематичным.
/**
* 校验颜色是否合法
* 测试用例较少,该技巧可能存在问题
*
* 原理,如果颜色不合法,将会被转换为rgb(255,255,255)
* 只需验证设置后的颜色是否等于传入的颜色
* @param color
*/
function checkColor(color: string) {
// todo
const style = new Option().style
style.color = color
return style.color === color
}
// 只负责将传入的值转换为 h, s, v 三个通道值,而不去校验值是否超出范围或有效
function parseColor(color) {
// hex2hsv
if (HEX_REG.test(color)) {}
// rgb2hsv
if (RGB_REG.test(color)) {}
// ...
return {
h,
s,
v,
a
}
}
setValue (color) {
const { h, s, v, a } = parseColor(color)
const {r, g, b} = hsv2rgb(h, s, v,)
if (checkColor(`rgb(${r},${g},${b})`)) {
// todo
}
}
исходный код
Эта статья была впервые опубликована вмой блог