在vue中实现picker样式_基于vue的颜色选择器vue-color-picker
/**
* author : alex
* email : 961163829@qq.com*/exportdefault{
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{returnarr;
}
},
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;varx, 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;
}returnr;
},/*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) {varm1, 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) returnm2;if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;returnm1;
},
RGBToHSL:function(rgb) {varmin, 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];
}
}
}
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%;
}
在vue中实现picker样式_基于vue的颜色选择器vue-color-picker相关推荐
- 在vue中实现picker样式_基于Vue实现timepicker
主要用到的还是Vue的基本知识而已,不过要想到的细节很多. 先放效果,点击上框,显示timepicker.而且可以根据点击的是时还是分来改变圆盘的数字. 这里我用了两个组件,和,这里的时和分的数值我挂 ...
- vue中,scss样式的三种写法——当前页面直接定义、@import引入样式、main.js引入公共样式 deep和important的写法
vue中,scss样式的三种写法--当前页面直接定义.@import引入样式.main.js引入公共样式 & deep和important的写法 1.安装scss # 安装node-sass ...
- 解决Vue刷新一瞬间出现样式未加载完或者出现Vue代码问题
解决Vue刷新一瞬间出现样式未加载完或者出现Vue代码问题 参考文章: (1)解决Vue刷新一瞬间出现样式未加载完或者出现Vue代码问题 (2)https://www.cnblogs.com/jiah ...
- 颜色拾取器color picker (javascript version)
颜色拾取器 216种web safe color的构造方法 var cl = ['00','33','66','99','CC','FF']; var clist = []; for( ...
- vue中headers是什么_【vue】饿了么项目-header组件开发
1.数据传递的理解 在App.vue中用到了header组件,首先注册组件 components: {'v-header': header } 然后才能引用 :seller="seller& ...
- vue中:class实现样式的绑定
在vue中通过 :class 实现 实现 标签中 条件与样式的绑定 示例代码: <div class="right" :class="{ kuan: 条件1, bi ...
- vue中修改滚动条样式
该方法只适用于Chrome浏览器 样式写在 APP.vue 中,可以用在全局,如果只用在那个盒子中,只需要在::前面加上盒子的class名就可以 ::-webkit-scrollbar {width: ...
- vue中echarts调用接口_在vue2中使用echarts (Vue-ECharts插件)
Vue-ECharts ECharts 的 Vue.js 组件. 基于 ECharts v4.1.0 + 开发,依赖 Vue.js v2.2.6 +. 安装 npm(推荐方式) $ npm insta ...
- vue中绑定style样式的方式
vue中绑定样式的方式有多种 下面就来看看吧 开始之前先准备一些样式 css样式 <style>.red {color: red}.green {color: green}.big {fo ...
最新文章
- WebSphere安装
- 从源码分析DEARGUI之让table可以选中
- 谷歌公布十大恶意网站 均曾攻击上万网站
- 268. Missing Number
- 从零开始带你一步一步使用YOLOv3测试自己的数据
- 展望2018:WebRTC和下一代编解码器
- oracle之 Oracle归档日志管理
- 2019 wannafly winter camp day5-8代码库
- 程序员面试金典 - 面试题 01.01. 判定字符是否唯一(位运算,牛)
- Cloud一分钟 | 成本大增致谷歌财报蒙尘;Gartner发数据库魔力象限:阿里云成为黑马...
- [物理学与PDEs]第5章习题6 各向同性材料时强椭圆性条件的等价条件
- java 代码重排_Java中指令重排
- 学习WEB的心理路程
- 8个高清图片素材网站,免费可商用。
- Android 暗黑模式
- 分级聚类算法(集体智慧编程)
- 华为OD机试真题 Python 实现【开放日活动】【100%通过率】【2022.11 Q4 新题】
- Sharpdevelop开发工具
- 计算机科学与技术有意义吗,各位大大,我是一名小二本的计算机科学与技术专业学生,我想问我有必要去考研吗?...
- VsCode安装和配置C++环境详细全流程
热门文章
- java flash 压缩_Java和flash通信中数据的zlib压缩与解压缩
- 2015大学计算机二级考试,2015年计算机二级考试模拟题(一)
- zuul网关找不到服务_网关zuul中对所有下游服务权限做控制zuulauth
- php表单密码由加密变明文,PHP 安全性漫谈 Linux+Apache+Mysql+PHP
- SSH-远程登录协议
- 制作登录注册密码找回网站常用控件
- sql server 事务与try catch
- 如何灵活使用 ActionBar, Google 音乐ActionBar 隐藏和显示效果
- 对于纯Java项目,JVM 各个类加载器的加载目标是什么?
- 如何解析一个字符串并返回一个嵌套数组?