扁平、简单、可定制的颜色选择器。
完整功能演示
特点
- 🎨 主题
- 🔄 简单使用
- 🚫 零依赖
- 🌈 多种颜色表示方式
- 🔍 颜色对比
- 🎚️ 透明度控制
- 🖱️ 通过鼠标滚轮进行细节调整
- 📱 响应式和自动定位
- 👆 支持触摸设备
- 🎨 快速选择色板
- ♿ 完全无障碍和国际化
- 🌑 支持 Shadow DOM
项目状态
[!重要] 本项目可能会继续获得重要的安全和错误修复更新,但其功能集已冻结,不太可能获得新功能或增强。
做出这个决定的原因是该工具的构建方式(单体结构,核心是一个单一文件,所有内容都是纯 JS 等),这使得维护变得非常困难,在没有完全重写的情况下,测试变得不可能,而且在这种复杂程度下已经失去了乐趣。
个人建议直接使用你正在使用的框架将这些 UI 相关的"小部件"构建到应用程序中,这虽然需要更多时间,但作为回报,你可以完全掌控它的工作方式和外观。像 (p)react、vue 和 svelte 这样的框架可以让你在一天内轻松开发这样的东西。
主题
经典 | 整体 | 迷你 |
---|---|---|
迷你主题使用 CSS Grid,因此在旧浏览器中无法工作。
入门指南
Node
注意:README 始终与最新提交保持同步。有关最新版本的安装说明,请参阅发布版本。
通过 npm 安装:
$ npm install @simonwep/pickr
通过 yarn 安装:
$ yarn add @simonwep/pickr
引入代码和样式:
// 选择以下主题之一
import '@simonwep/pickr/dist/themes/classic.min.css'; // '经典'主题
import '@simonwep/pickr/dist/themes/monolith.min.css'; // '整体'主题
import '@simonwep/pickr/dist/themes/nano.min.css'; // '迷你'主题
// 现代或 ES5 打包版本(请注意下面的说明!)
import Pickr from '@simonwep/pickr';
import Pickr from '@simonwep/pickr/dist/pickr.es5.min';
注意:ES5 打包版本(即遗留版本)相当大(约为现代版本的三倍)。 请考虑使用现代版本,并在最终打包时添加 polyfills! (或者更好的做法是:提示用户应该使用最新的浏览器)。 IE 等浏览器不受支持(至少官方不支持)。
浏览器
jsdelivr:
<!-- 选择以下主题之一 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/classic.min.css"/> <!-- '经典'主题 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/monolith.min.css"/> <!-- '整体'主题 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/nano.min.css"/> <!-- '迷你'主题 -->
<!-- 现代或 ES5 打包版本 -->
<script src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.es5.min.js"></script>
确保在 pickr.min.css
之后加载 pickr.min.js
(或 ES5 版本)。此外,script
标签不适用于 defer
属性。
使用方法
// 简单示例,更多配置请参见可选选项。
const pickr = Pickr.create({
el: '.color-picker',
theme: 'classic', // 或 'monolith',或 'nano'
swatches: [
'rgba(244, 67, 54, 1)',
'rgba(233, 30, 99, 0.95)',
'rgba(156, 39, 176, 0.9)',
'rgba(103, 58, 183, 0.85)',
'rgba(63, 81, 181, 0.8)',
'rgba(33, 150, 243, 0.75)',
'rgba(3, 169, 244, 0.7)',
'rgba(0, 188, 212, 0.7)',
'rgba(0, 150, 136, 0.75)',
'rgba(76, 175, 80, 0.8)',
'rgba(139, 195, 74, 0.85)',
'rgba(205, 220, 57, 0.9)',
'rgba(255, 235, 59, 0.95)',
'rgba(255, 193, 7, 1)'
],
components: {
// 主要组件
preview: true,
opacity: true,
hue: true,
// 输入/输出选项
interaction: {
hex: true,
rgba: true,
hsla: true,
hsva: true,
cmyk: true,
input: true,
clear: true,
save: true
}
}
});
你可以在这里找到更多示例。
事件
从版本 0.4.x
开始,Pickr 是事件驱动的。使用 on(event, cb)
和 off(event, cb)
函数来绑定/解绑事件监听器。
事件 | 描述 | 参数 |
---|---|---|
init | 初始化完成 - 可以使用 pickr | PickrInstance |
hide | Pickr 已关闭 | PickrInstance |
show | Pickr 已打开 | HSVaColorObject, PickrInstance |
save | 用户点击了保存/清除按钮。清除时也会触发,颜色为 null | HSVaColorObject or null, PickrInstance |
clear | 用户清除了颜色 | PickrInstance |
change | 颜色已更改(但未保存)。在 swatchselect 时也会触发 | HSVaColorObject, eventSource, PickrInstance |
changestop | 用户停止更改颜色 | eventSource, PickrInstance |
cancel | 用户点击了取消按钮(返回到之前的颜色) | PickrInstance |
swatchselect | 用户点击了其中一个色板 | HSVaColorObject, PickrInstance |
示例:
pickr.on('init', instance => {
console.log('事件:"init"', instance);
}).on('hide', instance => {
console.log('事件:"hide"', instance);
}).on('show', (color, instance) => {
console.log('事件:"show"', color, instance);
}).on('save', (color, instance) => {
console.log('事件:"save"', color, instance);
}).on('clear', instance => {
console.log('事件:"clear"', instance);
}).on('change', (color, source, instance) => {
console.log('事件:"change"', color, source, instance);
}).on('changestop', (source, instance) => {
console.log('事件:"changestop"', source, instance);
}).on('cancel', instance => {
console.log('事件:"cancel"', instance);
}).on('swatchselect', (color, instance) => {
console.log('事件:"swatchselect"', color, instance);
});
其中 source
可以是
slider
- UI中的任何滑块。input
- 用户输入字段。swatch
- 色板之一。
选项
const pickr = new Pickr({
// 将被实际颜色选择器替换的选择器或元素。
// 可以是一个HTMLElement。
el: '.color-picker',
// pickr应用应该被添加为子元素的位置。
container: 'body',
// 你想使用的主题。可以是'classic'、'monolith'或'nano'
theme: 'classic',
// 目前不支持嵌套滚动,由于添加这个功能会非常复杂,
// 所以更简单的方法是将其设置为true,这样当用户滚动其后面的区域时,pickr会隐藏。
closeOnScroll: false,
// 添加到pcr-app的自定义类。可用于应用自定义样式。
appClass: 'custom-class',
// 不用pickr按钮替换'el'元素,而是将'el'用作按钮。
// 如果为true,appendToBody也会自动为true。
useAsButton: false,
// pickr(小部件)和对应参考(按钮)之间的间隙大小,单位为px
padding: 8,
// 如果为true,pickr将不会浮动,而是会附加在el解析元素之后。
// 仍然可以通过.hide()隐藏它。
inline: false,
// 如果为true,pickr将在页面滚动或窗口调整大小时自动重新定位。
// 可以设置为false以便更容易进行自定义定位。
autoReposition: true,
// 定义色相和不透明度旋钮可以移动的方向。
// 'v' => 不透明度和色相滑块都只能垂直移动。
// 'hv' => 不透明度滑块可以水平移动,色相滑块可以垂直移动。
// 可用于应用自定义布局
sliders: 'v',
// 初始状态。如果为true,'disabled'将被添加到按钮的类列表中。
disabled: false,
// 如果为true,用户将无法调整任何不透明度。
// 不透明度将锁定在1,不透明度滑块将被移除。
// HSVaColor对象也不包含alpha值,所以toString()方法只会
// 打印HSV、HSL、RGB、HEX等。
lockOpacity: false,
// 输出字符串的精度(仅在components.interaction.input为true时有效)
outputPrecision: 0,
// 定义变更/保存行为:
// - 要保持当前颜色不变直到按下保存,设置为`true`,
// - 要在每次变更(从选择器或调色板)时同步应用颜色到按钮和预览(保存),设置为`false`。
comparison: true,
// 默认颜色。如果你使用命名颜色如红色、白色...也要为
// defaultRepresentation设置一个值,因为没有命名颜色的按钮。
default: '#42445a',
// 可选的颜色色板。当为null时,色板被禁用。
// 类型是所有可以被pickr生成的类型,例如hex(a)、hsv(a)、hsl(a)、rgb(a)、cmyk,以及CSS颜色名称如'magenta'。
// 示例:swatches: ['#F44336', '#E91E63', '#9C27B0', '#673AB7'],
swatches: null,
// 输入/输出文本框的默认颜色表示。
// 有效选项为`HEX`、`RGBA`、`HSVA`、`HSLA`和`CMYK`。
defaultRepresentation: 'HEX',
// 保持颜色选择器始终可见的选项。
// 你仍然可以通过'pickr.hide()'和'pickr.show()'来隐藏/显示它。
// 保存按钮保留其功能,所以点击时仍会触发onSave事件。
showAlways: false,
// 通过按键关闭pickr。
// 默认是'Escape'。可以是事件键或代码。
// (参见:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)
closeWithKey: 'Escape',
// 定义颜色选择器的位置。
// 任何top、left、bottom或right的组合,可选修饰符:start、middle、end
// 示例:top-start / right-end
// 如果发生剪裁,颜色选择器将自动选择其位置。
// Pickr使用https://github.com/Simonwep/nanopop作为定位引擎。
position: 'bottom-middle',
// 启用使用滚轮更改输入字段中数字的功能。
// 要使用它,将光标放在一个数字的位置上并滚动,使用ctrl可以五步一跳
adjustableNumbers: true,
// 显示或隐藏特定组件。
// 默认情况下只有调色板(和保存按钮)可见。
components: {
// 定义调色板本身是否应该可见。
// 如果preview、opacity或hue为true,将被覆盖为true
palette: true,
preview: true, // 显示先前状态和新颜色之间的比较
opacity: true, // 显示不透明度滑块
hue: true, // 显示色相滑块
// 在底部交互栏上显示或隐藏组件。
interaction: {
// 按钮,如果你禁用了一个但在default:或setColor()中使用了该格式 - 也要设置representation-type!
hex: false, // 显示'输入/输出格式为hex'按钮(rgba值的十六进制表示)
rgba: false, // 显示'输入/输出格式为rgba'按钮(红绿蓝和alpha)
hsla: false, // 显示'输入/输出格式为hsla'按钮(色相饱和度亮度和alpha)
hsva: false, // 显示'输入/输出格式为hsva'按钮(色相饱和度明度和alpha)
cmyk: false, // 显示'输入/输出格式为cmyk'按钮(青品黄黑)
input: false, // 显示输入/输出文本框,显示选定的颜色值。
// 输入的格式由defaultRepresentation决定,
// 可以通过用户使用hex、rgba、hsla等按钮(上面设置)来更改。
cancel: false, // 显示取消按钮,将颜色重置为之前的状态
clear: false, // 显示清除按钮;与取消相同,但保持窗口打开
save: false, // 显示保存按钮
},
},
// 翻译,这些是默认值。
i18n: {
// UI中可见的字符串
'ui:dialog': '颜色选择器对话框',
'btn:toggle': '切换颜色选择器对话框',
'btn:swatch': '颜色样本',
'btn:last-color': '使用上一个颜色',
'btn:save': '保存',
'btn:cancel': '取消',
'btn:clear': '清除',
// 用于aria-labels的字符串
'aria:btn:save': '保存并关闭',
'aria:btn:cancel': '取消并关闭',
'aria:btn:clear': '清除并关闭',
'aria:input': '颜色输入字段',
'aria:palette': '颜色选择区域',
'aria:hue': '色相选择滑块',
'aria:opacity': '选择滑块'
}
});
通过Shadow-DOM进行选择
示例设置:
<div class="entry">
#shadow-root
<div class="innr">
<div class="another">
#shadow-root
<div class="pickr"></div>
</div>
</div>
</div>
要选择.pickr
元素,你可以在el
中使用自定义的>>
shadow-dom选择器:
el: '.entry >> .innr .another >> .pickr'
查询结果中每个>>
后面的ShadowRoot
都会在下一个查询选择中使用。
另一种方法是直接将目标元素本身作为el
提供。
HSVaColor对象
默认的颜色表示是hsva(色相
、饱和度
、明度
和透明度
),但你也可以将其转换为下列其他格式。
- hsva.toHSVA() - 将对象转换为hsva数组。
- hsva.toHSLA() - 将对象转换为hsla数组。
- hsva.toRGBA() - 将对象转换为rgba数组。
- hsva.toHEXA() - 将对象转换为十六进制数组。
- hsva.toCMYK() - 将对象转换为cmyk数组。
- hsva.clone() - 克隆颜色对象。
toString()
方法被重写,所以你可以获得一个颜色表示字符串。
hsva.toRGBA(); // 返回 [r, g, b, a]
hsva.toRGBA().toString(); // 返回 rgba(r, g, b, a),具有最高精度
hsva.toRGBA().toString(3); // 返回 rgba(r, g, b, a),四舍五入到小数点后第三位
方法
- pickr.setHSVA(h
:Number
,s:Number
,v:Number
,a:Float
, silent:Boolean
) - 设置一个颜色,如果颜色被接受则返回true。 - pickr.setColor(str:
:String | null
, silent:Boolean
):Boolean
- 解析一个表示颜色的字符串(例如#fff
、rgb(10, 156, 23)
)或名称,例如'magenta',如果颜色被接受则返回true。null
将清除颜色。
如果silent
为true(默认为false),按钮不会改变当前颜色。
- pickr.on(事件
:String
, 回调:Function
):Pickr
- 为给定的对应事件名称添加事件监听器(参见事件部分)。 - pickr.off(事件
:String
, 回调:Function
):Pickr
- 从给定的对应事件名称中移除事件监听器(参见事件部分)。 - pickr.show()
:Pickr
- 显示颜色选择器。 - pickr.hide()
:Pickr
- 隐藏颜色选择器。 - pickr.disable()
:Pickr
- 禁用pickr并为按钮添加disabled
类。 - pickr.enable()
:Pickr
- 启用pickr并从按钮移除disabled
类。 - pickr.isOpen()
:Boolean
- 如果颜色选择器当前处于打开状态,则返回true。 - pickr.getRoot()
:Object
- 以树结构形式返回pickr的DOM树。 - pickr.getColor()
:HSVaColor
- 返回当前的HSVaColor对象。 - pickr.getSelectedColor()
:HSVaColor
- 返回当前应用的颜色。 - pickr.destroy() - 销毁所有功能。
- pickr.destroyAndRemove() - 销毁所有功能并移除pickr元素,包括按钮。
- pickr.setColorRepresentation(类型
:String
):Boolean
- 更改当前的颜色表示方式。有效选项包括HEX
、RGBA
、HSVA
、HSLA
和CMYK
,如果类型无效则返回false。 - pickr.getColorRepresentation()
:String
- 返回当前使用的颜色表示方式(如HEXA
、RGBA
等)。 - pickr.applyColor(静默
:Boolean
):Pickr
- 与按下保存按钮效果相同。如果静默为true,则不会触发onSave
事件。 - pickr.addSwatch(颜色
:String
):Boolean
- 向色板添加颜色。如果成功添加到色板,则返回true
。 - pickr.removeSwatch(索引
:Number
):Boolean
- 通过索引从色板中移除颜色,如果成功则返回true。
静态方法
Pickr
- create(选项
:Object
):Pickr
- 创建新实例。
Pickr.utils
- once(元素
:HTMLElement
, 事件:String
, 函数:Function
[, 选项:Object
]) - 附加一个只会触发一次的事件处理程序 - on(元素
:HTMLElement(s)
, 事件:String(s)
, 函数:Function
[, 选项:Object
]) - 附加事件处理函数。 - off(元素
:HTMLElement(s)
, 事件:String(s)
, 函数:Function
[, 选项:Object
]) - 移除事件处理程序。 - createElementFromString(html
:String
):HTMLElement
- 从此字符串创建新的HTML元素。 - eventPath(事件
:Event
):[HTMLElement]
- 事件路径事件属性的polyfill。 - createFromTemplate(字符串
:String
) - 参见内联文档。 - resolveElement(值
:String|HTMLElement
) - 解析HTMLElement
,支持>>>
作为shadow dom选择器。 - adjustableInputNumbers(元素
:InputElement
, 映射器:Function
) - 创建通过鼠标滚动更改输入字段中数字的可能性。 映射器函数接受三个参数:匹配的数字、乘数和匹配的索引。
请谨慎使用这些工具,不能保证它们会永远存在!
静态属性
- version - 当前版本。
- I18N_DEFAULTS - i18n默认值。
- DEFAULT_OPTIONS - 默认选项(不要直接覆盖此属性本身,只更改其属性)。
常见问题
如何初始化多个pickr?我可以通过
class
或id
访问实例吗?
不可以。你需要自己跟踪实例变量 - pickr(尚)不是Web组件。
最佳选择是通过document.createElement
创建新元素,并直接将其作为el
传递。
示例。
我想在表单中使用pickr,该如何操作?
你可以使用useAsButton: true
,并将输入元素的引用(或选择器)作为el
传递。然后,每当发生更改时,你就可以更新输入元素。示例。
我想在挂载pickr后更新选项,这可能吗?
很遗憾不行。这个项目的核心代码相当老(超过2年),我是在我早期的JavaScript时期制作的 - 这个小部件无法以这种方式动态地重新渲染自身。 你必须销毁它并重新初始化。
贡献
如果你想提出问题、创建Pull Request,或者只是想了解如何在本地机器上运行它,请阅读贡献指南。