【基于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.mzph.cn/news/836426.shtml

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

相关文章

web前端之纯CSS实现简单酷炫的照片墙效果、排除元素的伪类、scale

MENU 效果htmlstylescale:not() 效果 html <div class"container"><div class"box"><img src"../../image/1_.jpg"></div><div class"box"><img src"../../image/2_.jpg"></div>…

【python量化交易】qteasy使用教程06——创建自定义因子选股交易策略

创建自定义因子选股策略 使用qteasy创建自定义因子选股交易策略开始前的准备工作本节的目标Alpha选股策略的选股思想计算选股指标用FactorSorter定义Alpha选股策略交易策略的回测结果用GeneralStg定义一个Alpha选股策略回测结果&#xff1a;本节回顾 使用qteasy创建自定义因子选…

Electron、QT、WPF三强争霸,该支持谁呢?

Electron、QT、WPF都是跨平台的桌面应用开发框架&#xff0c;都是非常流行的&#xff0c;作为开发者该选用哪个呢&#xff1f;本文从多个角度分析一下。 一、定义 Electron、Qt 和 WPF 都是用于创建桌面应用程序的框架或工具&#xff0c;它们各自有着不同的特点和优势。 Elec…

Linux-笔记 开发板Uboot命令使用

将之前自学的知识整理了一下笔记&#xff0c;以便回忆 信息查询命令 1、help/?&#xff1a;查看所支持命令 > ? md md - memory displayUsage: md [.b, .w, .l] address [# of objects]2、bdinfo&#xff1a;查询板子信息 > bdinfo arch_number 0x00000000 boot_p…

匿名管道及其应用

目录 一、什么是匿名管道&#xff1f; 三、创建与使用匿名管道 三、匿名管道的特点 匿名管道的四种情况 匿名管道的五种特性 四、匿名管道的实践应用---进程池 在编程的世界中&#xff0c;匿名管道是一种非常重要的通信机制。今天&#xff0c;让我们一起来深入探讨一下匿…

vivado Virtex-7 配置存储器器件

Virtex-7 配置存储器器件 下表所示闪存器件支持通过 Vivado 软件对 Virtex -7 器件执行擦除、空白检查、编程和验证等配置操作。 本附录中的表格所列赛灵思系列非易失性存储器将不断保持更新 &#xff0c; 并支持通过 Vivado 软件对其中所列非易失性存储器 进行擦除、…

单链表经典算法OJ题---力扣206,876(带图详解

1.链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;【点击即可跳转】 思路&#xff1a;创建三个指针&#xff0c;看下图 注意&#xff1a;n3如果为空&#xff0c;则不能继续指向下一节点&#xff0c;需要进行判断 代码实现&#xff1a; struct ListNode* reverseLi…

第二课,python基础语法(一),认识字面量和变量、注释

一&#xff0c;字面量 &#xff08;一&#xff09;什么是字面量 被写下来的的固定的值&#xff0c;称之为字面量 &#xff08;二&#xff09;常见的三种字面量类型 &#xff08;三&#xff09;练习一下&#xff0c;使用print去输出三种不同类型的字面量&#xff1a;10&#x…

树莓派安装opencv

安装opencv 上述步骤完成后&#xff0c;输入以下代码(基于python3) sudo apt-get install python3-opencv -y不行的话&#xff0c;试试换源&#xff0c;然后 sudo apt-get update成功&#xff01; 测试opencv是否安装成功 输入 python3 然后再输入 import cv2 没有报错就…

【Java】:向上转型、向下转型和ClassCastException异常

目录 先用一个生动形象的例子来解释向上转型和向下转型 向上转型&#xff08;Upcasting&#xff09; 向下转型&#xff08;Downcasting&#xff09; 向上转型 概念 例子 发生向上转型的情况 1.子类对象赋值给父类引用 2.方法参数传递 3.返回值 向下转型 概念 注意…

扩散模型(Diffusion Model)学习笔记

目录 Diffusion Model 基本原理 预测原理 ddpm 实例 ddmp数字图片生成 有的还没看完 Diffusion Model 基本原理 扩散模型1&#xff1a;基本原理 - 知乎 前向扩散过程可以理解为一个马尔可夫链&#xff0c;即通过逐步对一张真实图片添加高斯噪声直到最终变成纯高斯噪声图片…

labview技术交流-字符串数组连接成字符串

应用场景 我们可能需要将一维的字符串数组转换成一整条字符串&#xff0c;然后方便记录在数据库或表格中的一个单元格中。 代码展示 方案一 我们使用for循环完成这样的功能需求&#xff0c;见下图&#xff1a; 这种方案可能相对基础和普通&#xff0c;但是它更方便和易于扩展…

【科研绘图 基础版】01 使用Python绘制时间序列折线图

下面这段代码绘制了一个折线图&#xff0c;其中包含了实际平均温度数据和使用线性回归模型预测的平均温度数据&#xff08;用来近似地表示数据的整体趋势&#xff09;。 具体来说&#xff0c;图中的横轴表示年份&#xff0c;纵轴表示平均温度。蓝色的实心线代表了实际的平均温度…

《Python机器学习 》书籍分享

文章目录 前言内容介绍作者简介书籍目录 前言 随着计算能力的快速增长&#xff0c;大量任务都可在台式机上完成&#xff1b;在这样的背景下&#xff0c;机器学习应运而生&#xff0c;成为当今炙手可热的话题。但初出茅庐的新手常对机器学习感到十分畏惧&#xff1b;为给这些新…

面试集中营—Seata分布式事务

一、分布式事务 本地事务 在计算机系统中&#xff0c;更多的是通过关系型数据库来控制事务&#xff0c;这是利用数据库本身的事务特性来实现的&#xff0c; 因此叫数据库事务&#xff0c;由于应用主要靠关系数据库来控制事务&#xff0c;而数据库通常和应用在同一个服务器&am…

数据结构:包装类初始泛型

目录 1.包装类1.1 基本数据类型和对应的包装类1.2 装箱和拆箱 2.什么是泛型3.引出泛型3.1 语法3.2 泛型的使用 4.泛型是如何编译的4.1 擦除机制4.2 为什么不能实例化泛型类型数组 5.泛型的上界5.1 语法5.2 示例5.3 复杂示例 6.泛型方法6.1 定义语法6.2 示例6.3 使用示例-可以类…

【CMU 15-445】Proj4 Concurrency Control

Concurrency Control 通关记录Task1 TimestampsTask2 Storage Format and Sequential ScanTask3 MVCC ExecutorsTask3.1 Insert ExecutorTask3.2 CommitTask3.3 Update and Delete ExecutorTask3.4 Stop-the-world Garbage Collection Task4 Primary Key IndexTask4.0 Index Sc…

Springboot+logback 详细配置

一、添加依赖 这里使用springboot3.0.2 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency><dependency><groupId>org.projectlombok</grou…

macos使用yarn创建vite时出现Usage Error: The nearest package directory问题

步骤是macos上使用了yarn create vite在window上是直接可以使用了yarn但是在macos上就出现报错 我们仔细看&#xff0c;它说的If /Users/chentianyu isnt intended to be a project, remove any yarn.lock and/or package.json file there.说是要我们清除yarn.lock和package.js…

yolo world 瑞芯微芯片rknn部署、地平线芯片Horizon部署、TensorRT部署

特别说明&#xff1a;参考官方开源的 yoloworld 代码、瑞芯微官方文档、地平线的官方文档&#xff0c;如有侵权告知删&#xff0c;谢谢。 模型和完整仿真测试代码&#xff0c;放在github上参考链接 模型和代码。 yoloworld出来的有一段时间了&#xff0c;还没有盘到板端上玩一玩…