vue自定义颜色选择器(重置版)

 实现效果

相较于上次发布的颜色选择器,这次加入了圆形的选择器,并且优化了代码。

<SquareColor ref="squareColor" :color="color" @change="changeColor1" />

setColor1() {
            // this.color = 'rgba(255, 82, 111, 0.5)'
            this.$refs.squareColor.changeColor('rgba(255, 82, 111, 0.5)')
        }

使用方式:可以使用color属性传入默认颜色,目前支持hex16进制,rgb,rgba,hsl这四种格式,使用change事件获取颜色修改后的值,如果需要父组件动态修改其中的颜色则需要调用组件中的changeColor方法。

如果需要修改传出的颜色类型可以在组件中的getRGBA方法中进行修改,或者在父组件中使用color-convert进行转换。

在使用该组件之前需要引入color-convert依赖

npm install color-convert

完整代码:该代码主要分为四个部分(方形选择器组件,圆形选择器组件,utils,父组件示例)

方形选择器:

<template>
    <div class="color-box">
        <div class="color-panel" ref="colorPanel" @mousedown="colorPanelMD" :style="{ background: colorPanelColor }">
            <div class="color-white-panel"></div>
            <div class="color-black-panel"></div>
            <div ref="colorPanelSliderThumb" class="color-panel-slider-thumb"></div>
        </div>
        <div class="hue-panel" ref="huePanel" @mousedown="huePanelMD">
            <div ref="huePanelSliderThumb" class="hue-slider-thumb"></div>
        </div>
        <div class="alpha-panel" ref="alphaPanel" @mousedown="alphaPanelMD">
            <div class="alpha-panel-cover"
                :style="{ background: `linear-gradient(to right, rgba(255, 255, 255, 0) 0, ${colorPanelColor} 100%)` }">
            </div>
            <div ref="alphaPanelSliderThumb" class="alpha-slider-thumb"></div>
        </div>
    </div>
</template>

<script>
import convert from 'color-convert'
import { colorTypeConversion } from '@/utils'
export default {
    props: {
        color: {
            type: String,
            required: true,
            default: ''
        }
    },
    data() {
        return {
            colorPanelColor: 'red',
            h: 0,
            s: 0,
            v: 100,
            alpha: 1,
        };
    },
    mounted() {
        this.changeColor(this.color)
    },

    methods: {
        // 设置颜色 转换颜色为hsv类型
        changeColor(val) {
            let colorObj = colorTypeConversion(val)
            if (colorObj?.alpha) {
                this.alpha = colorObj.alpha
            }
            if (colorObj?.color?.length == 3) {
                let [h, s, v] = colorObj.color
                // 判断当前颜色是否和需要转换的颜色是否一致,一致则不进行转换
                if (this.h !== h || this.s !== s || this.v !== v) {
                    this.h = colorObj.color[0]
                    this.s = colorObj.color[1]
                    this.v = colorObj.color[2]
                    this.$nextTick(() => {
                        this.initPosi();
                    })
                }
            }
        },
        // 初始化hsv初始位置
        initPosi() {
            // 设置色相条按钮位置
            this.$refs.huePanelSliderThumb.style.left = this.h / 360 * this.$refs.huePanel.offsetWidth + 'px'
            // 设置透明度条按钮位置
            this.$refs.alphaPanelSliderThumb.style.left = this.alpha * this.$refs.alphaPanel.offsetWidth + 'px'
            // 设置色盘按钮位置
            this.$refs.colorPanelSliderThumb.style.left = this.s / 100 * this.$refs.colorPanel.offsetWidth + 'px'
            this.$refs.colorPanelSliderThumb.style.top = (100 - this.v) / 100 * this.$refs.colorPanel.offsetHeight + 'px'
            // 设置色盘和透明度背景色
            this.colorPanelColor = '#' + convert.hsv.hex(this.h, this.s, this.v)
        },
        // 色盘鼠标事件
        colorPanelMD(e) {
            let that = this
            let colorPanel = that.$refs.colorPanel
            let colorPanelSliderThumb = that.$refs.colorPanelSliderThumb
            let { width, height } = colorPanel.getBoundingClientRect()
            colorPanelSliderThumb.style.left = that.judgeBoundary(e.offsetX, 0, width) + 'px'
            colorPanelSliderThumb.style.top = that.judgeBoundary(e.offsetY, 0, height) + 'px'
            that.getSV()
            let initLeft = colorPanelSliderThumb.offsetLeft
            let initTop = colorPanelSliderThumb.offsetTop
            let initX = e.pageX
            let initY = e.pageY
            document.addEventListener('mousemove', mouseMove)
            function mouseMove(e) {
                colorPanelSliderThumb.style.left = that.judgeBoundary(e.pageX - initX + initLeft, 0, width) + 'px'
                colorPanelSliderThumb.style.top = that.judgeBoundary(e.pageY - initY + initTop, 0, height) + 'px'
                that.getSV()
            }
            document.addEventListener('mouseup', mouseUp)
            function mouseUp() {
                document.removeEventListener('mousemove', mouseMove)
                document.removeEventListener('mouseup', mouseUp)
            }
        },
        // 获取饱和度和明值
        getSV() {
            let that = this
            let colorPanel = that.$refs.colorPanel
            let colorPanelSliderThumb = that.$refs.colorPanelSliderThumb
            let { width, height } = colorPanel.getBoundingClientRect()
            let left = colorPanelSliderThumb.offsetLeft
            let top = colorPanelSliderThumb.offsetTop
            let s = left / width * 100
            let v = 100 - top / height * 100
            that.s = s
            that.v = v
            that.getRGBA();
        },
        // 色相鼠标事件
        huePanelMD(e) {
            let that = this
            let huePanel = that.$refs.huePanel
            let huePanelSliderThumb = that.$refs.huePanelSliderThumb
            let { width } = huePanel.getBoundingClientRect()
            huePanelSliderThumb.style.left = that.judgeBoundary(e.offsetX, 0, width) + 'px'
            that.getHue();
            let initLeft = huePanelSliderThumb.offsetLeft
            let initX = e.pageX
            document.addEventListener('mousemove', mouseMove)
            function mouseMove(e) {
                huePanelSliderThumb.style.left = that.judgeBoundary(e.pageX - initX + initLeft, 0, width) + 'px'
                that.getHue();
            }
            document.addEventListener('mouseup', mouseUp)
            function mouseUp() {
                document.removeEventListener('mousemove', mouseMove)
                document.removeEventListener('mouseup', mouseUp)
            }
        },
        // 获取色相并转换成颜色
        getHue() {
            let that = this
            let huePanel = that.$refs.huePanel
            let huePanelSliderThumb = that.$refs.huePanelSliderThumb
            let { width } = huePanel.getBoundingClientRect()
            let hue = huePanelSliderThumb.offsetLeft / width * 360
            that.h = hue
            let color = convert.hsv.hex(hue, 100, 100)
            that.colorPanelColor = '#' + color
            that.getRGBA();
        },
        // 透明度鼠标事件
        alphaPanelMD(e) {
            let that = this
            let alphaPanel = that.$refs.alphaPanel
            let alphaPanelSliderThumb = that.$refs.alphaPanelSliderThumb
            let { width } = alphaPanel.getBoundingClientRect()
            alphaPanelSliderThumb.style.left = that.judgeBoundary(e.offsetX, 0, width) + 'px'
            that.getAlpha();
            let initLeft = alphaPanelSliderThumb.offsetLeft
            let initX = e.pageX
            document.addEventListener('mousemove', mouseMove)
            function mouseMove(e) {
                alphaPanelSliderThumb.style.left = that.judgeBoundary(e.pageX - initX + initLeft, 0, width) + 'px'
                that.getAlpha();
            }
            document.addEventListener('mouseup', mouseUp)
            function mouseUp() {
                document.removeEventListener('mousemove', mouseMove)
                document.removeEventListener('mouseup', mouseUp)
            }
        },
        getAlpha() {
            let that = this
            let alphaPanel = that.$refs.alphaPanel
            let alphaPanelSliderThumb = that.$refs.alphaPanelSliderThumb
            let { width } = alphaPanel.getBoundingClientRect()
            let alpha = (alphaPanelSliderThumb.offsetLeft / width).toFixed(2)
            that.alpha = alpha
            this.getRGBA();
        },
        // 获取RGBA色值
        getRGBA() {
            let color = convert.hsv.rgb(this.h, this.s, this.v)
            let rgba = `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${this.alpha})`
            this.$emit('change', rgba)
        },
        // 边界判断
        judgeBoundary(value, min, max) {
            if (value < min) {
                return min
            }
            if (value > max) {
                return max
            }
            return value
        },
    },
};
</script>

<style lang="scss" scoped>
.color-box {
    width: 300px;

    .color-panel {
        position: relative;
        height: 200px;
        // background-color: red;

        .color-white-panel {
            position: absolute;
            inset: 0;
            background: linear-gradient(to right, #fff 0%, transparent 100%);
        }

        .color-black-panel {
            position: absolute;
            inset: 0;
            background: linear-gradient(to top, #000 0%, transparent 100%);
        }

        .color-panel-slider-thumb {
            position: absolute;
            top: 0;
            left: 0;
            transform: translate(-50%, -50%);
            width: 5px;
            height: 5px;
            box-shadow: 0 0 2px #5a5a5a;
            border: 3px solid #fff;
            border-radius: 50%;
            pointer-events: none;
        }
    }

    .hue-panel {
        position: relative;
        height: 12px;
        margin: 20px 0;
        background: linear-gradient(to right, red 0, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, red);
    }

    .alpha-panel {
        position: relative;
        height: 12px;
        background: url('../../assets/images/alpha.png');

        .alpha-panel-cover {
            position: absolute;
            inset: 0;
        }

        .alpha-slider-thumb {
            left: 100%;
        }
    }
}


.hue-slider-thumb,
.alpha-slider-thumb {
    position: absolute;
    left: 0;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 5px;
    height: 140%;
    border-radius: 4px;
    background-color: #fff;
    box-shadow: 0 0 2px #5a5a5a;
    cursor: pointer;
    pointer-events: none;
}
</style>

圆形选择器:

<template>
    <div class="color-box">
        <div class="top-part">
            <div :style="{ width: width + 'px', height: width + 'px' }" class="color-panel" ref="colorPanel"
                @mousedown="colorPanelMD">
                <div class="value-bg" ref="valueBg"></div>
                <div ref="colorPanelSliderThumb" class="color-panel-slider-thumb"></div>
            </div>
            <div class="value-panel" @mousedown="valuePanelMD" ref="valuePanel" :style="{ height: width + 'px' }">
                <div ref="valuePanelSliderThumb" class="value-slider-thumb"></div>
            </div>
        </div>
        <div :style="{ width: width + 'px' }" class="alpha-panel" ref="alphaPanel" @mousedown="alphaPanelMD">
            <div class="alpha-panel-cover"
                :style="{ background: `linear-gradient(to right, rgba(255, 255, 255, 0) 0, ${colorPanelColor} 100%)` }">
            </div>
            <div ref="alphaPanelSliderThumb" class="alpha-slider-thumb"></div>
        </div>
    </div>
</template>

<script>
import convert from 'color-convert'
import { colorTypeConversion } from '@/utils'
export default {
    props: {
        width: {
            type: Number,
            default: 200,
            required: false,
        },
        color: {
            type: String,
            required: true,
            default: ''
        }
    },
    data() {
        return {
            h: 0,
            s: 0,
            v: 100,
            alpha: 1,
            colorPanelColor: '#fff',
        };
    },

    mounted() {
        this.changeColor(this.color)
    },

    methods: {
        // 设置颜色 转换颜色为hsv类型
        changeColor(val) {
            let colorObj = colorTypeConversion(val)
            if (colorObj?.alpha) {
                this.alpha = colorObj.alpha
            }
            if (colorObj?.color?.length == 3) {
                let [h, s, v] = colorObj.color
                // 判断当前颜色是否和需要转换的颜色是否一致,一致则不进行转换
                if (this.h !== h || this.s !== s || this.v !== v) {
                    this.h = colorObj.color[0]
                    this.s = colorObj.color[1]
                    this.v = colorObj.color[2]
                    this.$nextTick(() => {
                        this.initPosi();
                    })
                }
            }
        },
        // 初始化hsv初始位置
        initPosi() {
            // 设置明值位置即右侧柱子按钮位置
            let height = this.$refs.valuePanel.getBoundingClientRect().height
            this.$refs.valuePanelSliderThumb.style.top = height - height * this.v / 100 + 'px'
            this.$refs.valueBg.style.background = `rgba(0, 0, 0, ${Number(1 - (this.v / 100).toFixed(2))})`
            // 获取饱和度(长度) 和 色相(夹角)
            const vector = [0, 1]; // 假设圆心为坐标原点,并使用夹角度数配合旋转矩阵以及按钮距离圆心的长度求取按钮在色盘中的位置
            let r = this.width / 2
            let length = this.s / 100 * r
            let angle = -Number((this.h - Math.PI / 180).toFixed(2))
            // 将角度转为弧度
            const angleInRadians = angle * Math.PI / 180;
            // 计算另一个向量
            const x = vector[0] * Math.cos(angleInRadians) - vector[1] * Math.sin(angleInRadians);
            const y = vector[0] * Math.sin(angleInRadians) + vector[1] * Math.cos(angleInRadians);
            // 根据长度进行缩放
            const scaleFactor = length / Math.sqrt(x * x + y * y);
            const newX = x * scaleFactor;
            const newY = y * scaleFactor;
            this.$refs.colorPanelSliderThumb.style.left = newX + r + 'px'
            this.$refs.colorPanelSliderThumb.style.top = r - newY + 'px'
            // 给底部透明度设置背景
            this.colorPanelColor = '#' + convert.hsv.hex(this.h, this.s, this.v)
            // 设置透明度按钮位置
            let { width } = this.$refs.alphaPanel.getBoundingClientRect()
            this.$refs.alphaPanelSliderThumb.style.left = width * this.alpha + 'px'
        },
        colorPanelMD(e) {
            let that = this
            const colorPanelSliderThumb = that.$refs.colorPanelSliderThumb
            colorPanelSliderThumb.style.left = e.offsetX + 'px'
            colorPanelSliderThumb.style.top = e.offsetY + 'px'
            that.calculateAngle() // 计算夹角 获取色相
            let initLeft = colorPanelSliderThumb.offsetLeft
            let initTop = colorPanelSliderThumb.offsetTop
            let initX = e.pageX
            let initY = e.pageY
            document.addEventListener('mousemove', mouseMove)
            function mouseMove(e) {
                let x = e.pageX - initX + initLeft
                let y = e.pageY - initY + initTop
                colorPanelSliderThumb.style.left = that.circleJudgeBoundary(x, y).targetX + 'px'
                colorPanelSliderThumb.style.top = that.circleJudgeBoundary(x, y).targetY + 'px'
                that.calculateAngle() // 计算夹角 获取色相
            }

            document.addEventListener('mouseup', mouseUp)
            function mouseUp(e) {
                document.removeEventListener('mousemove', mouseMove)
                document.removeEventListener('mouseup', mouseUp)
            }
        },
        // 获取当前滑块的向量坐标归一化 并获取其饱和度值
        calcSliderThumbVector() {
            let r = this.width / 2
            const colorPanel = this.$refs.colorPanel
            const colorPanelSliderThumb = this.$refs.colorPanelSliderThumb
            let { width, height, left, top } = colorPanel.getBoundingClientRect()
            let originX = left + width / 2 - colorPanel.offsetLeft
            let originY = top + height / 2 - colorPanel.offsetTop
            let x = (colorPanelSliderThumb.getBoundingClientRect().left - left + colorPanelSliderThumb.getBoundingClientRect().width / 2) - originX
            let y = originY - (colorPanelSliderThumb.getBoundingClientRect().top - top + colorPanelSliderThumb.getBoundingClientRect().height / 2)
            // 获取饱和度
            let s = Number((Math.sqrt(x ** 2 + y ** 2) / r * 100).toFixed(2))
            this.s = s <= 100 ? s : 100
            return this.normalizeVector([x, y])
        },
        // 归一化二维向量
        normalizeVector(vector) {
            // 计算向量的模长
            const magnitude = Math.sqrt(vector[0] ** 2 + vector[1] ** 2);
            // 将向量的每个分量除以模长
            const normalizedVector = [vector[0] / magnitude, vector[1] / magnitude];
            return normalizedVector;
        },
        // 计算两个二维向量的夹角 夹角度数即色相
        calculateAngle(vectorA = [0, 1], vectorB = this.calcSliderThumbVector(), isGetRGBA = true) {
            // 计算向量的点积
            const dotProduct = vectorA[0] * vectorB[0] + vectorA[1] * vectorB[1];
            // 计算向量的模长
            const magnitudeA = Math.sqrt(vectorA[0] ** 2 + vectorA[1] ** 2);
            const magnitudeB = Math.sqrt(vectorB[0] ** 2 + vectorB[1] ** 2);
            // 计算夹角的余弦值
            let cosTheta;
            if (magnitudeA * magnitudeB === 0) {
                cosTheta = 0
            } else {
                cosTheta = dotProduct / (magnitudeA * magnitudeB);
            }
            // 计算夹角的弧度值
            const angleRad = Math.acos(cosTheta);
            let h;
            if (vectorB[0] < 0 && isGetRGBA) {
                h = Number((((2 * Math.PI - angleRad) * 180) / Math.PI).toFixed(2));

            } else {
                h = Number(((angleRad * 180) / Math.PI).toFixed(2));

            }
            this.h = h
            if (isGetRGBA) this.getRGBA();
            return h;
        },
        // 圆盘边界判断
        circleJudgeBoundary(targetX, targetY) {
            const colorPanel = this.$refs.colorPanel
            let { width, height, left, top } = colorPanel.getBoundingClientRect()
            let originX = left + width / 2 - colorPanel.offsetLeft
            let originY = top + height / 2 - colorPanel.offsetTop
            let x = targetX - originX
            let y = originY - targetY
            // 判断鼠标是否已经超出的圆盘 如果超出了圆盘 则将鼠标位置限制在圆盘内
            if (Math.sqrt(x ** 2 + y ** 2) <= this.width / 2) {
                return { targetX, targetY }
            } else {
                // 计算目标坐标的夹角
                let angle = this.calculateAngle([x, 0], [x, y], false)
                // 计算标记点在圆盘边缘的坐标位置 以圆盘中心为原点
                let r = this.width / 2 // 半径
                let realX = (r * Math.cos(angle * Math.PI / 180)) * (x / Math.abs(x)) + r
                let realY = r - (r * Math.sin(angle * Math.PI / 180)) * (y / Math.abs(y))
                return { targetX: Number(realX.toFixed(2)), targetY: Number(realY.toFixed(2)) }
            }
        },
        valuePanelMD(e) {
            let that = this
            let valuePanel = that.$refs.valuePanel
            let { top, height } = valuePanel.getBoundingClientRect()
            let valuePanelSliderThumb = that.$refs.valuePanelSliderThumb
            let initY = e.pageY
            valuePanelSliderThumb.style.top = initY - top - valuePanelSliderThumb.getBoundingClientRect().height / 2 + 'px'
            that.getValue()
            let initTop = valuePanelSliderThumb.offsetTop

            document.addEventListener('mousemove', mouseMove)
            function mouseMove(e) {
                valuePanelSliderThumb.style.top = that.judgeBoundary(initTop + e.pageY - initY, 0, height) + 'px'
                that.getValue()
            }
            document.addEventListener('mouseup', mouseUp)
            function mouseUp() {
                document.removeEventListener('mousemove', mouseMove)
                document.removeEventListener('mouseup', mouseUp)
            }
        },
        // 获取明值
        getValue() {
            let valuePanel = this.$refs.valuePanel
            let { height } = valuePanel.getBoundingClientRect()
            let offsetTop = this.$refs.valuePanelSliderThumb.offsetTop
            this.v = 100 - Number((offsetTop / height * 100).toFixed(2))
            this.$refs.valueBg.style.background = `rgba(0, 0, 0, ${Number(1 - (this.v / 100).toFixed(2))})`
            this.getRGBA()
        },
        // 透明度鼠标事件
        alphaPanelMD(e) {
            let that = this
            let alphaPanel = that.$refs.alphaPanel
            let alphaPanelSliderThumb = that.$refs.alphaPanelSliderThumb
            let { width } = alphaPanel.getBoundingClientRect()
            alphaPanelSliderThumb.style.left = that.judgeBoundary(e.offsetX, 0, width) + 'px'
            that.getAlpha();
            let initLeft = alphaPanelSliderThumb.offsetLeft
            let initX = e.pageX
            document.addEventListener('mousemove', mouseMove)
            function mouseMove(e) {
                alphaPanelSliderThumb.style.left = that.judgeBoundary(e.pageX - initX + initLeft, 0, width) + 'px'
                that.getAlpha();
            }
            document.addEventListener('mouseup', mouseUp)
            function mouseUp() {
                document.removeEventListener('mousemove', mouseMove)
                document.removeEventListener('mouseup', mouseUp)
            }
        },
        getAlpha() {
            let that = this
            let alphaPanel = that.$refs.alphaPanel
            let alphaPanelSliderThumb = that.$refs.alphaPanelSliderThumb
            let { width } = alphaPanel.getBoundingClientRect()
            let alpha = (alphaPanelSliderThumb.offsetLeft / width).toFixed(2)
            that.alpha = alpha
            this.getRGBA();
        },
        // 获取RGBA色值
        getRGBA() {
            let color = convert.hsv.rgb(this.h, this.s, this.v)
            let rgba = `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${this.alpha})`
            this.colorPanelColor = `rgb(${color[0]}, ${color[1]}, ${color[2]})`
            this.$emit('change', rgba)
        },
        // 明值和透明度边界判断
        judgeBoundary(value, min, max) {
            if (value < min) {
                return min
            }
            if (value > max) {
                return max
            }
            return value
        },

    },
};
</script>
<style lang="scss" scoped>
.color-box {
    .top-part {
        display: flex;

        .color-panel {
            position: relative;
            border-radius: 50%;
            background: conic-gradient(red 0, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, red);

            &::before {
                content: '';
                position: absolute;
                inset: 0;
                border-radius: 50%;
                z-index: 10000;
                background: radial-gradient(#fff 0, transparent 80%);
            }

            .value-bg {
                position: absolute;
                inset: 0;
                z-index: 10010;
                border-radius: 50%;
            }

            .color-panel-slider-thumb {
                position: absolute;
                top: 50%;
                left: 50%;
                z-index: 10999;
                transform: translate(-50%, -50%);
                width: 6px;
                height: 6px;
                background: #fff;
                border: 1px solid #000;
                border-radius: 50%;
                pointer-events: none;
                box-sizing: border-box;
            }
        }

        .value-panel {
            position: relative;
            width: 12px;
            background: linear-gradient(to bottom, #fff 0, #000 100%);
            margin-left: 20px;

            .value-slider-thumb {
                position: absolute;
                top: 0;
                left: 50%;
                transform: translate(-50%, 0);
                width: 120%;
                height: 5px;
                border-radius: 4px;
                background-color: #fff;
                box-shadow: 0 0 2px #5a5a5a;
                pointer-events: none;
            }
        }

    }

    .alpha-panel {
        position: relative;
        height: 12px;
        background: url('../../assets/images/alpha.png');
        margin-top: 20px;

        .alpha-panel-cover {
            position: absolute;
            inset: 0;
        }

        .alpha-slider-thumb {
            position: absolute;
            left: 100%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 5px;
            height: 140%;
            border-radius: 4px;
            background-color: #fff;
            box-shadow: 0 0 2px #5a5a5a;
            cursor: pointer;
            pointer-events: none;
        }
    }
}
</style>

uitls>index.js:

import convert from 'color-convert'
// color: 颜色,type: 需要转换的类型
export function colorTypeConversion(color, type = 'hsv') {
    let reg = /(\d+(\.\d+)?)|(\.\d+)/g
    // 判断颜色类型 并转换
    if (color.startsWith('#')) {
        return {
            color: convert.hex[type](color),
            alpha: 1
        }
    } else if (color.startsWith('rgba')) {
        let arr = color.match(reg).map(item => Number(item))
        return {
            color: convert.rgb[type](arr[0], arr[1], arr[2]),
            alpha: arr[3]
        }
    } else if (color.startsWith('rgb')) {
        let arr = color.match(reg).map(item => Number(item))
        return {
            color: convert.rgb[type](arr[0], arr[1], arr[2]),
            alpha: 1
        }
    } else if (color.startsWith('hsl')) {
        let arr = color.match(reg)
        return {
            color: convert.hsl[type]([arr[0], arr[1], arr[2]]),
            alpha: 1
        }
    } else {
        return {
            color: convert.hex[type](color),
            alpha: 1
        }
    }
}

父组件示例:

<template>
    <div class="page1">
        <div class="box">
            <div style="margin-bottom: 25px;">
                <span>{{ color }}</span>
                <div class="show-color" :style="{ background: color }"></div>
            </div>
            <SquareColor ref="squareColor" :color="color" @change="changeColor1" />
            <button @click="setColor1">修改为 rgba(255, 82, 111, 0.5)</button>
        </div>
        <div class="box">
            <div style="margin-bottom: 25px;">
                <span>{{ color2 }}</span>
                <div class="show-color" :style="{ background: color2 }"></div>
            </div>
            <CircleColor ref="circleColor" :color="color2" @change="changeColor2" />
            <button @click="setColor2">修改为 #5fff45</button>
        </div>
    </div>
</template>

<script>
import SquareColor from '@/components/color/square.vue'
import CircleColor from '@/components/color/circle.vue'
export default {
    name: 'ComponentPage1',
    components: {
        SquareColor,
        CircleColor,
    },
    data() {
        return {
            color: 'hsl(107.74deg 88.62% 47.73%)',
            color2: 'rgba(255, 66, 237, 1)',
        };
    },

    mounted() { },

    methods: {
        setColor1() {
            this.color = 'rgba(255, 82, 111, 0.5)'
            this.$refs.squareColor.changeColor('rgba(255, 82, 111, 0.5)')
        },
        setColor2() {
            this.color2 = '#5fff45'
            this.$refs.circleColor.changeColor('#5fff45')
        },
        changeColor1(color) {
            this.color = color
        },
        changeColor2(color) {
            this.color2 = color
        }
    },
};
</script>

<style lang="scss" scoped>
.page1 {
    display: flex;
    flex-wrap: wrap;
    gap: 50px;
    padding: 100px;

    .box {
        padding: 20px;
        box-shadow: 0 0 8px #b8b7b7;
        border-radius: 10px;

        .show-color {
            display: inline-block;
            width: 100px;
            height: 25px;
            margin-left: 25px;
            vertical-align: middle;
            box-shadow: 0 0 8px #b8b7b7;
            border-radius: 4px;
        }
    }
}

button {
    background-color: #409eff;
    color: #fff;
    border: none;
    padding: 8px 15px;
    border-radius: 4px;
    margin: 20px 0;
    cursor: pointer;
}
</style>

完整项目代码压缩包:colorPicker

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值