📒 背景
最近项目中需要制作一个颜色选择器(如下图展示),今天分享一下这个组件功能。希望能抛砖引玉,给大家带来启发。
🔍需求功能
- icon或者文字颜色需要选择颜色
👣设计开发
先说一下我的开发环境版本:
node: v11.3.0
npm: 6.4.1
vue:2.5.11
如果不是以上版本也没关系,今日分享的思路,相信你可以自己造出来~
首先点击空白收缩:
this.handler = function(e) {
_this.showPanel = false;
}
document.body.addEventListener('click', this.handler)
然后颜色渐变区域:
// 选择颜色的7色条
makeColorBar() {
var gradientBar = this.ctx.createLinearGradient(0, 0, 0, this.height);
gradientBar.addColorStop(0, '#F00');
gradientBar.addColorStop(1 / 6, '#F0F');
gradientBar.addColorStop(2 / 6, '#00F');
gradientBar.addColorStop(3 / 6, '#0FF');
gradientBar.addColorStop(4 / 6, '#0F0');
gradientBar.addColorStop(5 / 6, '#FF0');
gradientBar.addColorStop(1, '#F00');
this.ctx.fillStyle = gradientBar;
this.ctx.fillRect(0, 0, 20, this.height);
},
然后是拖拽选择颜色区域:
// 颜色选择区域
makeColorBox(color) {
var gradientBase = this.ctx.createLinearGradient(30, 0, this.width, 0);
gradientBase.addColorStop(1, color);
gradientBase.addColorStop(0, 'rgba(255,255,255,1)');
this.ctx.fillStyle = gradientBase;
this.ctx.fillRect(30, 0, this.width, this.height);
var my_gradient1 = this.ctx.createLinearGradient(0, 0, 0, this.height);
my_gradient1.addColorStop(0, 'rgba(0,0,0,0)');
my_gradient1.addColorStop(1, 'rgba(0,0,0,1)');
this.ctx.fillStyle = my_gradient1;
this.ctx.fillRect(30, 0, this.width, this.height);
// this.onCanvasClick(this.canvasPos);
},
其中获取rgb颜色:
// 获取rgb
getRgbaAtPoint(pos, area) {
if (area == 'bar') {
var imgData = this.ctx.getImageData(0, 0, 20, this.height);
} else {
var imgData = this.ctx.getImageData(0, 0, this.width, this.height);
}
var data = imgData.data;
var dataIndex = (pos.y * imgData.width + pos.x) * 4;
//开始消除误差
if (pos.x >= 30 && pos.y > this.height - 3) {
return [0, 0, 0, this.alpha];
}
if (pos.x >= 30 && pos.y <= 1) {
data[dataIndex] = 255;
}
if (pos.x >= 30 && pos.x <= 31) {
return [
data[dataIndex],
data[dataIndex],
data[dataIndex],
this.alpha
]
}
if (pos.x >= this.width - 1) {
return [
data[dataIndex],
0,
0,
this.alpha
]
}
// 消除误差结束
return [
data[dataIndex],
data[dataIndex + 1],
data[dataIndex + 2],
this.alpha
];
},
rgba转16进制
// rgb/rgba色值转16进制
rgb2hex(rgb) {
var reg = /^(rgb|RGB)/;
var a;
if (reg.test(rgb)) {
var colorArr = rgb.replace(/(?:rgba|rgb|RGBA|RGB|\(|\))*/g, "").split(',');
var alpha = (colorArr && colorArr[3] || "").trim()
var hex = "#" + ((1 << 24) + (parseInt(colorArr[0]) << 16) + (parseInt(colorArr[1]) << 8) + parseInt(
colorArr[2])).toString(16).slice(1);
if (alpha != '' && alpha != '1') {
a = ((alpha * 255) | 1 << 8).toString(16).slice(1);
hex = hex + a;
}
return hex.toUpperCase();
} else {
return rgb
}
},
16进制转rgb
// 16进制色值转rgb
hex2rgb(hex) {
var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
var color = hex.toLowerCase();
if (reg.test(color)) {
if (color.length === 4) {
var colorNew = "#";
for (var i = 1; i < color.length; i += 1) {
colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1));
}
color = colorNew;
}
var colorChange = [];
for (var i = 1; i < color.length; i += 2) {
colorChange.push(parseInt("0x" + color.slice(i, i + 2)));
}
return "rgb(" + colorChange.join(",") + ")";
} else {
return color;
}
}
更多逻辑代码欢迎体验组件--mycomponentsvue
npm install mycomponentsvue@0.0.15
import mycomponents from 'mycomponentsvue'
Vue.use(mycomponents)
<color-pick v-model="textColor" :predefine="predefineColor" icon="showcolor"></color-pick>
本组件只用于学习交流哈!所以名字起的比较随意!~
⛳参考学习
vue-color组件(sketch-picker) 和 element-ui的colorPicker组件(colorPicker)
🚀写在最后
如果本文中有bug、逻辑错误,或者您有更好的优化方案欢迎评论联系我哦!~关注我持续分享日常工作中的组件设计和学习分享,一起进步加油!