Vue带渐变色拾色器

在vue项目中,我们一般使用element组件,但是有时候组件不能满足我们的需求,物品们这时候就需要自己写组件,今天给大家分享一个带有渐变色的拾色器
首先我在github找到一款用jq写的拾色器,改造为vue拾色器,下面为改造好的拾色器


他不爱你哈colorpicker.png

1.创建拾色器组件,引入拾色器

<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, // 显示预制颜色
          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>

2.放置所需js以及样式


企业微信截图_16188105542162.png

1.colorpicker.js 代码比较多我就不贴了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容