基于vue的颜色选择器color-picker
项目中有用到颜色选择器的童鞋们可以看过来了
关于color-picker的jquery的插件是有蛮多,不过vue组件没有吧,反正我没有找到,
虽然element-ui里面有这个,但是你愿意为了一个小功能去引入这么大的依赖库吗?
适用于:想写基于vue的单个color-picker功能的童鞋
甩github地址啦:https://github.com/alexzaolin/vue-color-picker
(麻烦觉得有用的童鞋帮我点个star,谢谢谢谢谢~~)
凑个字数贴一下代码(部分算法来自网络):
<template lang="html">
<div>
<div class="color-picker-container" :id="containerId" :class="{'active':isShowPicker}">
<div class="color"></div>
<div class="wheel"></div>
<div class="overlay"></div>
<div class="h-marker marker"></div>
<div class="sl-marker marker"></div>
</div>
</div>
</template> <script>
/**
* author : alex
* email : 961163829@qq.com
*/
export default {
props:{
/*由父组件传递的默认颜色*/
defaultColor:{
type:String,
default:"#000000"
},
/*目标元素,可以是input框或者按钮等*/
targetElem:null
},
data(){
return {
isShowPicker:false,
wheel:document.querySelector('.wheel'),
color:this.defaultColor,
containerId:"color-picker-container",
dom:{
hMarker:null,
slMarker:null,
color:null,
targetElem:null,
container:null
},
radius:84,
square:100,
width:194
}
},
mounted(){ this.dom.container=document.querySelector('#'+this.containerId);
this.dom.hMarker=document.querySelector('.h-marker');
this.dom.slMarker=document.querySelector('.sl-marker');
this.dom.color=document.querySelector('.color');
this.dom.targetElem=document.querySelector(this.targetElem); this.init();
},
methods:{
init:function(){
var self = this;
self.posInit();
self.eventBind(); // Init color
self.setColor(self.color);
},
openPicker:function(){
var self = this;
this.isShowPicker = true;
this.wheel=document.querySelector('.wheel');
/*色盘打开的时候绑定点击事件*/
document.addEventListener("click",self.documentClick);
},
closePicker:function(){
this.isShowPicker = false;
/*色盘关闭的时候解绑事件*/
document.removeEventListener("click",this.documentClick);
},
eventBind:function(){
var self = this;
self.dom.container.addEventListener("mousedown",self.mousedown);
},
documentClick:function(e){
/*你可能不需要关闭色盘,那这个方法也是可以不需要的*/
var parents1 = this.getParents(e,this.dom.container,true);;
var parents2 = this.getParents(e,this.dom.targetElem,true);
if(parents1.length===0&&parents2.length===0){
this.closePicker();
}
},
posInit:function(){
/*色盘的位置计算*/
var target = this.dom.targetElem; var top = this.getElementViewTop(target);
var left = this.getElementViewLeft(target); this.dom.container.style.position = "fixed";
this.dom.container.style.top = (top)+'px'; this.dom.container.style.left = (left + this.dom.targetElem.offsetWidth)+'px'; },
getElementViewLeft:function(element){
/*获取元素距离视窗左部距离*/
var actualLeft = element.offsetLeft;
var current = element.offsetParent; while (current !== null){
actualLeft += current.offsetLeft;
current = current.offsetParent;
} if (document.compatMode == "BackCompat"){
var elementScrollLeft=document.body.scrollLeft;
} else {
var elementScrollLeft=document.documentElement.scrollLeft;
} return actualLeft-elementScrollLeft;
},
getElementViewTop:function(element){
/*获取元素距离视窗顶部距离*/
var actualTop = element.offsetTop;
var current = element.offsetParent; while (current !== null){
actualTop += current. offsetTop;
current = current.offsetParent;
} if (document.compatMode == "BackCompat"){
var elementScrollTop=document.body.scrollTop;
} else {
var elementScrollTop=document.documentElement.scrollTop;
} return actualTop-elementScrollTop;
},
getParents:function(e,parent,andSelf){
/*获取祖先节点,返回一个数组*/
var target = e.target;
var parent = typeof parent==='string'?document.querySelector(parent):parent; var curTarget = target; var arr = typeof andSelf === "undefined"?[curTarget]:[];
var result = []; while(true){
if((typeof parent !== 'undefined'&&curTarget == parent)||
typeof parent === 'undefined'&&curTarget.nodeType===9){
arr.push(curTarget);
break;
}
if(!!curTarget){arr.push(curTarget)} if(!!curTarget.parentNode){
curTarget = curTarget.parentNode
}else{
break;
}
}
if(!!parent){
return arr.indexOf(parent)>-1?arr:[];
}else{
return arr;
}
},
getParent:function(e){
/*获取父节点*/
return e.target.nodeType!==9&&e.target.parentNode;
},
/**
* 以下为组件内部函数
* 算法来自网络
*/
updateValue:function (event) {
var self = this; var that = event.target;
if (that.value && that.value != self.color) {
self.setColor(that.value);
}
},
/**
* Change color with HTML syntax #123456
*/
setColor:function (color) {
var self = this;
var unpack = self.unpack(color);
if (self.color != color && unpack) { self.color = color;
self.rgb = unpack;
self.hsl = self.RGBToHSL(self.rgb);
self.updateDisplay();
}
},
/**
* Change color with HSL triplet [0..1, 0..1, 0..1]
*/
setHSL:function (hsl) {
var self = this;
self.hsl = hsl;
self.rgb = self.HSLToRGB(hsl);
self.color = self.pack(self.rgb);
self.updateDisplay();
},
/**
* Retrieve the coordinates of the given event relative to the center
* of the widget.
*/
widgetCoords:function (event) {
var self = this;
var x, y;
var el = event.target || event.srcElement;
var reference = self.wheel; if (typeof event.offsetX != 'undefined') {
// Use offset coordinates and find common offsetParent
var pos = { x: event.offsetX, y: event.offsetY }; // Send the coordinates upwards through the offsetParent chain.
var e = el;
while (e) {
e.mouseX = pos.x;
e.mouseY = pos.y;
pos.x += e.offsetLeft;
pos.y += e.offsetTop;
e = e.offsetParent;
} // Look for the coordinates starting from the wheel widget.
var e = reference;
var offset = { x: 0, y: 0 }
while (e) {
if (typeof e.mouseX != 'undefined') {
x = e.mouseX - offset.x;
y = e.mouseY - offset.y;
break;
}
offset.x += e.offsetLeft;
offset.y += e.offsetTop;
e = e.offsetParent;
} // Reset stored coordinates
e = el;
while (e) {
e.mouseX = undefined;
e.mouseY = undefined;
e = e.offsetParent;
}
}
else {
// Use absolute coordinates
var pos = self.absolutePosition(reference);
x = (event.pageX || 0*(event.clientX + document.documentElement.scrollLeft)) - pos.x;
y = (event.pageY || 0*(event.clientY + document.documentElement.scrollTop)) - pos.y;
}
// Subtract distance to middle
return { x: x - self.width / 2, y: y - self.width / 2 };
},
/**
* Mousedown handler
*/
mousedown:function (event) {
var self = this;
if (!document.dragging) {
document.documentElement.addEventListener('mousemove', self.mousemove);
document.documentElement.addEventListener('mouseup', self.mouseup);
document.dragging = true;
} // Check which area is being dragged
var pos = self.widgetCoords(event);
self.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > self.square; // Process
self.mousemove(event);
return false;
},
/**
* Mousemove handler
*/
mousemove:function (event) {
var self = this;
// Get coordinates relative to color picker center
var pos = self.widgetCoords(event); // Set new HSL parameters
if (self.circleDrag) {
var hue = Math.atan2(pos.x, -pos.y) / 6.28;
if (hue < 0) hue += 1;
self.setHSL([hue, self.hsl[1], self.hsl[2]]);
}
else {
var sat = Math.max(0, Math.min(1, -(pos.x / self.square) + .5));
var lum = Math.max(0, Math.min(1, -(pos.y / self.square) + .5));
self.setHSL([self.hsl[0], sat, lum]);
}
return false;
},
/**
* Mouseup handler
*/
mouseup:function () {
var self = this;
// Uncapture mouse
document.documentElement.removeEventListener('mousemove', self.mousemove);
document.documentElement.removeEventListener('mouseup', self.mouseup);
document.dragging = false;
},
/**
* Update the markers and styles
*/
updateDisplay:function () {
var self = this;
// Markers
var angle = self.hsl[0] * 6.28; self.dom.hMarker.style.left = Math.round(Math.sin(angle) * self.radius + self.width / 2) + 'px';
self.dom.hMarker.style.top = Math.round(-Math.cos(angle) * self.radius + self.width / 2) + 'px'; self.dom.slMarker.style.left = Math.round(self.square * (.5 - self.hsl[1]) + self.width / 2) + 'px';
self.dom.slMarker.style.top = Math.round(self.square * (.5 - self.hsl[2]) + self.width / 2) + 'px'; // Saturation/Luminance gradient
self.dom.color.style.backgroundColor = self.pack(self.HSLToRGB([self.hsl[0], 1, 0.5])); // important
// 将获取到的最新的color值emit出去
self.$emit("onChange",self.color);
//self.dom.targetElem.style.backgroundColor = self.color;
//self.dom.targetElem.style.color = self.hsl[2] > 0.5 ? '#000' : '#fff'; // Change linked value
// if (self.dom.targetElem.value && self.dom.targetElem.value != self.color) {
// self.dom.targetElem.value = self.color;
// }
},
/**
* Get absolute position of element
*/
absolutePosition:function (el) {
var self = this;
var r = { x: el.offsetLeft, y: el.offsetTop };
// Resolve relative to offsetParent
if (el.offsetParent) {
var tmp = self.absolutePosition(el.offsetParent);
r.x += tmp.x;
r.y += tmp.y;
}
return r;
},
/* Various color utility functions */
pack:function (rgb) {
var r = Math.round(rgb[0] * 255);
var g = Math.round(rgb[1] * 255);
var b = Math.round(rgb[2] * 255);
return '#' + (r < 16 ? '0' : '') + r.toString(16) +
(g < 16 ? '0' : '') + g.toString(16) +
(b < 16 ? '0' : '') + b.toString(16);
},
unpack:function (color) {
if (color.length == 7) {
return [parseInt('0x' + color.substring(1, 3)) / 255,
parseInt('0x' + color.substring(3, 5)) / 255,
parseInt('0x' + color.substring(5, 7)) / 255];
}
else if (color.length == 4) {
return [parseInt('0x' + color.substring(1, 2)) / 15,
parseInt('0x' + color.substring(2, 3)) / 15,
parseInt('0x' + color.substring(3, 4)) / 15];
}
},
HSLToRGB:function (hsl) {
var m1, m2, r, g, b;
var h = hsl[0], s = hsl[1], l = hsl[2];
m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
m1 = l * 2 - m2;
return [this.hueToRGB(m1, m2, h+0.33333),
this.hueToRGB(m1, m2, h),
this.hueToRGB(m1, m2, h-0.33333)];
},
hueToRGB:function (m1, m2, h) {
h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
if (h * 2 < 1) return m2;
if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
return m1;
},
RGBToHSL:function (rgb) {
var min, max, delta, h, s, l;
var r = rgb[0], g = rgb[1], b = rgb[2];
min = Math.min(r, Math.min(g, b));
max = Math.max(r, Math.max(g, b));
delta = max - min;
l = (min + max) / 2;
s = 0;
if (l > 0 && l < 1) {
s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
}
h = 0;
if (delta > 0) {
if (max == r && max != g) h += (g - b) / delta;
if (max == g && max != b) h += (2 + (b - r) / delta);
if (max == b && max != r) h += (4 + (r - g) / delta);
h /= 6;
}
return [h, s, l];
}
}
}
</script> <style lang="css" scoped>
.color-picker-container {
position: fixed;
display: none; }
.color-picker-container.active{
display: block;
}
.color-picker-container * {
position: absolute;
cursor: crosshair;
}
.color-picker-container, .color-picker-container .wheel {
width: 195px;
height: 195px;
}
.color-picker-container .color, .color-picker-container .overlay {
top: 47px;
left: 47px;
width: 101px;
height: 101px;
}
.color-picker-container .wheel {
width: 195px;
height: 195px;
background: url(./images/wheel.png) no-repeat;
-webkit-background-size: 100%;
background-size: 100%;
}
.color-picker-container .overlay {
background: url(./images/mask.png) no-repeat;
-webkit-background-size: 100%;
background-size: 100%;
}
.color-picker-container .marker {
width: 17px;
height: 17px;
margin: -8px 0 0 -8px;
overflow: hidden;
background: url(./images/marker.png) no-repeat;
-webkit-background-size: 100%;
background-size: 100%;
}
</style>
基于vue的颜色选择器color-picker的更多相关文章
- 基于vue的颜色选择器vue-color-picker
项目中有用到颜色选择器的童鞋们可以看过来了 关于color-picker的jquery的插件是有蛮多,不过vue组件没有吧,反正我没有找到, 虽然element-ui里面有这个,但是你愿意为了一个小功 ...
- vue | 基于vue的城市选择器和搜索城市对应的小区
城市选择器应该是比较常用的一个组件,用户可以去选择自己的城市,选择城市后返回,又根据自己选择的城市搜索小区. 功能展示 这是选择结果 这是选择城市 这是搜索小区 这是搜索小区接口,key为城市名字,i ...
- HTML5的input color系统颜色选择器
前两天,我写了一篇<推荐两款jQuery色盘选择器>介绍,那是使用JavaScript实现的色盘,今天我给大家介绍HTML5的色盘选择器.HTML5有一个input类型为color,即颜色 ...
- NX二次开发-Block UI C++界面Object Color Picker(对象颜色拾取器)控件的获取(持续补充)
Object Color Picker(对象颜色拾取器)控件的获取 NX9+VS2012 #include <uf.h> #include <uf_obj.h> UF_init ...
- 【canvas系列】用canvas实现一个colorpicker(类似PS的颜色选择器)
每个浏览器都有自己的特点,比如今天要做的colorpicker就是,一千个浏览器,一千个哈姆雷特,一千个colorpicker.今天canvas系列就用canvas做一个colorpicker. ** ...
- 11个JavaScript颜色选择器插件
几年前,很难找到一个合适的颜色选择器.正好看到很多不错的JavaScript颜色选择器插件,故而把这些编译汇总.在本文,Web设计师和开发人员 Kevin Liew 选取了11个相应插件,有些会比较复 ...
- 基于Vue.js PC桌面端弹出框组件|vue自定义弹层组件|vue模态框
vue.js构建的轻量级PC网页端交互式弹层组件VLayer. 前段时间有分享过一个vue移动端弹窗组件,今天给大家分享一个最近开发的vue pc端弹出层组件. VLayer 一款集Alert.Dia ...
- UWP 颜色选择器(ColorPicker) 和 自定义的Flyout(AdvancedFlyout)
ColorPicker 故事背景 项目里面需要一个像Winfrom里面那样的颜色选择器,如下图所示: 在网上看了一下.没有现成的东东可以拿来使用.大概查看了一下关于颜色的一些知识,想着没人种树,那就由 ...
- Android圆环形颜色选择器:HoloColorPicker
HoloColorPicker实现圆环形颜色选择器,可以改变颜色饱和度来选择颜色.选择颜色时,可以用手指沿着圆环滑动一个滑块,从而选择颜色. 添加以下XML至你的布局中: ? 1 2 3 4 < ...
随机推荐
- Asp.net MVC 如何对所有用户输入的字符串字段做Trim处理
经常需要对用户输入的数据在插入数据库或者判断之前做Trim处理,针对每个ViewModel的字段各自做处理是我们一般的想法.最近调查发现其实也可以一次性实现的. MVC4.6中实现方式 1,实现IMo ...
- [0] 领域模型 VS 贫血模型
贫血→结构体领域→封装方法的类 1.领域模型 也要能够 到达解耦,最好不要出现billdao.InsertBill(obj)这种2.领域方法 最好是自身的方法,如改变一个属性值,添加一个子集,而不是一 ...
- Tomcat启动报错java.lang.UnsatisfiedLinkError
之前tomcat启动老是报错,虽然不影响项目的启动运行,但是有强迫症的程序员会心里不爽: 问题是由于本机安装的jdk版本与tomcat中使用的jdk版本不一致导致的. 后面我把原先tomcat启动环境 ...
- net core 程序docker打包镜像并发布到官方store
学习一个技术的第一步,总是要先打印或显示一个hello world的.当然,学习docker也不例外.上一篇文章已经简单的介绍了环境的安装和配置.接下来就要打印我们的hello world了. 首先我 ...
- android的drawable资源
1.android中可以通过xml文件配置资源,比如字符串啦,整数拉.浮点数等等,当然也可以配置图片资源和选择器,下面我们就看看几种图片资源的配置. @1矩形方框,带渐变色的配置代码 <?xml ...
- CoolBlog开发笔记第4课:数据库模型设计
教程目录 1.1 CoolBlog开发笔记第1课:项目分析 1.2 CoolBlog开发笔记第2课:搭建开发环境 1.3 CoolBlog开发笔记第3课:创建Django应用 前言 我新书<Py ...
- Javaee需不需要培训?培训完可以顺利找到工作吗?
Javaee需不需要培训?培训完可以顺利找到工作吗? 在IT行业中Java以它通用性.高效性.平台移植性和安全性遍布各个领域,它的火热也给IT市场发展带来一定影响,随着Java技术的广泛运营,企业对J ...
- mkdirs自动创建文件夹
//保存路径 如file路径是E:\filer\a.jpg File toSaveFile=new File("filePath"); if(toSaveFile!=null){ ...
- 网站优化html关键词代码使用
html的meta标签 .meta标签是内嵌在你网页中的特殊html标签,包含着你有关于你网页的一些隐藏信息.Meat标签的作用是向搜索引擎解释你的网页是有关哪方面信息的.对于高级的搜索引擎来说,ht ...
- thinkphp带查询条件的分页
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...