📒 背景

最近项目中需要制作一个颜色选择器(如下图展示),今天分享一下这个组件功能。希望能抛砖引玉,给大家带来启发。

基于vue2开发colorPick组件_ico

🔍需求功能

  • icon或者文字颜色需要选择颜色


👣设计开发

先说一下我的开发环境版本:

基于vue2开发colorPick组件_16进制_02

node: v11.3.0

npm: 6.4.1

vue:2.5.11

如果不是以上版本也没关系,今日分享的思路,相信你可以自己造出来~

首先点击空白收缩:

 this.handler = function(e) {
    _this.showPanel = false;
 }
document.body.addEventListener('click', this.handler)

然后颜色渐变区域:

// 选择颜色的7色条
      makeColorBar() {
        var gradientBar = this.ctx.createLinearGradient(0, 0, 0, this.height);
        gradientBar.addColorStop(0, '#F00');
        gradientBar.addColorStop(1 / 6, '#F0F');
        gradientBar.addColorStop(2 / 6, '#00F');
        gradientBar.addColorStop(3 / 6, '#0FF');
        gradientBar.addColorStop(4 / 6, '#0F0');
        gradientBar.addColorStop(5 / 6, '#FF0');
        gradientBar.addColorStop(1, '#F00');

        this.ctx.fillStyle = gradientBar;
        this.ctx.fillRect(0, 0, 20, this.height);
      },

然后是拖拽选择颜色区域:

 // 颜色选择区域
      makeColorBox(color) {
        var gradientBase = this.ctx.createLinearGradient(30, 0, this.width, 0);
        gradientBase.addColorStop(1, color);
        gradientBase.addColorStop(0, 'rgba(255,255,255,1)');
        this.ctx.fillStyle = gradientBase;
        this.ctx.fillRect(30, 0, this.width, this.height);

        var my_gradient1 = this.ctx.createLinearGradient(0, 0, 0, this.height);
        my_gradient1.addColorStop(0, 'rgba(0,0,0,0)');
        my_gradient1.addColorStop(1, 'rgba(0,0,0,1)');
        this.ctx.fillStyle = my_gradient1;
        this.ctx.fillRect(30, 0, this.width, this.height);

	      // this.onCanvasClick(this.canvasPos);
      },

其中获取rgb颜色:

// 获取rgb
      getRgbaAtPoint(pos, area) {
        if (area == 'bar') {
          var imgData = this.ctx.getImageData(0, 0, 20, this.height);
        } else {
          var imgData = this.ctx.getImageData(0, 0, this.width, this.height);
        }
        var data = imgData.data;
        var dataIndex = (pos.y * imgData.width + pos.x) * 4;
        //开始消除误差
        if (pos.x >= 30 && pos.y > this.height - 3) {
          return [0, 0, 0, this.alpha];
        }
        if (pos.x >= 30 && pos.y <= 1) {
          data[dataIndex] = 255;
        }
        if (pos.x >= 30 && pos.x <= 31) {
          return [
            data[dataIndex],
            data[dataIndex],
            data[dataIndex],
            this.alpha
          ]
        }
        if (pos.x >= this.width - 1) {
          return [
            data[dataIndex],
            0,
            0,
            this.alpha
          ]
        }
        // 消除误差结束
        return [
          data[dataIndex],
          data[dataIndex + 1],
          data[dataIndex + 2],
          this.alpha
        ];
      },

rgba转16进制

// rgb/rgba色值转16进制
      rgb2hex(rgb) {
        var reg = /^(rgb|RGB)/;
        var a;
        if (reg.test(rgb)) {
          var colorArr = rgb.replace(/(?:rgba|rgb|RGBA|RGB|\(|\))*/g, "").split(',');
          var alpha = (colorArr && colorArr[3] || "").trim()
          var hex = "#" + ((1 << 24) + (parseInt(colorArr[0]) << 16) + (parseInt(colorArr[1]) << 8) + parseInt(
            colorArr[2])).toString(16).slice(1);
          if (alpha != '' && alpha != '1') {
            a = ((alpha * 255) | 1 << 8).toString(16).slice(1);
            hex = hex + a;
          }
          return hex.toUpperCase();
        } else {
          return rgb
        }
      },

16进制转rgb

// 16进制色值转rgb
      hex2rgb(hex) {
        var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
        var color = hex.toLowerCase();
        if (reg.test(color)) {
          if (color.length === 4) {
            var colorNew = "#";
            for (var i = 1; i < color.length; i += 1) {
              colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1));
            }
            color = colorNew;
          }
          var colorChange = [];
          for (var i = 1; i < color.length; i += 2) {
            colorChange.push(parseInt("0x" + color.slice(i, i + 2)));
          }
          return "rgb(" + colorChange.join(",") + ")";
        } else {
          return color;
        }
      }

更多逻辑代码欢迎体验组件--mycomponentsvue

npm install mycomponentsvue@0.0.15

import mycomponents from 'mycomponentsvue'

Vue.use(mycomponents)

<color-pick v-model="textColor" :predefine="predefineColor" icon="showcolor"></color-pick>

本组件只用于学习交流哈!所以名字起的比较随意!~


⛳参考学习

vue-color组件(sketch-picker) 和 element-ui的colorPicker组件(colorPicker

基于vue2开发colorPick组件_颜色选择器_03


基于vue2开发colorPick组件_ico_04


🚀写在最后

如果本文中有bug、逻辑错误,或者您有更好的优化方案欢迎评论联系我哦!~关注我持续分享日常工作中的组件设计和学习分享,一起进步加油!