关于前端:如何封装一个颜色选择ColorPicker组件

42次阅读

共计 3729 个字符,预计需要花费 10 分钟才能阅读完成。

本篇文章次要分两局部来解说,首先带你进一步认识一下 色彩模型 相干的概念,而后在此基础上封装一个本人的 ColorPicker 组件。

同时,在文章结尾处将分享一个前端小技巧,不要错过哦!

色彩模型

咱们平时开发中,常常用到的色彩模型次要是 十六进制 RGB两种,浏览器所反对的色彩模型还有 色彩标识符 HSL。作为前端开发人员,根本只须要依据设计稿给出的色值,复制过去就能够了,然而如果要封装一个色彩抉择组件,却不得不理解一下这几种色彩模型的原理。

RGB 和十六进制

其中最直观的色彩模型应该就是 RGB 了,这个比较简单,它次要是将色彩分为了 3 个通道 redgreenblue,就别离对应RGB。而后每一个通道又分成了 256(0~255)个级别,来示意色彩的强度。依据屏幕的三原色原理,就能够合成咱们须要的各种色彩了,它所能示意的色彩就有256 ** 3 = 16777216 种,曾经远远超过人眼所能辨认的色彩范畴了。

十六进制也是属于 RGB 色彩模型,只是展现的模式不一样而已。它将 RGB 所示意的十进制数值转成十六进制来示意,每个色彩通道(0~255)十六进制就是(00~FF),并也 # 号结尾。

举例:

  1. 所有色彩通道为 0 时,体现进去的色彩就是全黑,RGB 示意 rgb(0,0,0),十六进制示意#000000 或者#000
  2. 所有色彩通道为 255 时,体现进去的就是全白,RGB 示意 rgb(255,255,255),十六进制示意#ffffff 或者#fff;
  3. 同理,蓝色、绿色、红色就是各自通道的数值设置最大,其余通道的数值设置最小。

尽管 RGB 三通道模型很直观,也能示意那么多的色彩,然而很显然,很难通过人来调出本人想要的色彩。因为当咱们须要一个色彩时,很难人为把控哪个通道的色彩须要多一点,哪个色彩通道设置小一些。专业人士可能会依据教训大略能调进去,然而对于咱们的用户小白,基本上就是大刀阔斧了。

HSL 和 HSV(很要害)

针对上述问题,咱们就不得不理解一下其余两个色彩模型了:HSLHSV。这两个色彩模型很类似,所以放在一起说了,搞明确了这两个色彩显示原理,就能够玩出很多花色了。

HSL 次要是将色彩分为了 色相(H:hue)、饱和度(S:saturation)、亮度(L:lightness) 三个通道,其中最重要的就是色相(H)了。

色相 H 就是基于红、绿、蓝三原色用一个 360°的圆环来示意,红色位于 0°,绿色位于 120°,蓝色位于 240°。并且在红色和绿色之间 60°地位减少了 黄色 ,绿色和蓝色之间 180°地位减少了 青色 ,蓝色和红色之间 300°地位减少 洋红色。而后通过这 6 种颜色进行适度,就得出的一个 360°的色相环。

饱和度 S 就是指色彩的强度或者说纯度,通过百分比 0~100% 来示意。数值越大,色彩看起来就越娇艳,数值越小,看起来就越黯淡。所出现进去的就是从灰色到色相色彩的适度。

亮度 L 就是示意色彩的明暗水平,也是用百分比 0~100% 来示意。次要反馈的就是色彩中的黑、白两种色彩,小于 50% 时,混入的彩色就越多,大于 50% 的时候,混入的红色就越多。当数值为 0 时,体现进去的色彩就是纯黑,数值为 100% 时,体现进去的色彩就是纯白,不论另外两个通道数值为多少的时候。

HSV模型和 HSL 模型一样,H 也是示意色相,不同的是 S 和 V(value)。

饱和度 S 尽管也是指色彩的纯度,但它反映进去的是混入红色的值,值越大,混入红色越少,色彩就越纯,值越小,混入的红色就越多。数值为 0 时,体现进去的就是纯白。

明度 V 它所体现的明暗水平是指混入彩色的水平。数值越小,混入彩色就越多,数值越大,混入的彩色就越少。数值为 0 时,体现的就是纯黑。

组件 UI 的实现

理解了这些色彩模型的原理,那咱们当初就能够开始上代码了。

仔细的同学应该发现了,为什么要介绍 HSV 模型呢?浏览器其实是不反对该色彩模型的。这其实次要是为了封装组件的须要,当初市面上的色彩抉择组件,基本上都是依据 HSV 色彩模型实现的。至于为什么,一种是为了对立吧,一些共识的规范不要去扭转它;第二个应该也是不便 UI 的实现,须要将这些三维的色彩模型开展成二维,而 HSV 开展后更合乎人的直观视觉。

怎么开展?

  • 个别是将 色相 H 开展成一维的线形(通过 0°~360°的圆环或者是线段示意);
  • 饱和度 S 明度 V 开展成二维的矩形,x轴示意饱和度 S,y轴示意明度 V;
  • 如果须要 透明度 A ,另外再减少一条一维的线段。下面没有着重介绍透明度,因为这些色彩模型透明度都是一样的,算是一个通用的色彩通道吧。

上面看 UI 的实现(留神:组件基于 uniapp + vue3,只展现局部代码):

色相的实现

<view class="hue"></view>
.hue {
  /* 色相:从左到右顺次为 红、黄、绿、青、蓝、洋红,等分突变 */
  background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%);
}

饱和度和明度矩形的实现

<!-- 对比度和明度的矩形 -->
<view class="sv" :style="{background: hColor}">
  <view class="s-mask">
    <view class="v-mask"></view>
  </view>
</view>

其中 hColor 示意色相环中抉择的色彩。

.s-mask {
  /* 饱和度 x 轴实现:从左到右,纯白 >>> 通明的突变 */
  background: linear-gradient(to right, #fff, rgba(255, 255, 255, 0));
}
.v-mask {
  height: 150px;
  /* 明度 y 轴的实现:从下到上,纯黑 >>> 通明的突变 */
  background: linear-gradient(to top, #000, rgba(0, 0, 0, 0));
}

放一张最终的效果图:

如果想看具体成果,能够去我的微信小程序体验,搜寻【涂图了】就能够找到。

组件逻辑的实现

用到的第三方库:

  • color-convert

次要是为了不同色彩模型之间数值的转换,如果你有工夫,也能够去理解他们之间的转换算法,本人实现。

定义组件的props

const props = defineProps({
  value: {
    type: String,
    default: '#000',
  },
});

为了兼容所有的色彩模型,在拿到 props 参数之后,都须要转成咱们组件外部实现的 HSV 模型。

const setDefaultValue = (color: string) => {let defaultHSV: HSV = [0, 0, 0];
  if (/^#/.test(color)) {defaultHSV = hex.hsv(color);
  } else if (/^rgb/.test(color)) {defaultHSV = rgb.hsv(color.match(/\d+/g) as unknown as RGB);
  } else if (/^hsl/.test(color)) {defaultHSV = hsl.hsv(color.match(/\d+/g) as unknown as HSL);
  } else if (/^hsv/.test(color)) {defaultHSV = color.match(/\d+/g) as unknown as HSL;
  }

  console.log(color, '===> hsv', defaultHSV);
}

在拿到 HSV 的各个数值之后,就能够对咱们的组件进行初始化了。因为代码量较多,就不贴代码了,大略就是对 拖拽控件 的偏移量进行初始化。

同时,在组件外部批改了色彩之后,也须要通过事件传出去,不要忘了将 HSV 模型转成浏览器能辨认的模型。

const emit = defineEmits<{(event: 'change', value: string): void;
}>();

触发机会能够是实时的 touchmove,也能够是在touchend 时,或者在组件外部加一个 确认 按钮来触发。依据集体需要以及性能来衡量,我是在 touchend 时触发 change 事件的。

对于色彩抉择组件 ColorPicker 的封装就到这里了。最初,再分享一个干货小福利。

色彩转换小技巧

如何疾速将其余色彩模型转换成 RGB 呢?

间接看代码:

const $div = document.createElement('div');
$div.style.color = 'red';
document.body.appendChild($div);

const colorRGB = window.getComputedStyle($div).color;
console.log(colorRGB); // rgb(255, 0, 0)

document.body.removeChild($div);

将下面代码间接复制到你的浏览器控制台试一下,其次要是通过浏览器原生的 APIgetComputedStyle来实现的,它能够将浏览器反对的任意色彩,主动转换成 RGB/RGBA 来返回。

最初

感激你的浏览,如果感觉不错,记得点赞和分享!

对于文章中组件的实现成果可参考我的小程序【涂图了】进行体验,同时也能够关注我的公众号【末日码农】,获取更多技术相干常识~

正文完
 0