Skip to content

Commit d777dae

Browse files
committed
feat: 新增 颜色选择器
1 parent f3874d8 commit d777dae

File tree

12 files changed

+446
-5
lines changed

12 files changed

+446
-5
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.DS_Store
22
node_modules
3-
/dist
3+
44

55
# local env files
66
.env.local

package.json

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
{
2-
"name": "vue-layui",
3-
"version": "0.1.0",
4-
"private": true,
2+
"name": "vue-lay",
3+
"version": "0.1.1",
4+
"author": "kouchao",
5+
"private": false,
6+
"main": "src/index.js",
57
"scripts": {
68
"serve": "vue-cli-service serve",
79
"build": "vue-cli-service build"
810
},
11+
"repository": {
12+
"type": "git",
13+
"url": "git+https://github.com/kouchao/vue-layui.git"
14+
},
15+
"keywords": [
16+
"vue",
17+
"layui",
18+
"vue-layui",
19+
"vue layui"
20+
],
21+
"license": "MIT",
22+
"homepage": "http://vue-layui.jskou.com",
923
"dependencies": {
1024
"@fortawesome/fontawesome-free": "^5.2.0",
1125
"async-validator": "^1.8.5",

src/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<template>
22
<div id="app">
3-
43
<lay-admin>
54
<lay-header>
65
<lay-logo>vue-layui</lay-logo>
@@ -83,6 +82,7 @@
8382
</template>
8483
<lay-menu-child-item title="弹出层" :to="{name: 'layer'}"></lay-menu-child-item>
8584
<lay-menu-child-item title="分页" :to="{name: 'laypage'}"></lay-menu-child-item>
85+
<lay-menu-child-item title="颜色选择器" :to="{name: 'colorPicker'}"></lay-menu-child-item>
8686
<lay-menu-child-item title="滑块" :to="{name: 'slider'}"></lay-menu-child-item>
8787
<lay-menu-child-item title="评分" :to="{name: 'rate'}"></lay-menu-child-item>
8888
<lay-menu-child-item title="轮播" :to="{name: 'carousel'}"></lay-menu-child-item>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* kouchao 创建于 2018/9/10
3+
*/
4+
5+
import LayColorPicker from './src/color-picker';
6+
7+
/* istanbul ignore next */
8+
LayColorPicker.install = function(Vue) {
9+
Vue.component(LayColorPicker.name, LayColorPicker);
10+
};
11+
12+
export default LayColorPicker;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<template>
2+
<div
3+
:class="['layui-unselect', 'layui-colorpicker', (size ? 'layui-colorpicker-' + size : '')]"
4+
@click="handleClick"
5+
>
6+
<span>
7+
<span
8+
class="layui-colorpicker-trigger-span"
9+
lay-type
10+
:style="color ? 'background: ' + color : ''"
11+
>
12+
<i
13+
class="layui-icon layui-colorpicker-trigger-i"
14+
:class="{
15+
'layui-icon-close': !color,
16+
'layui-icon-down': color
17+
}"
18+
></i>
19+
</span>
20+
</span>
21+
</div>
22+
</template>
23+
24+
<script>
25+
export default {
26+
name: "ColorBox",
27+
props: {
28+
color: {
29+
type: String
30+
},
31+
size: String
32+
},
33+
data() {
34+
return {
35+
format: "hex", //颜色显示/输入格式,可选 rgb,hex
36+
alpha: false //是否开启透明度
37+
};
38+
},
39+
methods: {
40+
handleClick(evt) {
41+
this.$emit("click", evt);
42+
}
43+
}
44+
};
45+
</script>
46+
47+
<style scoped>
48+
</style>
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
<template>
2+
<div class="layui-color-picker" :class="uid">
3+
<ColorBox :color="color" @click="handleToggle" :size="size"/>
4+
<div :hidden="isHidden" class="layui-anim layui-anim-upbit layui-colorpicker-main">
5+
<div class="layui-colorpicker-main-wrapper">
6+
<div ref="basis" class="layui-colorpicker-basis">
7+
<canvas ref="canvas" @mousedown="handleCanvasMouseDown" width="260" height="180"/>
8+
<div
9+
@mousedown="handleMouseDown"
10+
ref="choose"
11+
class="layui-colorpicker-basis-cursor"
12+
:style="{
13+
left: left + 'px',
14+
top: top + 'px'
15+
}"
16+
></div>
17+
</div>
18+
<color-side @change="sideChange"/>
19+
</div>
20+
<div class="layui-colorpicker-main-alpha">
21+
<div class="layui-colorpicker-alpha-bgcolor">
22+
<div ref="alphaslider" class="layui-colorpicker-alpha-slider" style="left: 280px;"></div>
23+
</div>
24+
</div>
25+
<div class="layui-colorpicker-main-input">
26+
<div class="layui-inline">
27+
<input :value="color" type="text" class="layui-input">
28+
</div>
29+
<div class="layui-btn-container">
30+
<button class="layui-btn layui-btn-primary layui-btn-sm" @click="handleClear">清空</button>
31+
<button class="layui-btn layui-btn-sm" @click="handleConfirm">确定</button>
32+
</div>
33+
</div>
34+
</div>
35+
</div>
36+
</template>
37+
38+
<script>
39+
/**
40+
* 改为画布实现
41+
* 已知bug 边界颜色选择不正确
42+
* 目前只实现选择颜色,未实现输入颜色色板进行变化
43+
* 参考 https://blog.csdn.net/e4cqss6c/article/details/55100232
44+
*/
45+
import ColorBox from "./color-box";
46+
import ColorSide from "./color-side";
47+
48+
import { rgb2hex, hex2rgb } from "./color";
49+
export default {
50+
name: "LayColorPicker",
51+
components: {
52+
ColorBox,
53+
ColorSide
54+
},
55+
props: {
56+
value: String,
57+
size: String,
58+
type: String
59+
},
60+
data() {
61+
return {
62+
startLeft: 0,
63+
left: 0,
64+
top: 0,
65+
startTop: 0,
66+
isHidden: true,
67+
color: this.value || "",
68+
uid: "color-picker-" + Math.random() + ""
69+
};
70+
},
71+
mounted() {
72+
this.genBase();
73+
},
74+
methods: {
75+
genBase(color = "#f00") {
76+
const ctx = this.$refs.canvas.getContext("2d");
77+
const width = 260;
78+
var base = ctx.createLinearGradient(0, 0, width, 0);
79+
base.addColorStop(1, color);
80+
base.addColorStop(0, "rgba(255,255,255,1)");
81+
ctx.fillStyle = base;
82+
ctx.fillRect(0, 0, width, width);
83+
84+
var my_gradient1 = ctx.createLinearGradient(0, 0, 0, width);
85+
my_gradient1.addColorStop(0, "rgba(0,0,0,0)");
86+
my_gradient1.addColorStop(1, "rgba(0,0,0,1)");
87+
ctx.fillStyle = my_gradient1;
88+
ctx.fillRect(0, 0, width, width);
89+
},
90+
sideChange(color) {
91+
this.genBase(color);
92+
this.change();
93+
},
94+
handleCanvasMouseDown(e) {
95+
this.left = e.offsetX - 6;
96+
this.top = e.offsetY - 6;
97+
98+
this.handleMouseDown(e);
99+
this.change();
100+
},
101+
handleMouseDown(e) {
102+
this.clientX = e.clientX;
103+
this.clientY = e.clientY;
104+
105+
this.startLeft = this.left;
106+
this.startTop = this.top;
107+
window.addEventListener("mousemove", this.onDragging);
108+
window.addEventListener("mouseup", this.onDragEnd);
109+
},
110+
onDragging(e) {
111+
let left = e.clientX - this.clientX + this.startLeft;
112+
let top = e.clientY - this.clientY + this.startTop;
113+
114+
if (top < -6) top = -6;
115+
if (top > 174) top = 174;
116+
if (left < -6) left = -6;
117+
if (left > 254) left = 254;
118+
this.left = left;
119+
this.top = top;
120+
this.change();
121+
e.preventDefault();
122+
},
123+
onDragEnd(e) {
124+
window.removeEventListener("mousemove", this.onDragging);
125+
window.removeEventListener("mouseup", this.onDragEnd);
126+
},
127+
change() {
128+
const ctx = this.$refs.canvas.getContext("2d");
129+
var imgData = ctx.getImageData(this.left + 5, this.top + 6, 1, 1);
130+
const [r, g, b, a] = imgData.data;
131+
if(this.type == 'rgb'){
132+
this.color = `rgb(${r}, ${g}, ${b})`
133+
} else {
134+
this.color = "#" + rgb2hex([r, g, b, a]);
135+
}
136+
137+
},
138+
handleConfirm() {
139+
this.isHidden = true;
140+
window.removeEventListener("click", this.hidden);
141+
this.$emit("input", this.color);
142+
this.$emit("change", this.color);
143+
},
144+
handleClear() {
145+
this.color = "";
146+
},
147+
handleToggle(e) {
148+
this.isHidden = !this.isHidden;
149+
if (!this.isHidden) {
150+
window.addEventListener("click", this.hidden);
151+
} else {
152+
window.removeEventListener("click", this.hidden);
153+
}
154+
this.color = this.value;
155+
},
156+
hidden(e) {
157+
const res = e.path
158+
.map(o => o.className)
159+
.find(o => o && o.includes(this.uid));
160+
if (res) {
161+
return false;
162+
}
163+
window.removeEventListener("click", this.hidden);
164+
165+
this.handleToggle();
166+
}
167+
},
168+
watch:{
169+
value(){
170+
this.color = this.value
171+
console.log(this.value)
172+
}
173+
}
174+
};
175+
</script>
176+
177+
<style scoped>
178+
.layui-color-picker {
179+
position: relative;
180+
}
181+
</style>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<template>
2+
<div class="layui-colorpicker-side">
3+
<canvas ref="side" @mousedown="handleCanvasMouseDown" width="12" height="180"/>
4+
<div
5+
@mousedown="handleMouseDown"
6+
class="layui-colorpicker-side-slider"
7+
:style="{
8+
top: top + 'px'
9+
}"
10+
></div>
11+
</div>
12+
</template>
13+
14+
<script>
15+
export default {
16+
name: "LayColorPicker",
17+
data() {
18+
return {
19+
startLeft: 0,
20+
top: -3,
21+
startTop: 0
22+
};
23+
},
24+
mounted() {
25+
const ctx = this.$refs.side.getContext("2d");
26+
const height = 180;
27+
const color = "#f00";
28+
const side = ctx.createLinearGradient(0, 0, 0, height);
29+
side.addColorStop(0, "#f00");
30+
side.addColorStop(1 / 6, "#f0f");
31+
side.addColorStop(2 / 6, "#00f");
32+
side.addColorStop(3 / 6, "#0ff");
33+
side.addColorStop(4 / 6, "#0f0");
34+
side.addColorStop(5 / 6, "#ff0");
35+
side.addColorStop(1, "#f00");
36+
37+
ctx.fillStyle = side;
38+
ctx.fillRect(0, 0, 12, height);
39+
},
40+
methods: {
41+
handleCanvasMouseDown(e) {
42+
this.top = e.offsetY - 3;
43+
this.handleMouseDown(e);
44+
this.change()
45+
},
46+
handleMouseDown(e) {
47+
this.clientY = e.clientY;
48+
49+
this.startTop = this.top;
50+
window.addEventListener("mousemove", this.onDragging);
51+
window.addEventListener("mouseup", this.onDragEnd);
52+
},
53+
onDragging(e) {
54+
let top = e.clientY - this.clientY + this.startTop;
55+
56+
if (top < -3) top = -3;
57+
if (top > 177) top = 177;
58+
this.top = top;
59+
this.change();
60+
e.preventDefault();
61+
},
62+
onDragEnd(e) {
63+
window.removeEventListener("mousemove", this.onDragging);
64+
window.removeEventListener("mouseup", this.onDragEnd);
65+
},
66+
change() {
67+
const ctx = this.$refs.side.getContext("2d");
68+
const imgData = ctx.getImageData(0, this.top + 2, 1, 1);
69+
const [r, g, b, a] = imgData.data;
70+
this.$emit("change", `rgb(${r}, ${g}, ${b})`);
71+
}
72+
}
73+
};
74+
</script>
75+
76+
<style scoped>
77+
.layui-colorpicker-side {
78+
background: transparent;
79+
}
80+
</style>

0 commit comments

Comments
 (0)