在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 代码比较多我就不贴了