parent
b4a9568fad
commit
beb20c6497
@ -0,0 +1,30 @@ |
|||||||
|
import Vue from 'vue' |
||||||
|
import Main from './main.vue' |
||||||
|
|
||||||
|
const Constructor = Vue.extend(Main) |
||||||
|
|
||||||
|
let instance |
||||||
|
|
||||||
|
const signature = function ({image, lineWidth = 6, lineColor = '#000000', onConfirm}) { |
||||||
|
if (instance) instance.close() |
||||||
|
else { |
||||||
|
instance = new Constructor().$mount() |
||||||
|
document.body.appendChild(instance.$el) |
||||||
|
} |
||||||
|
instance.image = image |
||||||
|
instance.lineWidth = lineWidth |
||||||
|
instance.lineColor = lineColor |
||||||
|
instance.onConfirm = onConfirm |
||||||
|
instance.init() |
||||||
|
instance.visible = true |
||||||
|
return instance |
||||||
|
} |
||||||
|
|
||||||
|
signature.close = function () { |
||||||
|
if (instance) { |
||||||
|
instance.close() |
||||||
|
instance = null |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default signature |
||||||
@ -0,0 +1,155 @@ |
|||||||
|
<template> |
||||||
|
<div v-show="visible" class="signature-board"> |
||||||
|
<canvas |
||||||
|
ref="canvas" |
||||||
|
@mousedown.prevent="drawStart" |
||||||
|
@mousemove.prevent="drawMove" |
||||||
|
@mouseup.prevent="drawEnd" |
||||||
|
@touchstart.prevent="drawStart" |
||||||
|
@touchmove.prevent="drawMove" |
||||||
|
@touchend.prevent="drawEnd" |
||||||
|
/> |
||||||
|
<div class="signature-board__footer"> |
||||||
|
<el-button plain size="small" @click="clear">清 空</el-button> |
||||||
|
<el-button plain size="small" @click="close">关 闭</el-button> |
||||||
|
<el-button size="small" type="primary" @click="confirm">确 定</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
/* |
||||||
|
* 突然发现没办法做到竖屏横屏都支持,坑爹 |
||||||
|
* */ |
||||||
|
|
||||||
|
function getEventPoint(e) { |
||||||
|
let x, y |
||||||
|
if (['mousedown', 'mousemove'].includes(e.type)) { |
||||||
|
x = e.clientX - e.target.offsetLeft |
||||||
|
y = e.clientY - e.target.offsetTop |
||||||
|
} |
||||||
|
else { |
||||||
|
x = e.changedTouches[0].clientX - e.target.offsetLeft |
||||||
|
y = e.changedTouches[0].clientY - e.target.offsetTop |
||||||
|
} |
||||||
|
return {x, y} |
||||||
|
} |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'SignatureBoard', |
||||||
|
props: { |
||||||
|
image: String, |
||||||
|
lineWidth: Number, |
||||||
|
lineColor: String, |
||||||
|
onConfirm: Function |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
visible: false, |
||||||
|
drew: false, |
||||||
|
drawing: false, |
||||||
|
startX: 0, |
||||||
|
startY: 0 |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
drawStart(e) { |
||||||
|
const {x, y} = getEventPoint(e) |
||||||
|
this.drew = true |
||||||
|
this.drawing = true |
||||||
|
this.startX = x |
||||||
|
this.startY = y |
||||||
|
this.ctx.strokeStyle = this.lineColor |
||||||
|
this.ctx.lineWidth = this.lineWidth |
||||||
|
}, |
||||||
|
|
||||||
|
drawMove(e) { |
||||||
|
if (!this.drawing) return |
||||||
|
const {x, y} = getEventPoint(e) |
||||||
|
this.ctx.beginPath() |
||||||
|
this.ctx.moveTo(this.startX, this.startY) |
||||||
|
this.ctx.lineTo(x, y) |
||||||
|
this.ctx.stroke() |
||||||
|
this.ctx.closePath() |
||||||
|
this.startY = y |
||||||
|
this.startX = x |
||||||
|
}, |
||||||
|
|
||||||
|
drawEnd() { |
||||||
|
this.drawing = false |
||||||
|
}, |
||||||
|
|
||||||
|
getBase64() { |
||||||
|
if (!this.drew) return null |
||||||
|
return this.$refs.canvas.toDataURL() |
||||||
|
}, |
||||||
|
|
||||||
|
resize() { |
||||||
|
const canvas = this.$refs.canvas |
||||||
|
|
||||||
|
canvas.height = window.innerHeight |
||||||
|
canvas.width = window.innerWidth |
||||||
|
}, |
||||||
|
|
||||||
|
init() { |
||||||
|
this.resize() |
||||||
|
|
||||||
|
this.ctx = this.$refs.canvas.getContext('2d') |
||||||
|
this.ctx.lineCap = 'round' |
||||||
|
this.ctx.lineJoin = 'round' |
||||||
|
|
||||||
|
if (this.image) { |
||||||
|
let img = new Image() |
||||||
|
img.src = this.image |
||||||
|
img.onload = () => { |
||||||
|
this.ctx.drawImage(img, 0, 0, img.width, img.height) |
||||||
|
this.drew = true |
||||||
|
img = null |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
clear() { |
||||||
|
this.drew = false |
||||||
|
this.drawing = false |
||||||
|
this.$refs.canvas && (this.$refs.canvas.height = window.innerHeight) |
||||||
|
}, |
||||||
|
|
||||||
|
close() { |
||||||
|
this.visible = false |
||||||
|
this.clear() |
||||||
|
}, |
||||||
|
|
||||||
|
confirm() { |
||||||
|
this.onConfirm && this.onConfirm(this.getBase64()) |
||||||
|
this.visible = false |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
window.addEventListener('resize', this.resize) |
||||||
|
}, |
||||||
|
destroyed() { |
||||||
|
this.clear() |
||||||
|
window.removeEventListener('resize', this.resize) |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss"> |
||||||
|
.signature-board { |
||||||
|
position: fixed; |
||||||
|
background-color: white; |
||||||
|
top: 0; |
||||||
|
right: 0; |
||||||
|
height: 100vh; |
||||||
|
width: 100vw; |
||||||
|
z-index: 100; |
||||||
|
overflow: hidden; |
||||||
|
|
||||||
|
&__footer { |
||||||
|
position: absolute; |
||||||
|
bottom: 20px; |
||||||
|
right: 20px; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,29 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div class="tip-row"> |
||||||
|
搞了个手写签名,竖屏横屏不可兼得 |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<img :src="src" style="width: 100%;height: 500px;object-fit: contain"> |
||||||
|
</div> |
||||||
|
<el-button plain @click="signature">点击签名</el-button> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
name: 'signatureExample', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
src: null |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
signature() { |
||||||
|
this.$signature({ |
||||||
|
image: this.src, onConfirm: img => this.src = img |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
Loading…
Reference in new issue