【基于element ui的color选择器】基于element ui的color选择器

技术版本如下:

vue 2.6.14
less 3.13.1
element-ui 2.15.6
less-loader 5.0.0

需求:

支持RGB、HEX编码、支持吸管吸取颜色、颜色选择器、颜色模板、透明度、色板、线性渐变颜色

效果图:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.引入选择器的color-all文件

<template><div><div><div class="colorpicker-box" :style="{background:handStyle()}"></div></div><h3>带编码显示的color选择器</h3><div>  <ColorPicker:data="pickerColor"@update:isLinear="pickerColor.isLinear = $event"@update:direction="pickerColor.direction = $event"@update:leftColor="handUpdateElement($event, 0)"@update:rightColor="handUpdateElement($event, 1)"></ColorPicker></div><h3>无编码显示的color选择器</h3><div><ColorPicker:data="pickerColor":isText="false"@update:isLinear="pickerColor.isLinear = $event"@update:direction="pickerColor.direction = $event"@update:leftColor="handUpdateElement($event, 0)"@update:rightColor="handUpdateElement($event, 1)"></ColorPicker></div></div>
</template>
<script>
import ColorPicker from '@/components/color-modal/color-picker.vue'
export default {components: {ColorPicker,},data() {return {pickerColor: {isLinear: false, //是否线性color: ['#334251'], //选择的颜色direction: 'right', //方向},}},methods: {handStyle() { return this.pickerColor.isLinear ? `linear-gradient(to ${this.pickerColor.direction},${this.pickerColor.color[0]} ,${this.pickerColor.color.length >= 2 ? this.pickerColor.color[1] : '#AE7DFF'})` : this.pickerColor.color[0]},handUpdateElement(value, cursor = null) {this.$set(this.pickerColor.color, cursor, value)},},
}
</script><style lang="less" scoped>
.colorpicker{&-box{width: 200px;border-radius: 5px;height: 30px;}div{padding: 10px;}
}</style>

2.重点,选择器的封装组件文件color-picker.vue

<template><el-popover placement="left-start" width="264" trigger="hover"><div class="colorPickerBody"><!-- tabs --><div class="colorPickerBody-headers"><el-radio-group v-model="activeName" size="mini" @change="handActive"><el-radio-button :label="0">颜色填充</el-radio-button><el-radio-button :label="1">线性填充</el-radio-button></el-radio-group></div><!-- top部分 --><div class="colorPickerBody-top"><div class="colorPickerBody-top-one"><!-- 颜色块color --><div class="color-diamond"><div :style="'background-color: ' +bgColor +';width: 100%;height: 100%;box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .15), inset 0 0 4px rgba(0, 0, 0, .25);'"></div></div><!-- select下拉 --><el-dropdown @command="handleCommand" class="eldropdownColor"><span class="el-dropdown-link">{{ colorType }}<i class="el-icon-arrow-down el-icon--right"></i></span><el-dropdown-menu slot="dropdown" :append-to-body="false"><el-dropdown-item command="HEX">HEX</el-dropdown-item><el-dropdown-item command="RGB">RGB</el-dropdown-item></el-dropdown-menu></el-dropdown><div v-if="colorType === 'HEX'"><el-input v-model="bgColor" class="colorValcss" @input="bgColor = $event; handHEXtoRGB($event)"></el-input></div><div v-else class="colorRGBBox"> <el-input type="number" v-model="red" min="0" max="255"class="colorRGBValcss" @input="handredChange"></el-input><el-input type="number" v-model="green" min="0"max="255" class="colorRGBValcss" @input="handgreenChange"></el-input><el-input type="number"v-model="blue" min="0" max="255" class="colorRGBValcss" @input="handblueChange"></el-input></div><div class="strawcss" title="吸管" @click="nativePick"><img src="@/assets/image/strawImg.svg"></div></div><!-- 线性特性box --><div v-if="activeName === 1" class="colorPickerBody-top-two"><div class="colorPickerBody-top-two-body"><div class="colorPickerBody-top-two-body-tag" title="首部" @click="handAlphaColor(true)"><img:src="handLineImg(true)"></div><div class="colorPickerBody-top-two-body-center" :style="'background: linear-gradient(to right, ' + handleftRightColor(true) + ', ' +handleftRightColor(false) +');'"></div><div class="colorPickerBody-top-two-body-tagRight" title="尾部" @click="handAlphaColor(false)"><img:src="handLineImg(false)"></div></div><div class="strawcss iconright" :title="data.direction === 'right' ? '旋转方向:上下' : '旋转方向:左右'"@click="handDirection"><i class="el-icon-refresh-right"></i></div></div><!-- 透明度块 --><div class="colorPickerBody-top-three"><div class="colorPickerBody-top-three-Alpha" ref="saturation_value"><div class="alpha-slider" ref="alpha_slider" @mousedown="mousedownAlpha"><div class="slider" :style="alphaSliderStyle + ';background:' + bgColor"></div><div :style="'background: linear-gradient(to right, rgba(0,0,0,0), ' +bgColor +');width: 100%;height: 100%;border-radius: 10px;'"></div></div></div><div class="colorPickerBody-top-three-number"> <el-input v-model="alpha" class="alphaValcss" type="number"min="0" max="100" @input="handAlpha"> <i slot="suffix" class="suffixInput">%</i></el-input></div></div></div><!-- 中间线 --><div class="colorPickerBody-border"></div><!-- bottom的颜色选择器 --><div class="colorPickerBody-body"><div class="colorPickerBody-body-headers"><div class="colorPickerBody-body-headers-title">颜色选择器</div><div class="colorPickerBody-body-headers-svg"><div :class="colorselecotr ? 'boxbuttom checkbuttom' : 'boxbuttom '" @click="colorselecotr = true"><imgsrc="@/assets/image/colordemo.svg"> </div><div :class="!colorselecotr ? 'boxbuttom checkbuttom' : 'boxbuttom '" @click="colorselecotr = false"><imgsrc="@/assets/image/colorpick.svg"></div></div></div class="colorPickerBody-body-box"><div v-if="colorselecotr"><MyColorSelect class="MyColorSelect" :color="bgColor" :alphaValue="alpha"@update:color="bgColor = $event; handHEXtoRGB($event)"></MyColorSelect></div><ul v-else class="colorDemoList"><li v-for="(item, index) in colorAll" :key="index" :style="'background: ' + item"@click="bgColor = item; handHEXtoRGB(item)"></li></ul></div></div><!-- 仿input框,默认显示第一个color --><div class="colorInputBody" slot="reference" v-if="isText"><div class="colorBox" :style="'background:' + data.color[0]"></div><div class="colorInputBody-title">{{ data.color[0] }}</div></div><div class="colorNoTextBody" slot="reference" v-else><div class="colorNoTextBody-colorBox" :style="'background:' + data.color[0]"></div></div></el-popover>
</template><script>
import MyColorSelect from "./MyColorSelect.vue"
import moveCursorImg from '@/assets/image/moveCursorImg.png'
import checkmoveCursorImg from '@/assets/image/checkmoveCursorImg.png'
import message from "@/utils/message.js";
import { debounce } from '@/utils/util.js'export default {props: {data: {type: Object,default: () => ({isLinear: false, //是否线性color: ["#000"], //选择的颜色direction: "right", //方向}),},//是否显示color编码isText: {type: Boolean,default: true}},components: {MyColorSelect},data() {return {colorAll: ["#FF0000", "#FFA500", "#FFFF00", "#008000", "#0000FF","#4B0082", "#EE82EE", "#FF1493", "#FF69B4", "#FF4500","#FF6347", "#FFD700", "#ADFF2F", "#00FFFF", "#87CEEB","#4169E1", "#800080", "#9932CC", "#8A2BE2", "#FF00FF","#FFC0CB", "#F08080", "#CD5C5C", "#FA8072", "#FFA07A","#FF7F50", "#FFDAB9", "#FFE4B5", "#FFDEAD", "#FFE4E1","#FFF0F5", "#F0FFF0", "#F5FFFA", "#B0E0E6", "#ADD8E6","#87CEFA", "#87CEEB", "#00BFFF", "#1E90FF", "#6495ED","#4682B4", "#5F9EA0", "#20B2AA", "#008B8B", "#008080"],alphaSliderStyle: "left: calc(100% - 6px);",alpha: 100,colorType: "HEX",bgColor: "",colorselecotr: true,activeName: 0,red: 255,green: 0,blue: 0,isLinearStart: true,moveCursorImg,checkmoveCursorImg,hasEyeDrop: 'EyeDropper' in window};},mounted() {this.bgColor = this.data.color[0]this.activeName = this.data.isLinear ? 1 : 0},methods: {handAlphaColor(item) {this.isLinearStart = item;let alphaNew = 1;if (item) {const { r, g, b, a } = this.parseColor(this.data.color[0]);alphaNew = a;} else {const { r, g, b, a } = this.parseColor(this.data.color[1]);alphaNew = a;}this.alpha = alphaNew.toFixed(2) * 100this.handAlpha()},// taghandActive(e) {if (e === 0) {this.bgColor = this.data.color[0]this.handAlphaColor(true)this.$emit('update:isLinear', false)} else {this.$emit('update:isLinear', true)}},// 方向handDirection() {if (this.data.direction === 'right') {this.$emit('update:direction', 'top')} else {this.$emit('update:direction', 'right')}},//取色async nativePick(e) {const val = e ? e.target.value : nullif (val) {console.log('获得颜色: ' + val)} else {const eyeDropper = new window.EyeDropper() // 初始化一个EyeDropper对象try {const result = await eyeDropper.open() // 开始拾取颜色this.bgColor = result.sRGBHex;this.handHEXtoRGB(result.sRGBHex)} catch (e) {console.log('用户取消了取色')}}},//判断线性条handleftRightColor(val) {let color = '#AE7DFF';if (val) {color = this.data.color[0]} else {if (this.data.color.length >= 2) color = this.data.color[1]}return color;},//判断首尾游标handLineImg(val) {let icon = moveCursorImg;if (val) {if (this.isLinearStart) {this.bgColor = this.data.color[0]icon = checkmoveCursorImg;}} else {if (!this.isLinearStart) {this.bgColor = this.data.color.length >= 2 ? this.data.color[1] : '#AE7DFF'icon = checkmoveCursorImg;}}return icon;},handredChange(val) {if ((val ?? '') !== '') {this.bgColor = this.rgba2hex(val, this.green, this.blue, this.matchHexA())this.handHEXtoRGB(this.bgColor)}},handgreenChange(val) {if ((val ?? '') !== '') {this.bgColor = this.rgba2hex(this.red, val, this.blue, this.matchHexA())this.handHEXtoRGB(this.bgColor)}},handblueChange(val) {if ((val ?? '') !== '') {this.bgColor = this.rgba2hex(this.red, this.green, val, this.matchHexA())this.handHEXtoRGB(this.bgColor)}},matchHexA() {let percentage = this.alpha * 0.01;return percentage;},rgba2hex(r, g, b, a = 1) {r = parseInt(r);let r1 =r.toString(16).length !== 2 ? "0" + r.toString(16) : r.toString(16);g = parseInt(g);let g1 =g.toString(16).length !== 2 ? "0" + g.toString(16) : g.toString(16);b = parseInt(b);let b1 =b.toString(16).length !== 2 ? "0" + b.toString(16) : b.toString(16);a = parseFloat(a);let a1 = "";if (a !== 1) {let temp = Math.floor(256 * a);a1 =temp.toString(16).length !== 2? "0" + temp.toString(16): temp.toString(16);}return `#${r1}${g1}${b1}${a1}`.toUpperCase();},handAlpha() {this.alphaSliderStyle = `left: ${this.alpha >= 96 ? "calc(100% - 9px)" : this.alpha + '%'};`;},// 透明度handleChangeAlpha(e) {let w = this.$refs.alpha_slider.clientWidth;let x =e.pageX - this.$refs.saturation_value.getBoundingClientRect().left;x = x < w && x > 0 ? x : x > w ? w : 0;// 计算透明度this.alpha = Math.floor((x / w) * 100 + 0.5);// 移动滑块this.alphaSliderStyle = `left: ${x >= w - 6 ? w - 9 : x}px;`;if (!this.colorselecotr) {this.bgColor = this.rgba2hex(this.red, this.green, this.blue, this.matchHexA())this.handHEXtoRGB(this.bgColor)}},mousedownAlpha(e) {this.handleChangeAlpha(e);window.addEventListener("mousemove", this.handleChangeAlpha);window.addEventListener("mouseup", this.mouseupAlpha);},mouseupAlpha(e) {window.removeEventListener("mousemove", this.handleChangeAlpha);window.removeEventListener("mouseup", this.mouseupAlpha);},handleCommand(command) {this.colorType = command;if (command === "RGB") {this.handHEXtoRGB(this.bgColor)}},isHexColorCode(str) {return /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/.test(str);},handHEXtoRGB: debounce(function (color) {if (!this.isHexColorCode(color)) {message.message("当前非HEX编码,请重新输入!", "error");return}const { r, g, b, a } = this.parseColor(color);this.red = r;this.green = g;this.blue = b;if (this.isLinearStart) {this.$emit('update:leftColor', color)} else {this.$emit('update:rightColor', color)}}, 500),parseColor(color) {if (color) {let r, g, b, a;if (typeof color === "string") {if (/^#?([0-9a-fA-F]{6}|[0-9a-fA-F]{8}|[0-9a-fA-F]{3}|[0-9a-fA-F]{4})$/.test(color)) {return this.hex2rgba(color);}} else {r = color.r > 255 ? 255 : color.r < 0 ? 0 : color.r;g = color.g > 255 ? 255 : color.g < 0 ? 0 : color.g;b = color.b > 255 ? 255 : color.b < 0 ? 0 : color.b;a = color.a > 1 ? 1 : color.a < 0 ? 0 : color.a;return { r, g, b, a };}} else {return null;}},hex2rgba(s) {if (/^#?[0-9a-fA-F]{3}$/.test(s)) {let b = s.substring(s.length - 1, s.length);let g = s.substring(s.length - 2, s.length - 1);let r = s.substring(s.length - 3, s.length - 2);return hex2rgba(`${r + r}${g + g}${b + b}`);}if (/^#?[0-9a-fA-F]{4}$/.test(s)) {let a = s.substring(s.length - 1, s.length);let b = s.substring(s.length - 2, s.length - 1);let g = s.substring(s.length - 3, s.length - 2);let r = s.substring(s.length - 4, s.length - 3);return hex2rgba(`${r + r}${g + g}${b + b}${a + a}`);}if (/^#?[0-9a-fA-F]{6}$/.test(s)) {let b = parseInt("0x" + s.substring(s.length - 2, s.length));let g = parseInt("0x" + s.substring(s.length - 4, s.length - 2));let r = parseInt("0x" + s.substring(s.length - 6, s.length - 4));return { r, g, b, a: 1 };}if (/^#?[0-9a-fA-F]{8}$/.test(s)) {let a = parseInt("0x" + s.substring(s.length - 2, s.length));a = a / 255;let b = parseInt("0x" + s.substring(s.length - 4, s.length - 2));let g = parseInt("0x" + s.substring(s.length - 6, s.length - 4));let r = parseInt("0x" + s.substring(s.length - 8, s.length - 6));return { r, g, b, a };}},},
};
</script><style scoped lang="less">
.colorDemoList {width: 100%;list-style-type: none;padding: 13px 0 0 0;margin: 0;li {display: inline-block;width: 16px;cursor: pointer;border-radius: 2px;height: 16px;margin: 0 9px 8px 0;}
}/* 颜色方块 */
.color-diamond {position: relative;width: 24px;height: 24px;border-radius: 2px;overflow: hidden;background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAWElEQVRIiWM8fubkfwYygKWJOSM5+mCAhRLNoxaPWjxq8ajFoxbTyeL/DAfJ0Xjs3Cl7Siwmu4Yht1aDgZEYx6MWj1o8avGoxaMWD3qLya5X//4nqx6HAQC7RBGFzolqTAAAAABJRU5ErkJggg==");background-size: 10px 10px;margin-right: 8px;
}.iconright {font-size: 15px;cursor: pointer;
}.strawcss {display: flex;align-items: center;justify-content: center;width: 24px;padding-left: 5px;img {cursor: pointer;}
}.eldropdownColor {width: 56px;color: #fff;}.colorPickerBody {height: 100%;width: 100%;padding: 5px 11px 13px 11px;&-top {padding: 10px 0 12px 0;width: 100%;height: 100%;&-one {display: flex;align-items: center;}&-two {display: flex;align-items: center;justify-content: space-between;padding-top: 12px;width: 100%;&-body {width: 100%;display: flex;flex-direction: row;align-items: center;position: relative;&-tag {position: absolute;left: -1px;top: -2px;cursor: pointer;z-index: 1;}img {width: 14px;height: 18px;}&-tagRight {position: absolute;right: -1px;top: -2px;cursor: pointer;}&-center {left: 6px;position: absolute;width: calc(100% - 12px);height: 12px;box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAWElEQVRIiWM8fubkfwYygKWJOSM5+mCAhRLNoxaPWjxq8ajFoxbTyeL/DAfJ0Xjs3Cl7Siwmu4Yht1aDgZEYx6MWj1o8avGoxaMWD3qLya5X//4nqx6HAQC7RBGFzolqTAAAAABJRU5ErkJggg==");background-size: 10px 10px;}}}&-three {width: 100%;display: flex;justify-content: space-between;align-items: center;padding-top: 20px;&-Alpha {width: 80%}&-number {width: 15%;::v-deep.el-input__suffix {right: 2px;top: 1px;}.suffixInput {color: #fff;font-size: 12px;}.alphaValcss {width: 44px;::v-deep .el-input__inner {text-align: center;height: 24px;font-size: 12px;padding: 0 3px;border-radius: 5px;border: 1px solid #484849;background: #29292cFF;color: #fff;}}}}.colorValcss {width: 119px;::v-deep .el-input__inner {height: 24px;border-radius: 2px 2px 2px 2px;border: 1px solid #484849;background: #29292cFF;color: #fff;}}.colorRGBBox {display: flex;}.colorRGBValcss {width: 40px;::v-deep .el-input__inner {height: 24px;padding: 0 3px;text-align: center;border-radius: 2px 2px 2px 2px;border: 1px solid #484849;background: #29292cFF;color: #fff;}}}&-border {height: 1px;background: #484849;margin: 0 0 12px 0;width: 100%;}&-body {width: 100%;height: 100%;&-headers {display: flex;justify-content: space-between;align-items: center;&-title {color: #fff;font-size: 14px;}&-svg {width: 43px;display: flex;justify-content: space-between;.checkbuttom {background: #3C3C3F;border-radius: 2px 2px 2px 2px;}.boxbuttom {width: 22px;height: 22px;display: flex;justify-content: center;align-items: center;}img {width: 16px;height: 16px;cursor: pointer;}}}}&-headers {::v-deep .el-radio-group {display: flex;}::v-deep .el-radio-button__inner {background: #29292c;border-radius: 2px 2px 2px 2px;border: 1px solid #484849;color: #99999b;width: 116px;height: 28px;box-shadow: none;}// 修改激活后的样式::v-deep .el-radio-button__orig-radio:checked+.el-radio-button__inner {background: #373739;border-radius: 2px 2px 2px 2px;border: 1px solid #484849;color: #fff;}}
}.colorInputBody {display: flex;flex-direction: Row;align-items: center;height: 30px;width: 120px;padding-left: 8px;border: 1px solid #000;border-radius: 5px;&-title {padding-left: 8px;color: #000;}
}.colorNoTextBody {width: 30px;height: 30px;border: none;padding: 3px;&-colorBox {width: 24px;height: 24px;border-radius: 4px;}
}.colorBox {width: 26px;height: 14px;
}/* 透明度滑块条 */
.alpha-slider {border-radius: 10px;position: relative;height: 12px;box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAWElEQVRIiWM8fubkfwYygKWJOSM5+mCAhRLNoxaPWjxq8ajFoxbTyeL/DAfJ0Xjs3Cl7Siwmu4Yht1aDgZEYx6MWj1o8avGoxaMWD3qLya5X//4nqx6HAQC7RBGFzolqTAAAAABJRU5ErkJggg==");background-size: 10px 10px;
}/* 滑块 */
.slider {border-radius: 20px;position: absolute;box-shadow: 0 0 2px rgba(0, 0, 0, 0.6);box-sizing: border-box;width: 12px;height: 100%;border: 3px solid #fff;
}
</style>

3.选择器的颜色板,MyColorSelect.vue页面

<template><div class="color-select"><div class="saturation-value" ref="saturation_value" @mousedown="mousedownSV"><div :style="'background-color: hsl(' + hue + ', 100%, 50%);'"><div class="point" :style="pointStyle"></div></div><div class="saturation-value-2"></div><div class="saturation-value-3"></div></div><div class="color-select-middle"><div style="flex: auto"><div class="hue-slider" ref="hue_slider" @mousedown="mousedownHue"><div class="slider" :style="hueSliderStyle"></div></div></div></div></div>
</template><script>
export default {name: "MyColorSelect",props: {color: {type: String,default: "",},alphaValue: {type: Number,default: 100,},},data() {return {pointStyle: "top: 25%; left: 80%;",hueSliderStyle: "left: 0;",hue: 0,saturation: 1,value: 1,red: 255,green: 0,blue: 0,alpha: 1,};},watch: {color: {handler(val) {this.handParse(val);},},alphaValue: {handler(val) {this.$emit("update:color",this.rgba2hex(this.red, this.green, this.blue, this.matchHexA()));},},},mounted() {this.handParse(this.color);},methods: {handParse(color) {if ((this.parseColor(color) ?? "") !== "") {const { r, g, b, a } = this.parseColor(color);this.red = r;this.green = g;this.blue = b;this.alpha = a;this.updateColor();}},updateColor() {let { h, s, v } = this.rgb2hsv(this.red, this.green, this.blue);this.hue = h;this.saturation = s;this.value = v;// 移动背景板圆圈this.pointStyle = `top: ${100 - v * 100}%;left: ${s * 100}%;`;// 移动色调滑块this.hueSliderStyle = `left: ${(this.hue / 360) * 100}%;`;},rgb2hsv(r, g, b) {let r1 = r / 255;let g1 = g / 255;let b1 = b / 255;let cmax = Math.max(r1, g1, b1);let cmin = Math.min(r1, g1, b1);let d = cmax - cmin;let h, s, v;if (d === 0) {h = 0;} else if (cmax === r1) {h = ((60 * (g1 - b1)) / d + 360) % 360;} else if (cmax === g1) {h = 60 * ((b1 - r1) / d + 2);} else if (cmax === b1) {h = 60 * ((r1 - g1) / d + 4);}if (cmax === 0) {s = 0;} else {s = d / cmax;}v = cmax;h = Math.floor(h + 0.5);s = Math.floor(s * 100 + 0.5) / 100;v = Math.floor(v * 100 + 0.5) / 100;return { h, s, v };},// 色调handleChangeHue(e) {let w = this.$refs.hue_slider.clientWidth;let x =e.pageX - this.$refs.saturation_value.getBoundingClientRect().left;x = x < w && x > 0 ? x : x > w ? w : 0;// 计算色调this.hue = Math.floor((x / w) * 360 + 0.5);// hsv转化为rgblet { r, g, b } = this.hsv2rgb(this.hue, this.saturation, this.value);this.red = r;this.green = g;this.blue = b;// 移动滑块this.hueSliderStyle = `left: ${x >= w - 6 ? w - 6 : x}px;`;this.$emit("update:color", this.rgba2hex(r, g, b, this.matchHexA()));},mousedownHue(e) {this.handleChangeHue(e);window.addEventListener("mousemove", this.handleChangeHue);window.addEventListener("mouseup", this.mouseupHue);},mouseupHue(e) {window.removeEventListener("mousemove", this.handleChangeHue);window.removeEventListener("mouseup", this.mouseupHue);},// 饱和度和亮度handleChangeSV(e) {let w = this.$refs.saturation_value.clientWidth;let h = this.$refs.saturation_value.clientHeight;let x =e.pageX - this.$refs.saturation_value.getBoundingClientRect().left;let y = e.pageY - this.$refs.saturation_value.getBoundingClientRect().top;x = x < w && x > 0 ? x : x > w ? w : 0;y = y < h && y > 0 ? y : y > h ? h : 0;// 计算饱和度和亮度this.saturation = Math.floor((x / w) * 100 + 0.5) / 100;this.value = Math.floor((1 - y / h) * 100 + 0.5) / 100;// hsv转化为rgblet { r, g, b } = this.hsv2rgb(this.hue, this.saturation, this.value);this.red = r;this.green = g;this.blue = b;// 移动背景板圆圈this.pointStyle = `top: ${y}px;left: ${x}px;`;this.$emit("update:color", this.rgba2hex(r, g, b, this.matchHexA()));},matchHexA() {let percentage = this.alphaValue * 0.01;return percentage;},mousedownSV(e) {// 鼠标按下计算饱和度和亮度并添加事件this.handleChangeSV(e);// 添加整个页面的鼠标事件window.addEventListener("mousemove", this.handleChangeSV);window.addEventListener("mouseup", this.mouseupSV);},mouseupSV(e) {// 鼠标松开后移除事件window.removeEventListener("mousemove", this.handleChangeSV);window.removeEventListener("mouseup", this.mouseupSV);},parseColor(color) {if (color) {let r, g, b, a;if (typeof color === "string") {if (/^#?([0-9a-fA-F]{6}|[0-9a-fA-F]{8}|[0-9a-fA-F]{3}|[0-9a-fA-F]{4})$/.test(color)) {return this.hex2rgba(color);}} else {r = color.r > 255 ? 255 : color.r < 0 ? 0 : color.r;g = color.g > 255 ? 255 : color.g < 0 ? 0 : color.g;b = color.b > 255 ? 255 : color.b < 0 ? 0 : color.b;a = color.a > 1 ? 1 : color.a < 0 ? 0 : color.a;return { r, g, b, a };}} else {return null;}},hsv2rgb(h, s, v) {h === 360 && (h = 0);let i = Math.floor(h / 60) % 6;let f = h / 60 - i;let p = v * (1 - s);let q = v * (1 - s * f);let t = v * (1 - s * (1 - f));let r, g, b;if (i === 0) {r = v;g = t;b = p;} else if (i === 1) {r = q;g = v;b = p;} else if (i === 2) {r = p;g = v;b = t;} else if (i === 3) {r = p;g = q;b = v;} else if (i === 4) {r = t;g = p;b = v;} else if (i === 5) {r = v;g = p;b = q;}r = Math.floor(r * 255 + 0.5);g = Math.floor(g * 255 + 0.5);b = Math.floor(b * 255 + 0.5);return { r, g, b };},rgba2hex(r, g, b, a = 1) {r = parseInt(r);let r1 =r.toString(16).length !== 2 ? "0" + r.toString(16) : r.toString(16);g = parseInt(g);let g1 =g.toString(16).length !== 2 ? "0" + g.toString(16) : g.toString(16);b = parseInt(b);let b1 =b.toString(16).length !== 2 ? "0" + b.toString(16) : b.toString(16);a = parseFloat(a);let a1 = "";if (a !== 1) {let temp = Math.floor(256 * a);a1 =temp.toString(16).length !== 2? "0" + temp.toString(16): temp.toString(16);}return `#${r1}${g1}${b1}${a1}`.toUpperCase();},hex2rgba(s) {if (/^#?[0-9a-fA-F]{3}$/.test(s)) {let b = s.substring(s.length - 1, s.length);let g = s.substring(s.length - 2, s.length - 1);let r = s.substring(s.length - 3, s.length - 2);return hex2rgba(`${r + r}${g + g}${b + b}`);}if (/^#?[0-9a-fA-F]{4}$/.test(s)) {let a = s.substring(s.length - 1, s.length);let b = s.substring(s.length - 2, s.length - 1);let g = s.substring(s.length - 3, s.length - 2);let r = s.substring(s.length - 4, s.length - 3);return hex2rgba(`${r + r}${g + g}${b + b}${a + a}`);}if (/^#?[0-9a-fA-F]{6}$/.test(s)) {let b = parseInt("0x" + s.substring(s.length - 2, s.length));let g = parseInt("0x" + s.substring(s.length - 4, s.length - 2));let r = parseInt("0x" + s.substring(s.length - 6, s.length - 4));return { r, g, b, a: 1 };}if (/^#?[0-9a-fA-F]{8}$/.test(s)) {let a = parseInt("0x" + s.substring(s.length - 2, s.length));a = a / 255;let b = parseInt("0x" + s.substring(s.length - 4, s.length - 2));let g = parseInt("0x" + s.substring(s.length - 6, s.length - 4));let r = parseInt("0x" + s.substring(s.length - 8, s.length - 6));return { r, g, b, a };}},},
};
</script><style scoped>
.color-select {position: relative;user-select: none;width: 100%;padding: 12px 0 0 0;
}/* 饱和度和亮度 */
.saturation-value {cursor: pointer;width: 100%;height: 148px;position: relative;margin-bottom: 12px;box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
}.saturation-value>div {position: absolute;top: 0;left: 0;width: 100%;height: 100%;
}/* 圆圈 */
.point {box-sizing: border-box;width: 6px;height: 6px;background-color: transparent;border: 2px solid #ccc;border-radius: 50%;transform: translate(-50%, -50%);position: absolute;z-index: 9;
}.saturation-value-2 {background: linear-gradient(to right, white, #ffffff00);
}.saturation-value-3 {background: linear-gradient(to top, black, #ffffff00);
}/* 色调滑块条 */
.hue-slider {position: relative;height: 10px;background: linear-gradient(90deg,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red);box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
}/* 滑块 */
.slider {position: absolute;box-shadow: 0 0 2px rgba(0, 0, 0, 0.6);box-sizing: border-box;width: 6px;height: 100%;background-color: #fff;
}
</style>

4.其中utils文件夹里的两个文件如下

message.js

import { Message, MessageBox } from 'element-ui';let message = {message: function(str, type = 'success') {Message[type](str);},confirm: function(text, title = '提示', confirm = null, cancel = null) {MessageBox.confirm(text, title, {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then((res) => {confirm && confirm(res);}).catch((res) => {cancel && cancel(res);});}
};export default message;

util.js

//防抖
export const  debounce=(fn, t) =>{const delay = t || 100;let timer = null;return function() {const args = arguments;const context = this;if (timer) {clearTimeout(timer);}timer = setTimeout(() => {timer = null;fn.apply(context, args);}, delay);};
}

5.重点:elementStyle.css样式文件,用于更改选择器的覆盖颜色

elementStyle.css文件需要在main.js引入

import '@/assets/css/elementStyle.css'

在这里插入图片描述

6.elementStyle.css代码如下

.el-popover{background: #303030 ;color: #ffffff;font-size: 12px;border: 1px solid rgba(255, 255, 255, 0.06);padding: 5px 5px;min-width: 40px;}.popper__arrow {display: none !important;
}
.el-dropdown-menu{background: #303030;border: 1px solid rgba(255, 255, 255, 0.06);
}
.el-dropdown-menu__item {color: #fff;width: 70px;}.el-dropdown-menu__item:focus,.el-dropdown-menu__item:not(.is-disabled):hover {background: #373739FF;}

7.引入的图片和svg图片在项目源码包里src/assets/image路径下

8.注意点

如果下载源码的话先

先执行
yarn install
再执行
yarn serve

运行成功后直接使用
http://127.0.0.1:8000/home访问

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/327935.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[vue] nvm

nvm ls // 看安装的所有node.js的版本nvm list available // 查显示可以安装的所有node.js的版本可以在可选列表里。选择任意版本安装&#xff0c;比如安装16.15.0 执行&#xff1a; nvm install 16.15.0安装好了之后。可以执行&#xff1a; …

鸿蒙内核源码分析 (内核启动篇) | 从汇编到 main ()

这应该是系列篇最难写的一篇&#xff0c;全是汇编代码&#xff0c;需大量的底层知识&#xff0c;涉及协处理器&#xff0c;内核镜像重定位&#xff0c;创建内核映射表&#xff0c;初始化 CPU 模式栈&#xff0c;热启动&#xff0c;到最后熟悉的 main() 。 内核入口 在链接文件…

FreeRTOS开发一、FreeRTOS移植

1、FreeRTOS 源码下载 两个下载链接&#xff0c; 一个是官网&#xff1a;http://www.freertos.org/&#xff0c; 另外一个是代码托管网站&#xff1a;https://sourceforge.net/projects/freertos/files/FreeRTOS/ 打开代码托管网站链接&#xff0c;我们选择FreeRTOS 的版本 V9…

全域运营平台是什么?优缺点有哪些?

当下&#xff0c;全域运营赛道逐渐兴盛&#xff0c;全域运营服务商的数量也开始呈现爆发趋势。在此背景下&#xff0c;很多人都对某些品牌的全域运营平台优缺点产生了浓厚的兴趣。由于小编只使用过微火全域运营平台&#xff0c;因此&#xff0c;本期会着重分析微火运营平台的优…

【软考】设计模式之桥接模式

目录 1. 说明2. 应用场景3. 结构图4. 构成5. 适用性6. 优点7. 缺点8. java示例 1. 说明 1.将抽象部分与其实现部分分离&#xff0c;使它们都可以独立地变化。2.桥接模式&#xff08;Bridge Pattern&#xff09;属于对象结构型模式&#xff0c;又称为柄体&#xff08;Handle an…

Leetcode2105. 给植物浇水 II

Every day a Leetcode 题目来源&#xff1a;2105. 给植物浇水 II 解法1&#xff1a;双指针 设 Alice 当前下标为 i&#xff0c;初始化为 0&#xff0c;水量为 a&#xff0c;初始化为 capacityA&#xff1b;Bob 当前下标为 j&#xff0c;初始化为 n-1&#xff0c;水量为 b&am…

力扣98.验证二叉搜索树

法一&#xff08;自己思路&#xff0c;复杂了&#xff09;&#xff1a; from collections import dequeclass Solution(object):def isValidBST(self, root):""":type root: TreeNode:rtype: bool"""queue deque()if root.left!None:queue.app…

FOSS全闪对象存储--与AI/ML相向而行

行业解读需求剖析 目前&#xff0c;随着AI/ML技术得到了快速的发展及应用&#xff0c;AI/ML系统对底层高速数据访问的需求也日趋强烈&#xff0c;虽然当前业界有多种解决方案&#xff0c;但都存在一些成本或性能方面的挑战&#xff0c;就目前常用的文件存储系统来说&#xff0…

win10共享文件夹到ubuntu22

win10共享文件夹 新建用户 新建用户、设置密码。避免共享给EveryOne&#xff0c;导致隐私问题。 点击左下角的开始菜单&#xff0c;选择“设置”&#xff08;WinI&#xff09;打开设置窗口。在设置窗口中&#xff0c;搜索或直接点击“账户”进入账户设置。在账户设置中&…

机器学习中常用的几种距离——欧式、余弦等

目录 一、欧式距离&#xff08;L2距离&#xff09;二、曼哈顿距离&#xff08;L1距离&#xff09;三、汉明距离四、余弦相似度 一、欧式距离&#xff08;L2距离&#xff09; &#xff08;1&#xff09;二维空间的距离公式&#xff08;三维空间的在这个基础上类推&#xff09;&…

Windows本地部署直播录屏利器Bililive-go并实现远程添加直播间录屏

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 1. Bililive-go与套件下载1.1 获取ffmpeg1.2 获取Bililive-go1.3 配置套件 2. 本地运行测试3. 录屏…

基于单片机的光照检测系统—光敏电阻

基于单片机的光照检测系统 &#xff08;仿真&#xff0b;程序&#xff0b;原理图&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.光敏电阻实时采集环境光照值&#xff1b; 2.采用ADC0804将模拟值转换为数字量&#xff1b; 3.四位数码管显示当前的光照…

Java JDK下载安装教程(2024年)

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

金士顿硬盘误删数据不用慌,这些恢复方法帮你忙

在数字化日益盛行的今天&#xff0c;硬盘作为存储数据的重要设备&#xff0c;其安全性与稳定性显得尤为关键。然而&#xff0c;即便是品质卓越的金士顿硬盘&#xff0c;也难免会遇到误删除数据的尴尬情况。面对这种情况&#xff0c;许多用户往往感到手足无措&#xff0c;甚至产…

LLM Agent智能体综述(万字长文)

前言 &#x1f3c6;&#x1f3c6;&#x1f3c6;在上一篇文章中&#xff0c;我们介绍了如何部署MetaGPT到本地&#xff0c;获取OpenAI API Key并配置其开发环境&#xff0c;并通过一个开发小组的多Agent案例感受了智能体的强大&#xff0c;在本文中&#xff0c;我们将对AI Agent…

Franz Electron + React 源码启动运行填坑指南

环境要求 安装miniconda python 环境electron/rebuild用得着&#xff0c;miniconda 默认自带的 python 是 3.11 版本&#xff0c;比较新&#xff1b; 安装virsual studio 2019 要把C桌面相关的都安装了&#xff0c;大概需要20G&#xff0c;不要安装到 C 盘&#xff0c;都安装到…

FlyFlow:支持驳回后自动跨节点跳回

本周更新 新增&#xff1a;审批节点驳回&#xff08;拒绝配置的驳回&#xff09;支持自动跳回当前节点新增&#xff1a;修改数据节点新增&#xff1a;删除数据节点新增&#xff1a;子流程支持配置自动跳过发起人节点优化&#xff1a;两个项目合并一个单体项目优化&#xff1a;…

JavaEE初阶-多线程进阶2

文章目录 前言一、CAS1.1 CAS的概念1.2 原子类1.3 CAS的ABA问题 二、JUC中常用类2.1 Callable接口2.2 ReentrantLock&#xff08;可重入&#xff09;2.3 Semaphore信号量2.4 CountDownLatch类2.5 CopyOnWriteArrayList类2.6 ConcurrentHashMap 前言 对于多线程进阶的部分&…

linux安装Openresty

安装必要的依赖库 指定仓库地址 下载openresty 添加环境变量 vi /etc/profile i export NGINX_HOME/usr/local/openresty/nginx/ export PATH${NGINX_HOME}/sbin:$PATH esc :wq source /etc/profile #启动 nginx # 重启 nginx -s reload #关闭 nginx -s stop

【class8】人工智能初步(图像识别-----卷积神经网络)

上节回顾 上节课&#xff0c;我们简单了解了图像识别和深度学习的相关知识。 快速回顾一下吧&#xff5e; A图像识别是以图像的主要特征为基础的。B. 图像分辨率决定图像的质量。 C&#xff0e; 像素是图像中的最小单位D. 在图像识别的原理上&#xff0c;计算机和人类在本质…