Vue帶漸變色拾色器

在vue項目中靠粪,我們一般使用element組件聊疲,但是有時候組件不能滿足我們的需求,物品們這時候就需要自己寫組件搭儒,今天給大家分享一個帶有漸變色的拾色器
首先我在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, // 顯示預制顏色
          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以及樣式


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

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市德撬,隨后出現的幾起案子铲咨,更是在濱河造成了極大的恐慌,老刑警劉巖蜓洪,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纤勒,死亡現場離奇詭異,居然都是意外死亡隆檀,警方通過查閱死者的電腦和手機摇天,發(fā)現死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恐仑,“玉大人泉坐,你說我怎么就攤上這事∩哑停” “怎么了腕让?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長歧斟。 經常有香客問我纯丸,道長偏形,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任觉鼻,我火速辦了婚禮俊扭,結果婚禮上,老公的妹妹穿的比我還像新娘滑凉。我一直安慰自己统扳,他們只是感情好,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布畅姊。 她就那樣靜靜地躺著,像睡著了一般吹由。 火紅的嫁衣襯著肌膚如雪若未。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天倾鲫,我揣著相機與錄音粗合,去河邊找鬼。 笑死乌昔,一個胖子當著我的面吹牛隙疚,可吹牛的內容都是我干的。 我是一名探鬼主播磕道,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼供屉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了溺蕉?” 一聲冷哼從身側響起伶丐,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎疯特,沒想到半個月后哗魂,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡漓雅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年录别,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邻吞。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡组题,死狀恐怖,靈堂內的尸體忽然破棺而出吃衅,到底是詐尸還是另有隱情往踢,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布徘层,位于F島的核電站峻呕,受9級特大地震影響利职,放射性物質發(fā)生泄漏。R本人自食惡果不足惜瘦癌,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一猪贪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧讯私,春花似錦热押、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至娘锁,卻和暖如春牙寞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背莫秆。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工间雀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人镊屎。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓惹挟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親缝驳。 傳聞我的和親對象是個殘疾皇子连锯,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內容