工作中的那点事之 组件
记录一下工作中实现的基础组件的思路。
颜色选择器
实现原理
利用 hsv 色系,将颜色拆分成 hue(色相)、Saturation(饱和度)、Value(亮度)三部分。
也可叫
hsb色系。Bright(明度)
其中 Saturation 组件负责saturation、value的变化,Hue组件负责 hue 的变化。

上图中,红色是Saturation组件,蓝色则是Hue组件。
Hue 的背景色可以直接使用下面的。算是一个标准。
react-color、ant-design都是
1 | |
计算公式:Saturation:
1 | |
Hue:
1 | |
公式简解:
色相的取值在 0-360 之间。所以计算出比例后需要乘以 360。而饱和度和亮度的取值在 0-1 之间,可以不做处理。
亮度需要用1 - y / height,是因为mouseY - top得到的结果是鼠标点距离顶部的距离,而亮度的值应该是鼠标点到底部的距离,所占的比例。
数据结构
这里颜色的值采用的是
number类型,需要转成 16 进制才能获取到hex字符串。下图中的value就是对应的number类型

Saturation、Hue都维护自己的一套数据结构。
初始值由父组件ColorPicker的value控制。
因为Saturation控制饱和度、亮度,Hue控制色相。所以它们的改动会互相影响,所以暴露方法,修改自身的状态。比如Hue控制的色相发生变化了,需要让Saturation修改它的色相值。
每个组件都维护自己的一套数据结构,通过暴露方法来修改自身状态这种方式,不会出现色系转换后的精度丢失问题。导致的问题就是会有抖动现象。因为
rgb转换成hsv色系后,可能是无限不循环小数,再转换成rgb,值会有偏差。
颜色转换算法可以参考:
https://gist.github.com/mjackson/5311256
有问题版本

这个版本的数据结构可以比较容易看出色系转换的问题。
这个版本的数据结构由
ColorPicker控制,其他组件都是基于value进行一些转换。会出现问题:色相变化时,Hue需要把hsv转换成value,让父组件修改value。同时,父组件修改后的值又反过来修改Hue的值,就会出现抖动问题。
日期选择器(日历)
核心
1 | |
注意:
- 上面的
month是从 0 开始计数的,0-11。 getDay返回值中,0 代表星期天,1 代表星期一,依此类推getDate可以返回一个指定的日期对象为一个月中的哪一日(从 1–31)。new Date()的第三个参数为 0 时,可以获取上个月的总天数。
通过上面这两个主要的方法,再拓展一下,就可以实现日期选择器了,包括支持选中范围等功能。