In vue project, we usually use element component, but sometimes the component can’t meet our requirements, at this time of the items you need to write their own components, today to share with a gradient color First of all, I found in making a written in jq color, transformed the vue color machine, the following to transform a good color

1. Create a color picker component and introduce the color picker

<template>
  <div class="xxxxx">
    <div :id="domId" class="mypicker" />
  </div>
</template>

<script>
import ColorPicker from './colorpicker'
import { mapState } from 'vuex'
// import {selectGradient} from ''
export default {
  props: {
    color: {
      default: '#ffffff'
    }
  },
  data() {
    return {
      domId: '',
      oldValue: '',
      mouse: { x: -1, y: -1 },
      glass: false,
      hexColor: ''
    }
  },
  watch: {
    fActO(val, oldval) {
      this.domId = 'dom-' + ((new Date()).getTime() + Math.random()).toString().replace('.', '')
      if (this.color.type == 'linear') {
        var zhuanhuan = this.fActO.fill.colorStops.map((e) => {
          return `${e.color} ${e.per}%`
        })
        var color = `linear-gradient(0.0deg,${zhuanhuan})`
      } else {
        var color = this.color == '' ? '#ffffff' : this.color
      }
      console.log(this.color)
      console.log(color)
      this.$nextTick(() => {
        var self = this
        var colorpicker = new ColorPicker({
          color: color,
          selector: '#' + this.domId,
          showprecolor: true, // 显示预制颜色
          prevcolors: null, // 预制颜色,不设置则默认
          showhistorycolor: false, // 显示历史
          historycolornum: 16, // 历史条数
          format: 'hex', // rgba hex hsla,初始颜色类型
          showPalette: true, // 显示色盘
          show: false, // 初始化显示
          lang: 'cn', // cn 、en
          colorTypeOption: 'single,linear-gradient,radial-gradient',
          canMove: false, // 选择器位置是否可以拖拽
          alwaysShow: false,
          autoConfirm: true,
          onError: function(e) {

          },
          onCancel: function(color) {
            console.log('cancel', color)
          },
          onChange: function(color) {
            self.$emit('active-change', color.color.hex)
            // console.log('change', color)
            if (color.colorType == 'single') {
              self.$emit('active-change', color.color.hex)
            } else if (color.colorType == 'linear-gradient') {
              // self.$emit('active-change', color.color.str)
              self.linear(color)
            } else {
              self.radial(color)
            }
          },
          onConfirm: function(color) {
            console.log('confirm', color)
            self.$emit('active-change', color.color.hex)
            // console.log('change', color)
            if (color.colorType == 'single') {
              self.$emit('active-change', color.color.hex)
            } else if (color.colorType == 'linear-gradient') {
              // self.$emit('active-change', color.color.str)
              self.linear(color)
            } else {
              // self.$emit('active-change', color.color.str)
              self.radial(color)
            }
          },
          openSucker: function(color) {
            self.glass = true
            if (color == 1) {
              var imgcan = document.querySelector('#imgcan')
              imgcan.style.display = 'block'
              var glasscan = document.getElementById('glasscan')
              var glasscanimg = document.getElementById('glasscanimg')
              var glasscanp = document.getElementById('glasscanp')
              var imgContext = document.querySelector('#canvas').getContext('2d')
              var glassContext = glasscan.getContext('2d')
              var img = new Image()
              self.mouse = captureMouse(imgcan)
              img.src = self.fObj.toDataURL({ multiplier: 1, withoutTransform: true })
              img.onload = function() {
                imgContext.drawImage(img, self.fObj.width, self.fObj.height)
              }
              // 获取元素内鼠标位置
              function captureMouse(element) {
                element.addEventListener('mousemove', function(event) {
                  var x = event.pageX
                  var y = event.pageY
                  if (event.type == 'touchstart') {
                    x = event.touches[0].clientX
                    y = event.touches[0].clientY
                  }
                  var canvas = event.target
                  self.mouse = self.getPointOnCanvas(canvas, x, y)
                }, false)
              }
              // 给画布绑定鼠标移动事件
              imgcan.onmousemove = function() {
                glassContext.clearRect(0, 0, glasscan.width, glasscan.height)
                glasscan.style.left = self.mouse.x + 'px'
                glasscan.style.top = self.mouse.y + 'px'
                glasscanimg.style.left = self.mouse.x + 'px'
                glasscanimg.style.top = self.mouse.y + 'px'
                glasscanp.style.left = self.mouse.x + 90 + 'px'
                glasscanp.style.top = self.mouse.y + 180 + 'px'
                // 显示鼠标位置
                // console.log(self.mouse.x, self.mouse.y)
                // console.log(imgContext.getImageData(self.mouse.x, self.mouse.y, 1, 1).data)
                var imageData = imgContext.getImageData(self.mouse.x, self.mouse.y, 1, 1)
                var pixel = imageData.data
                var r = pixel[0]
                var g = pixel[1]
                var b = pixel[2]
                var a = pixel[3] / 255
                a = Math.round(a * 100) / 100
                var rHex = r.toString(16)
                r < 16 && (rHex = '0' + rHex)
                var gHex = g.toString(16)
                g < 16 && (gHex = '0' + gHex)
                var bHex = b.toString(16)
                b < 16 && (bHex = '0' + bHex)
                var rgbaColor = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'
                var rgbColor = 'rgb(' + r + ',' + g + ',' + b + ')'
                var hexColor = '#' + rHex + gHex + bHex
                glasscanp.innerText = hexColor
                self.hexColor = hexColor
                var drawWidth = 50,
                  drawHeight = 50
                glassContext.drawImage(img, self.mouse.x - drawWidth / 4 + 4, self.mouse.y - drawHeight / 4 + 6, drawWidth, drawHeight, 0, 0, drawWidth * 16, drawHeight * 16) // 实现放大镜
              }
              // 绑定鼠标移出事件
              imgcan.onmouseout = function() {
                glasscan.style.display = 'none'
                glasscanimg.style.display = 'none'
                glasscanp.style.display = 'none'
              }
              imgcan.onmouseover = function() {
                if (self.glass == true) {
                  glasscan.style.display = 'block'
                  glasscanimg.style.display = 'block'
                  glasscanp.style.display = 'block'
                  imgcan.style.display = 'block'
                }
              }
              imgcan.onclick = function() {
                self.$emit('active-change', self.hexColor)
                var fcolorpicker = document.querySelector('.fcolorpicker-curbox')
                fcolorpicker.style.backgroundColor = self.hexColor
                this.option.color = self.hexColor
                console.log(self.hexColor)
                self.glass = false
                imgcan.style.display = 'none'
                glasscan.style.display = 'none'
                glasscanimg.style.display = 'none'
                glasscanp.style.display = 'none'
              }
            } else {
              var imgcan = document.querySelector('#imgcan')
              imgcan.style.display = 'none'
            }
          }
        })
      })
    }
  },
  computed: {
    ...mapState({
      fObj: state => state.fabricStore.fabricObject,
      fJson: state => state.fabricStore.fabricJson,
      fAct: state => state.fabricStore.fabricAcitveObjects,
      fActO: state => state.fabricStore.fabricAcitveObject,
      loginInfo: state => state.app.loginInfo
    })
  },
  // beforeDestroy() {
  //   if (!this.sameColor(this.oldValue, this.color)) {
  //     this.$emit('closePicker', this.oldValue)
  //   }
  // },
  mounted() {
    this.domId = 'dom-' + ((new Date()).getTime() + Math.random()).toString().replace('.', '')
    if (this.color.type == 'linear') {
      var zhuanhuan = this.fActO.fill.colorStops.map((e) => {
        return `${e.color} ${e.per}%`
      })
      var color = `linear-gradient(0.0deg,${zhuanhuan})`
    } else {
      var color = this.color == '' ? '#ffffff' : this.color
    }
    console.log('fill', this.fActO.fill)
    console.log(color)
    this.$nextTick(() => {
      var self = this
      var xncolorpicker = new XNColorPicker({
        color: color,
        selector: '#' + this.domId,
        showprecolor: true, // 显示预制颜色
        prevcolors: null, // 预制颜色,不设置则默认
        showhistorycolor: false, // 显示历史
        historycolornum: 16, // 历史条数
        format: 'hex', // rgba hex hsla,初始颜色类型
        showPalette: true, // 显示色盘
        show: false, // 初始化显示
        lang: 'cn', // cn 、en
        colorTypeOption: 'single,linear-gradient,radial-gradient',
        canMove: false, // 选择器位置是否可以拖拽
        alwaysShow: false,
        autoConfirm: true,
        onError: function(e) {

        },
        onCancel: function(color) {
          console.log('cancel', color)
        },
        onChange: function(color) {
          self.$emit('active-change', color.color.hex)
          // console.log('change', color)
          if (color.colorType == 'single') {
            self.$emit('active-change', color.color.hex)
          } else if (color.colorType == 'linear-gradient') {
            // self.$emit('active-change', color.color.str)
            self.linear(color)
          } else {
            // self.$emit('active-change', color.color.str)
            self.radial(color)
          }
        },
        onConfirm: function(color) {
          console.log(color)
          self.$emit('active-change', color.color.hex)
          // console.log('change', color)
          if (color.colorType == 'single') {
            self.$emit('active-change', color.color.hex)
          } else if (color.colorType == 'linear-gradient') {
            // self.$emit('active-change', color.color.str)
            self.linear(color)
          } else {
            // self.$emit('active-change', color.color.str)
            self.radial(color)
          }
        },
        openSucker: function(color) {
          self.glass = true
          if (color == 1) {
            var imgcan = document.querySelector('#imgcan')
            imgcan.style.display = 'block'
            var glasscan = document.getElementById('glasscan')
            var glasscanimg = document.getElementById('glasscanimg')
            var glasscanp = document.getElementById('glasscanp')
            var imgContext = document.querySelector('#canvas').getContext('2d')
            var glassContext = glasscan.getContext('2d')
            var img = new Image()
            self.mouse = captureMouse(imgcan)
            img.src = self.fObj.toDataURL({ multiplier: 1, withoutTransform: true })
            img.onload = function() {
              imgContext.drawImage(img, self.fObj.width, self.fObj.height)
            }
            // 获取元素内鼠标位置
            function captureMouse(element) {
              element.addEventListener('mousemove', function(event) {
                var x = event.pageX
                var y = event.pageY
                if (event.type == 'touchstart') {
                  x = event.touches[0].clientX
                  y = event.touches[0].clientY
                }
                var canvas = event.target
                self.mouse = self.getPointOnCanvas(canvas, x, y)
              }, false)
            }
            // 给画布绑定鼠标移动事件
            imgcan.onmousemove = function() {
              glassContext.clearRect(0, 0, glasscan.width, glasscan.height)
              glasscan.style.left = self.mouse.x + 'px'
              glasscan.style.top = self.mouse.y + 'px'
              glasscanimg.style.left = self.mouse.x + 'px'
              glasscanimg.style.top = self.mouse.y + 'px'
              glasscanp.style.left = self.mouse.x + 90 + 'px'
              glasscanp.style.top = self.mouse.y + 180 + 'px'
              // 显示鼠标位置
              // console.log(self.mouse.x, self.mouse.y)
              // console.log(imgContext.getImageData(self.mouse.x, self.mouse.y, 1, 1).data)
              var imageData = imgContext.getImageData(self.mouse.x, self.mouse.y, 1, 1)
              var pixel = imageData.data
              var r = pixel[0]
              var g = pixel[1]
              var b = pixel[2]
              var a = pixel[3] / 255
              a = Math.round(a * 100) / 100
              var rHex = r.toString(16)
              r < 16 && (rHex = '0' + rHex)
              var gHex = g.toString(16)
              g < 16 && (gHex = '0' + gHex)
              var bHex = b.toString(16)
              b < 16 && (bHex = '0' + bHex)
              var rgbaColor = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'
              var rgbColor = 'rgb(' + r + ',' + g + ',' + b + ')'
              var hexColor = '#' + rHex + gHex + bHex
              glasscanp.innerText = hexColor
              self.hexColor = hexColor
              var drawWidth = 50,
                drawHeight = 50
              glassContext.drawImage(img, self.mouse.x - drawWidth / 4 + 4, self.mouse.y - drawHeight / 4 + 6, drawWidth, drawHeight, 0, 0, drawWidth * 16, drawHeight * 16) // 实现放大镜
            }
            // 绑定鼠标移出事件
            imgcan.onmouseout = function() {
              glasscan.style.display = 'none'
              glasscanimg.style.display = 'none'
              glasscanp.style.display = 'none'
            }
            imgcan.onmouseover = function() {
              if (self.glass == true) {
                glasscan.style.display = 'block'
                glasscanimg.style.display = 'block'
                glasscanp.style.display = 'block'
                imgcan.style.display = 'block'
              }
            }
            imgcan.onclick = function() {
              self.$emit('active-change', self.hexColor)
              console.log(self.hexColor)
              var fcolorpicker = document.querySelector('.fcolorpicker-curbox')
              fcolorpicker.style.backgroundColor = self.hexColor
              self.glass = false
              imgcan.style.display = 'none'
              glasscan.style.display = 'none'
              glasscanimg.style.display = 'none'
              glasscanp.style.display = 'none'
            }
            var mainbody = document.querySelector('.mainbody')
            mainbody.onclick = function() {
              self.glass = false
              imgcan.style.display = 'none'
              glasscan.style.display = 'none'
              glasscanimg.style.display = 'none'
              glasscanp.style.display = 'none'
            }
          } else {
            var imgcan = document.querySelector('#imgcan')
            imgcan.style.display = 'none'
          }
        }
      })
    })

  },
  methods: {
    activeChangeColor(val) {
      this.$emit('active-change', val)
    },
    sameColor(c1, c2) {
      var rgb1 = c1.colorRgb()
      if (rgb1.indexOf('rgba') < 0) {
        rgb1 = rgb1.replace('rgb', 'rgba')
        rgb1 = rgb1.substr(0, rgb1.length - 1) + ',1)'
      }
      rgb1 = rgb1.replace('rgba(', '').replace(')', '').split(',')
      var rgb2 = c2.colorRgb()
      if (rgb2.indexOf('rgba') < 0) {
        rgb2 = rgb2.replace('rgb', 'rgba')
        rgb2 = rgb2.substr(0, rgb2.length - 1) + ',1)'
      }
      rgb2 = rgb2.replace('rgba(', '').replace(')', '').split(',')
      return (rgb1[0].trim() == rgb2[0].trim() && rgb1[1].trim() == rgb2[1].trim() && rgb1[2].trim() == rgb2[2].trim() && rgb1[3].trim() == rgb2[3].trim())
    },
    getPointOnCanvas(canvas, x, y) {
      var bbox = canvas.getBoundingClientRect()
      return {
        x: (x - bbox.left) * (canvas.width / bbox.width) - document.body.scrollLeft,
        y: (y - bbox.top) * (canvas.height / bbox.height) - document.body.scrollTop
      }
    },
    linear(item) {
      console.log(item)
      item.color.arry.colors.forEach(val => {
        val.offset = val.per / 100
      })
      const o = this.fActO
      const gradientLinear = new fabric.Gradient({
        type: 'linear',
        coords: {
          x1: 0,
          y1: 0,
          x2: o.width,
          y2: o.height
        },
        gradientUnits: 10, // 调色 字体百分比
        colorStops: item.color.arry.colors,
        value: item
      })
      o.set('fill', gradientLinear)
      this.fObj.renderAll()
    },
    radial(item) {
      item.color.arry.colors.forEach(val => {
        val.offset = val.per / 100
      })
      const o = this.fActO
      const gradientRadial = new fabric.Gradient({
        type: 'radial',
        coords: {
          x1: o.width / 2,
          y1: o.height / 2,
          x2: o.width / 2,
          y2: o.height / 2,
          r1: o.height / 2,
          r2: o.width / 2
        },
        gradientUnits: 10, // 调色 字体百分比
        colorStops: item.color.arry.colors
      })
      o.set('fill', gradientRadial)
    },
    selectGradient(item) {
      const o = this.fActO
      if (o) {
        if (item.colorE && item.color) {
          item.gradientLinear = new fabric.Gradient({
            type: 'linear',
            coords: {
              x1: 0,
              y1: 0,
              x2: o.width,
              y2: o.height
            },
            gradientUnits: 10, // 调色 字体百分比
            colorStops: [{
              offset: 0,
              color: item.color
            }, {
              offset: 1,
              color: item.colorE
            }]
          })
          item.gradientRadial = new fabric.Gradient({
            type: 'radial',
            coords: {
              x1: o.width / 2,
              y1: o.height / 2,
              x2: o.width / 2,
              y2: o.height / 2,
              r1: o.height / 2,
              r2: o.width / 2
            },
            gradientUnits: 10, // 调色 字体百分比
            colorStops: [{
              offset: 0,
              color: item.color
            }, {
              offset: 1,
              color: item.colorE
            }]
          })
          if (this.value === 1) {
            o.set('fill', item.gradientLinear)
          } else if (this.value === 2) {
            o.set('fill', item.gradientRadial)
          } else if (this.value === 0) {
            o.set('fill', '#000')
          }
        }
      }
    }
  }
}
</script>

<style lang="scss" scoped>
</style>

Copy the code

1. Colorpicker. js code is more than I will not paste