mini-color-picker
小程式拾色器(顔色選擇器)元件,以rgb為資料格式
對比:
- we-color-picker 需注意元件定位,操作 不跟手不流暢 ,配置複雜。其定位會撐開原有頁面,體驗不佳。滑動距離按像素區分(固定),需考慮裝置分辨率,不利于多端。
- PapaerPen 利用原有slider元件實作滑動選取,不限于裝置分辨率。但需三次操作。
特性:
本元件利用官方提供的slider實作選擇色相,movable-view選擇飽和度和明度,由于是官方基礎元件,操作順暢。在滑動區域的設定上,使用占比來影響色值變化,無需考慮rpx轉換。在操作流程上,限于手機操作區域,不能使用Popover,使用底部拉起彈窗,不影響原有頁面,
重點突出。在操作預覽上,由于彈窗遮罩不可避免無法實時預覽,采用色相滑塊的顔色來實作預覽。同時考慮了iphone-x的安全區域問題。
注意:
外部與元件通信的資料格式是rgb,為了避免引入多種資料格式而導緻代碼備援,開發者可自行按需轉換,參考附:
截圖示例
安裝使用
1. 擷取元件
git
可能不穩定,但包含最新功能更新
git clone https://github.com/MakerGYT/mini-color-picker.git
将項目中components/color-picker檔案夾拷貝到元件路徑下
npm
穩定
npm install mini-color-picker --save
使用npm包請參考
微信小程式官方文檔2. 引入元件
在使用該元件的頁面對應json檔案中添加:
{
"usingComponents": {
"color-picker":"/components/color-picker/color-picker"
}
}
如使用npm,
點選開發者工具中的菜單欄:工具 --> 建構 npm;
勾選“使用 npm 子產品”選項
{
"usingComponents": {
"color-picker":"mini-color-picker/color-picker"
}
}
3. 使用元件
參考
/pages<!-- index.wxml -->
<view style="background:{{rgb}};width:100px;height:24px;" bindtap="toPick"></view>
<color-picker bindchangeColor="pickColor" initColor="{{rgb}}" show="{{pick}}" />
Page({
data:{
rgb: 'rgb(0,154,97)',//初始值
pick: false
},
// 顯示取色器
toPick: function () {
this.setData({
pick: true
})
},
//取色結果回調
pickColor(e) {
let rgb = e.detail.color;
},
})
屬性清單
屬性 | 類型 | 預設值 | 必填 | 說明 |
---|---|---|---|---|
show | Boolean | false | 是 | 是否顯示 |
initColor | String | rgb(255,0,0) | 是 | 初始色,rgb表示 |
mask | true | 否 | 是否顯示背景蒙層 | |
maskClosable | 點選背景蒙層是否可以關閉 | |||
bindchangeColor | eventhandler | 取色後的回調,event.detail = {color} | ||
bindclose | 點選背景蒙層關閉掉color-picker後觸發的事件 |
License
MIT© MakerGYT
附
- rgb -> hex
/**
* @param {String} color:'rgb(255,0,0)'
* @return {String} hex:'#000'
*/
const rgb2hex = (color) => {
let rgb = color.split(',');
let R = parseInt(rgb[0].split('(')[1]);
let G = parseInt(rgb[1]);
let B = parseInt(rgb[2].split(')')[0]);
let hex = "#" + ((1 << 24) + (R << 16) + (G << 8) + B).toString(16).slice(1);
return hex;
},
- rgb -> hsv
/**
* @param {String} color:'rgb(255,0,0)'
* @return {Object} {h(°),s(%),v(%)}
*/
const rgb2hsv = (color) => {
let rgb = color.split(',');
let R = parseInt(rgb[0].split('(')[1]);
let G = parseInt(rgb[1]);
let B = parseInt(rgb[2].split(')')[0]);
let hsv_red = R / 255,hsv_green = G / 255,hsv_blue = B / 255;
let hsv_max = Math.max(hsv_red, hsv_green, hsv_blue),
hsv_min = Math.min(hsv_red, hsv_green, hsv_blue);
let hsv_h, hsv_s, hsv_v = hsv_max;
let hsv_d = hsv_max - hsv_min;
hsv_s = hsv_max == 0 ? 0 : hsv_d / hsv_max;
if (hsv_max == hsv_min) hsv_h = 0;
else {
switch (hsv_max) {
case hsv_red:
hsv_h = (hsv_green - hsv_blue) / hsv_d + (hsv_green < hsv_blue ? 6 : 0);
break;
case hsv_green:
hsv_h = (hsv_blue - hsv_red) / hsv_d + 2;
break;
case hsv_blue:
hsv_h = (hsv_red - hsv_green) / hsv_d + 4;
break;
}
hsv_h /= 6;
}
return {
h: (hsv_h * 360).toFixed(),
s: (hsv_s * 100).toFixed(),
v: (hsv_v * 100).toFixed()
}
},
- rgb -> cmyk
/**
* @param {String} color:'rgb(255,0,0)'
* @return {Object} {c(%),m(%),y(%),k(%)}
*/
const rgb2cmyk = (color)=> {
let rgb = color.split(',');
let R = parseInt(rgb[0].split('(')[1]);
let G = parseInt(rgb[1]);
let B = parseInt(rgb[2].split(')')[0]);
if ((R == 0) && (G == 0) && (B == 0)) {
return [0, 0, 0, 1];
} else {
let calcR = 1 - (R / 255),
calcG = 1 - (G / 255),
calcB = 1 - (B / 255);
let K = Math.min(calcR, Math.min(calcG, calcB)),
C = (calcR - K) / (1 - K),
M = (calcG - K) / (1 - K),
Y = (calcB - K) / (1 - K);
return {
c:(C*100).toFixed(),
m:(M*100).toFixed(),
y:(Y*100).toFixed(),
k:(K*100).toFixed()
}
}
}
- hex -> rgb
/**
* @param {String} hex:'#888888'
* @return {String} 'rgb(255,0,0)'
*/
const hex2rgb = (hex) => {
if (hex.length === 4) {
let hexNew = "#";
for (var i = 1; i < 4; i += 1) {
hexNew += hex.slice(i, i + 1).concat(hex.slice(i, i + 1));
}
hex = hexNew;
}
return "rgb(" + parseInt("0x" + hex.slice(1, 3)) + "," + parseInt("0x" + hex.slice(3, 5)) + "," + parseInt("0x" + hex.slice(5, 7)) + ")";
},
- hsv -> rgb
/**
* @param {Array} [h(°),s(%),v(%)]
* @return {String} 'rgb(255,0,0)'
*/
const hsv2rgb = (h, s, v) => {
let hsv_h = (h / 360).toFixed(2);
let hsv_s = (s / 100).toFixed(2);
let hsv_v = (v / 100).toFixed(2);
let i = Math.floor(hsv_h * 6);
let f = hsv_h * 6 - i;
let p = hsv_v * (1 - hsv_s);
let q = hsv_v * (1 - f * hsv_s);
let t = hsv_v * (1 - (1 - f) * hsv_s);
let rgb_r = 0,
rgb_g = 0,
rgb_b = 0;
switch (i % 6) {
case 0:
rgb_r = hsv_v;
rgb_g = t;
rgb_b = p;
break;
case 1:
rgb_r = q;
rgb_g = hsv_v;
rgb_b = p;
break;
case 2:
rgb_r = p;
rgb_g = hsv_v;
rgb_b = t;
break;
case 3:
rgb_r = p;
rgb_g = q;
rgb_b = hsv_v;
break;
case 4:
rgb_r = t;
rgb_g = p;
rgb_b = hsv_v;
break;
case 5:
rgb_r = hsv_v, rgb_g = p, rgb_b = q;
break;
}
return 'rgb(' + (Math.floor(rgb_r * 255) + "," + Math.floor(rgb_g * 255) + "," + Math.floor(rgb_b * 255)) + ')';
},