前言
好吧,其实这篇文章写起好久了,只是没发,为了跟第一篇对齐,这里就不改了
一:功能分析
在这里查看原型图(非标准原型图),我从中截取了部分:
从图中我们大体可以得到这些功能:
- 数据存储器,需要监听数据并对指定数据进行过滤(擦边球:vue2 和 vue3 的数据监听实现)
- 滑块拖拽实现
- 内部的 change 实现
二:数据存储器的实现
我这里使用的是 canvas 实现的颜色拾取,由于 getImageData
api
的一些特殊特性,需要对数据进行一些修正处理,所以我们的数据存储器需要实现监听功能。
数据存储器对于兼容 [Proxy](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
的浏览器使用 [Proxy](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
进行实现,如果浏览器不兼容 [Proxy](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
则使用 [Object.defineProperty](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)
进行实现。
在此之前,我们先来看下所以的数据定义:
这里没什么好讲的,都是一些数据变量名的定义。
1、使用 Proxy 实现数据存储器
PS:EventLevel
在第一讲《系列之颜色选择器(一):内部事件》进行了详细讲解
2、使用 Object.defineProperty 实现数据存储器
PS:EventLevel
在第一讲《系列之颜色选择器(一):内部事件》进行了详细讲解
3、完整代码
三:滑块拖拽实现
滑块拖拽其实就是监听鼠标在按下状态下的移动。
1、容易进入的思维误区
关于 drag 事件,最直接的想法就是将其绑定直接绑定在滑块上,这样的结果就是:需要另外给父容器绑定 click + drag 事件,否则点击滑块以外的地方将不会做出反应。既如此,何不直接将 drag 事件绑定在父容器上呢,然后反过来设置滑块的位置即可。
2、drag 抽象封装
注:滑块始终在父容器范围内,不会超出父容器
3、drag 事件绑定
四:内部 change 的实现
1、change 事件说明
事件级别说明:
- level 3:色域滑块改变
- level 2:色值滑块改变
- level 1:透明度滑块改变
- level 0:用户自定义 change
由于 change 定义的事件级别,且由 event.emitLessThan
触发,所以它特性如下:
- 大于等于指定级别的事件将被忽略,只会从小于指定级别的事件开始实行
也就是说,当执行 event.emitLessThan('change', 3)
时,只会从 level: 2
开始执行
2、完整代码
3、补充:关于 rfn 对象(不是重点的重点)
结语
好了,颜色选择器中的选择器部分就讲完了,还剩下颜色列表、输出值模式切换和一些小功能就略过了。