Vue帶漸變色拾色器

在vue項(xiàng)目中,我們一般使用element組件,但是有時(shí)候組件不能滿足我們的需求,物品們這時(shí)候就需要自己寫組件,今天給大家分享一個(gè)帶有漸變色的拾色器
首先我在github找到一款用jq寫的拾色器,改造為vue拾色器,下面為改造好的拾色器


他不愛你哈colorpicker.png

1.創(chuàng)建拾色器組件,引入拾色器

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

<script>
import XNColorPicker 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 xncolorpicker = new XNColorPicker({
          color: color,
          selector: '#' + this.domId,
          showprecolor: true, // 顯示預(yù)制顏色
          prevcolors: null, // 預(yù)制顏色,不設(shè)置則默認(rèn)
          showhistorycolor: false, // 顯示歷史
          historycolornum: 16, // 歷史條數(shù)
          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)
              }
              // 獲取元素內(nèi)鼠標(biāo)位置
              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)
              }
              // 給畫布綁定鼠標(biāo)移動(dòng)事件
              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'
                // 顯示鼠標(biāo)位置
                // 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) // 實(shí)現(xiàn)放大鏡
              }
              // 綁定鼠標(biāo)移出事件
              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, // 顯示預(yù)制顏色
        prevcolors: null, // 預(yù)制顏色,不設(shè)置則默認(rèn)
        showhistorycolor: false, // 顯示歷史
        historycolornum: 16, // 歷史條數(shù)
        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)
            }
            // 獲取元素內(nèi)鼠標(biāo)位置
            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)
            }
            // 給畫布綁定鼠標(biāo)移動(dòng)事件
            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'
              // 顯示鼠標(biāo)位置
              // 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) // 實(shí)現(xiàn)放大鏡
            }
            // 綁定鼠標(biāo)移出事件
            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, // 調(diào)色 字體百分比
        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, // 調(diào)色 字體百分比
        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, // 調(diào)色 字體百分比
            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, // 調(diào)色 字體百分比
            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>

2.放置所需js以及樣式


企業(yè)微信截圖_16188105542162.png

1.colorpicker.js 代碼比較多我就不貼了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容