赞
踩
vue 2.6.14
less 3.13.1
element-ui 2.15.6
less-loader 5.0.0
支持RGB、HEX编码、支持吸管吸取颜色、颜色选择器、颜色模板、透明度、色板、线性渐变颜色
<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>
<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"><img src="@/assets/image/colordemo.svg"> </div> <div :class="!colorselecotr ? 'boxbuttom checkbuttom' : 'boxbuttom '" @click="colorselecotr = false"><img src="@/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) * 100 this.handAlpha() }, // tag handActive(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 : null if (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>
<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转化为rgb let { 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转化为rgb let { 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>
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); }; }
elementStyle.css文件需要在main.js引入
import '@/assets/css/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; }
如果下载源码的话先
先执行
yarn install
再执行
yarn serve
运行成功后直接使用
http://127.0.0.1:8000/home访问
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。