forked from integrated_whb/integrated_whb_vue
签字背景色改成白色
parent
480013c3d2
commit
4976baad59
|
@ -0,0 +1,289 @@
|
|||
<template>
|
||||
<canvas ref="canvas" @mousedown="mouseDown" @mousemove="mouseMove" @mouseup="mouseUp"
|
||||
@touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd"></canvas>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
width: {
|
||||
type: Number,
|
||||
default: 800
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 300
|
||||
},
|
||||
lineWidth: {
|
||||
type: Number,
|
||||
default: 4
|
||||
},
|
||||
lineColor: {
|
||||
type: String,
|
||||
default: '#000000'
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: '#FFFFFF'
|
||||
},
|
||||
isCrop: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isClearBgColor: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
format: {
|
||||
type: String,
|
||||
default: 'image/png'
|
||||
},
|
||||
quality: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
hasDrew: false,
|
||||
resultImg: '',
|
||||
points: [],
|
||||
canvasTxt: null,
|
||||
startX: 0,
|
||||
startY: 0,
|
||||
isDrawing: false,
|
||||
sratio: 1
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
ratio () {
|
||||
return this.height / this.width
|
||||
},
|
||||
stageInfo () {
|
||||
return this.$refs.canvas.getBoundingClientRect()
|
||||
},
|
||||
myBg () {
|
||||
return this.bgColor ? this.bgColor : 'rgba(255, 255, 255, 0)'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'myBg': function (newVal) {
|
||||
this.$refs.canvas.style.background = newVal
|
||||
}
|
||||
},
|
||||
beforeMount () {
|
||||
window.addEventListener('resize', this.$_resizeHandler)
|
||||
},
|
||||
beforeDestroy () {
|
||||
window.removeEventListener('resize', this.$_resizeHandler)
|
||||
},
|
||||
mounted () {
|
||||
const canvas = this.$refs.canvas
|
||||
canvas.height = this.height
|
||||
canvas.width = this.width
|
||||
canvas.style.background = this.myBg
|
||||
this.$_resizeHandler()
|
||||
// 在画板以外松开鼠标后冻结画笔
|
||||
document.onmouseup = () => {
|
||||
this.isDrawing = false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
$_resizeHandler () {
|
||||
const canvas = this.$refs.canvas
|
||||
canvas.style.width = this.width + "px"
|
||||
const realw = parseFloat(window.getComputedStyle(canvas).width)
|
||||
canvas.style.height = this.ratio * realw + "px";
|
||||
this.canvasTxt = canvas.getContext('2d')
|
||||
this.canvasTxt.scale(1 * this.sratio, 1 * this.sratio)
|
||||
this.sratio = realw / this.width
|
||||
this.canvasTxt.scale(1 / this.sratio, 1 / this.sratio)
|
||||
},
|
||||
// pc
|
||||
mouseDown (e) {
|
||||
e = e || event
|
||||
e.preventDefault()
|
||||
this.isDrawing = true
|
||||
this.hasDrew = true
|
||||
let obj = {
|
||||
x: e.offsetX,
|
||||
y: e.offsetY
|
||||
}
|
||||
this.drawStart(obj)
|
||||
},
|
||||
mouseMove (e) {
|
||||
e = e || event
|
||||
e.preventDefault()
|
||||
if (this.isDrawing) {
|
||||
let obj = {
|
||||
x: e.offsetX,
|
||||
y: e.offsetY
|
||||
}
|
||||
this.drawMove(obj)
|
||||
}
|
||||
},
|
||||
mouseUp (e) {
|
||||
e = e || event
|
||||
e.preventDefault()
|
||||
let obj = {
|
||||
x: e.offsetX,
|
||||
y: e.offsetY
|
||||
}
|
||||
this.drawEnd(obj)
|
||||
this.isDrawing = false
|
||||
},
|
||||
// mobile
|
||||
touchStart (e) {
|
||||
e = e || event
|
||||
e.preventDefault()
|
||||
this.hasDrew = true
|
||||
if (e.touches.length === 1) {
|
||||
let obj = {
|
||||
x: e.targetTouches[0].clientX - this.$refs.canvas.getBoundingClientRect().left,
|
||||
y: e.targetTouches[0].clientY - this.$refs.canvas.getBoundingClientRect().top
|
||||
}
|
||||
this.drawStart(obj)
|
||||
}
|
||||
},
|
||||
touchMove (e) {
|
||||
e = e || event
|
||||
e.preventDefault()
|
||||
if (e.touches.length === 1) {
|
||||
let obj = {
|
||||
x: e.targetTouches[0].clientX - this.$refs.canvas.getBoundingClientRect().left,
|
||||
y: e.targetTouches[0].clientY - this.$refs.canvas.getBoundingClientRect().top
|
||||
}
|
||||
this.drawMove(obj)
|
||||
}
|
||||
},
|
||||
touchEnd (e) {
|
||||
e = e || event
|
||||
e.preventDefault()
|
||||
if (e.touches.length === 1) {
|
||||
let obj = {
|
||||
x: e.targetTouches[0].clientX - this.$refs.canvas.getBoundingClientRect().left,
|
||||
y: e.targetTouches[0].clientY - this.$refs.canvas.getBoundingClientRect().top
|
||||
}
|
||||
this.drawEnd(obj)
|
||||
}
|
||||
},
|
||||
// 绘制
|
||||
drawStart (obj) {
|
||||
this.startX = obj.x
|
||||
this.startY = obj.y
|
||||
this.canvasTxt.beginPath()
|
||||
this.canvasTxt.moveTo(this.startX, this.startY)
|
||||
this.canvasTxt.lineTo(obj.x, obj.y)
|
||||
this.canvasTxt.lineCap = 'round'
|
||||
this.canvasTxt.lineJoin = 'round'
|
||||
this.canvasTxt.lineWidth = this.lineWidth * this.sratio
|
||||
this.canvasTxt.stroke()
|
||||
this.canvasTxt.closePath()
|
||||
this.points.push(obj)
|
||||
},
|
||||
drawMove (obj) {
|
||||
this.canvasTxt.beginPath()
|
||||
this.canvasTxt.moveTo(this.startX, this.startY)
|
||||
this.canvasTxt.lineTo(obj.x, obj.y)
|
||||
this.canvasTxt.strokeStyle = this.lineColor
|
||||
this.canvasTxt.lineWidth = this.lineWidth * this.sratio
|
||||
this.canvasTxt.lineCap = 'round'
|
||||
this.canvasTxt.lineJoin = 'round'
|
||||
this.canvasTxt.stroke()
|
||||
this.canvasTxt.closePath()
|
||||
this.startY = obj.y
|
||||
this.startX = obj.x
|
||||
this.points.push(obj)
|
||||
},
|
||||
drawEnd (obj) {
|
||||
this.canvasTxt.beginPath()
|
||||
this.canvasTxt.moveTo(this.startX, this.startY)
|
||||
this.canvasTxt.lineTo(obj.x, obj.y)
|
||||
this.canvasTxt.lineCap = 'round'
|
||||
this.canvasTxt.lineJoin = 'round'
|
||||
this.canvasTxt.stroke()
|
||||
this.canvasTxt.closePath()
|
||||
this.points.push(obj)
|
||||
this.points.push({x: -1, y: -1})
|
||||
},
|
||||
// 操作
|
||||
generate (options) {
|
||||
let imgFormat = options && options.format ? options.format: this.format
|
||||
let imgQuality = options && options.quality ? options.quality: this.quality
|
||||
const pm = new Promise((resolve, reject) => {
|
||||
if (!this.hasDrew) {
|
||||
reject(`Warning: Not Signned!`)
|
||||
return
|
||||
}
|
||||
var resImgData = this.canvasTxt.getImageData(0, 0, this.$refs.canvas.width, this.$refs.canvas.height)
|
||||
this.canvasTxt.globalCompositeOperation = "destination-over"
|
||||
this.canvasTxt.fillStyle = this.myBg
|
||||
this.canvasTxt.fillRect(0,0,this.$refs.canvas.width ,this.$refs.canvas.height)
|
||||
this.resultImg = this.$refs.canvas.toDataURL(imgFormat, imgQuality)
|
||||
var resultImg = this.resultImg
|
||||
this.canvasTxt.clearRect(0, 0, this.$refs.canvas.width ,this.$refs.canvas.height)
|
||||
this.canvasTxt.putImageData(resImgData, 0, 0)
|
||||
this.canvasTxt.globalCompositeOperation = "source-over"
|
||||
if (this.isCrop) {
|
||||
const crop_area = this.getCropArea(resImgData.data)
|
||||
var crop_canvas = document.createElement('canvas')
|
||||
const crop_ctx = crop_canvas.getContext('2d')
|
||||
crop_canvas.width = crop_area[2] - crop_area[0]
|
||||
crop_canvas.height = crop_area[3] - crop_area[1]
|
||||
const crop_imgData = this.canvasTxt.getImageData(...crop_area)
|
||||
crop_ctx.globalCompositeOperation = "destination-over"
|
||||
crop_ctx.putImageData(crop_imgData, 0, 0)
|
||||
crop_ctx.fillStyle = this.myBg
|
||||
crop_ctx.fillRect(0, 0, crop_canvas.width , crop_canvas.height)
|
||||
resultImg = crop_canvas.toDataURL(imgFormat, imgQuality)
|
||||
crop_canvas = null
|
||||
}
|
||||
resolve(resultImg)
|
||||
})
|
||||
return pm
|
||||
},
|
||||
reset () {
|
||||
this.canvasTxt.clearRect(
|
||||
0,
|
||||
0,
|
||||
this.$refs.canvas.width,
|
||||
this.$refs.canvas.height
|
||||
)
|
||||
if (this.isClearBgColor) {
|
||||
this.$emit('update:bgColor', '')
|
||||
this.$refs.canvas.style.background = 'rgba(255, 255, 255, 0)'
|
||||
}
|
||||
this.points = []
|
||||
this.hasDrew = false
|
||||
this.resultImg = ''
|
||||
},
|
||||
getCropArea (imgData) {
|
||||
var topX = this.$refs.canvas.width; var btmX = 0; var topY = this.$refs.canvas.height; var btnY = 0
|
||||
for (var i = 0; i < this.$refs.canvas.width; i++) {
|
||||
for (var j = 0; j < this.$refs.canvas.height; j++) {
|
||||
var pos = (i + this.$refs.canvas.width * j) * 4
|
||||
if (imgData[pos] > 0 || imgData[pos + 1] > 0 || imgData[pos + 2] || imgData[pos + 3] > 0) {
|
||||
btnY = Math.max(j, btnY)
|
||||
btmX = Math.max(i, btmX)
|
||||
topY = Math.min(j, topY)
|
||||
topX = Math.min(i, topX)
|
||||
}
|
||||
}
|
||||
}
|
||||
topX++
|
||||
btmX++
|
||||
topY++
|
||||
btnY++
|
||||
const data = [topX, topY, btmX, btnY]
|
||||
return data
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
canvas {
|
||||
max-width: 100%;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue