admin管理员组

文章数量:1026989

vue之签名板实现

vue之签名实现

    • vue之签名实现

vue之签名实现

效果如下:

代码如下:

<template><div><div class="sign_handle"><div class="cav_wrapper"><canvas ref="signHandle" id="signHandle" /></div><div class="btn_container"><div  class="radio_container"><div :style="{background:item}" v-for="item in liColors" :key="item" @click="radioHandle(item)" class="color-item"></div></div><div class="btn"><div @touchstart="clearHandle" class="clear">清空</div><div @touchstart="saveImg" class="sure">确认</div></div></div><div class="show_sign_container" v-if="imgUrl"><div>签名图片如下</div><img :src="imgUrl" alt="" class="img"></div></div></div>
</template><script>
// 获取设备的宽度和高度
const { clientWidth, clientHeight } = document.documentElement
export default {name: 'Sign',data() {return {radio: '#000',height: 300, // 用于设置canvas的高度direction: false, // true 代表横屏, false 代表'竖屏'el: '', // canvas domctx: '', // canvas contextbackground: '#ddd', // canvas background-colorcolor: '#000', // 绘制时线条的颜色linewidth: 3, // 线条的宽度liColors: ['#ee0a24', '#000', '#1890ff'],isDraw: false,imgUrl:''}},created() {this.color = this.radiowindow.addEventListener('onorientationchange' in window ? 'orientationchange' : 'resize', () => {if (window.orientation === 180 || window.orientation === 0) {this.direction = falsethis.draw()}if (window.orientation === 90 || window.orientation === -90) {this.direction = truethis.draw()}}, false)},mounted() {this.draw()},methods: {radioHandle(value) {this.color = valuethis.setCanvas()},// 添加绘制 linedraw() {document.addEventListener('touchmove', e => e.preventDefault(), {passive: false})this.el = this.$refs.signHandlethis.initCanvas()},// 初始化canvas配置initCanvas() {const { height, direction, el } = this// 动态设置 canvas 的宽高if (direction) {el.width = heightel.height = clientWidth} else {el.width = clientWidthel.height = height}// 创建 context 对象this.ctx = el.getContext('2d')this.setCanvas()this.drawStart()this.drawing()this.drawEnd()},// 配置 canvassetCanvas() {const { ctx, height, direction } = this// 设置背景色ctx.fillStyle = this.background// 绘制矩形 fillRect定义了矩形当前的填充方式if (direction) {ctx.fillRect(0, 0, clientHeight, clientWidth - height)} else {ctx.fillRect(0, 0, clientWidth, clientHeight - height)}// 设置线条颜色ctx.strokeStyle = this.color// 设置线宽ctx.lineWidth = this.linewidth// 设置线条两头的结束点和开始点是圆形的ctx.lineCap = 'round'},// 开始绘制drawStart() {console.log('开始绘制');const { el, ctx } = thisel.addEventListener('touchstart', e => {ctx.beginPath()ctx.moveTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY)}, false)},// 绘制中drawing() {console.log('绘制中');const { el, ctx } = thisconst _this = thisel.addEventListener( 'touchmove', e => {_this.isDraw = trueconsole.log(_this.isDraw);ctx.lineTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY)ctx.stroke()}, false)},// 绘制结束drawEnd() {console.log('绘制结束');const { el, ctx } = thisel.addEventListener('touchend', () => {ctx.closePath()}, false)},// 清空clearHandle() {this.initCanvas()this.imgUrl = ''this.isDraw = false},// 保存信息saveImg() {if(!this.isDraw){// console.log('请签名后提交')return false}const imgBase64 = this.el.toDataURL()this.imgUrl = imgBase64console.log('保存签名成功' + imgBase64)let fileData = this.base64UrltoFile(imgBase64, 'fileName')let fileBlob = this.base64UrlToBlob(imgBase64)console.log(fileData);console.log(fileBlob);},// 将base64转换为文件base64UrltoFile(dataurl, filename) { let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n)while(n--){u8arr[n] = bstr.charCodeAt(n)}return new File([u8arr], filename, {type:mime})},// 将base64转换为Blobbase64UrlToBlob(urlData) {var bytes = window.atob(urlData.split(',')[1]); //去掉url的头,并转换为byte//处理异常,将ascii码小于0的转换为大于0var ab = new ArrayBuffer(bytes.length);var ia = new Uint8Array(ab);for (var i = 0; i < bytes.length; i++) {ia[i] = bytes.charCodeAt(i);}return new Blob([ab], {type: 'image/jpg'});}}
}
</script><style  lang="scss" scoped>
.sign_handle {.cav_wrapper{width: 100%;}.canvas {width: 100%;height: 400px;}.btn_container {width: 100%;height: 100px;background-color: #fff;display: flex;align-items: center;box-sizing: border-box;justify-content: space-between;.radio_container {.color-item{display: inline-block;color: #fff;width: 30px;height: 30px;margin: 0 10px;}}.btn{display: flex;.clear{width: 50px;height: 24px;font-size: 12px;text-align: center;line-height: 24px;border: 1px solid #000;border-radius: 4px;}.sure{width: 50px;height: 26px;font-size: 12px;text-align: center;line-height: 26px;color: #fff;margin: 0 20px;background: rgb(86, 70, 235);border-radius: 4px;}}}
}
.show_sign_container{display: flex;flex-direction: column;justify-content: center;align-items: center;background: #fff;width: 100%;height: 240px;font-size: 14px;img{width: 200px;height: 200px;margin-top: 10px;}
}
</style>

参考文章: vue 签名组件

GitHub地址: signature_pad

canvas用法参考网站:HTML5 Canvas

vue之签名板实现

vue之签名实现

    • vue之签名实现

vue之签名实现

效果如下:

代码如下:

<template><div><div class="sign_handle"><div class="cav_wrapper"><canvas ref="signHandle" id="signHandle" /></div><div class="btn_container"><div  class="radio_container"><div :style="{background:item}" v-for="item in liColors" :key="item" @click="radioHandle(item)" class="color-item"></div></div><div class="btn"><div @touchstart="clearHandle" class="clear">清空</div><div @touchstart="saveImg" class="sure">确认</div></div></div><div class="show_sign_container" v-if="imgUrl"><div>签名图片如下</div><img :src="imgUrl" alt="" class="img"></div></div></div>
</template><script>
// 获取设备的宽度和高度
const { clientWidth, clientHeight } = document.documentElement
export default {name: 'Sign',data() {return {radio: '#000',height: 300, // 用于设置canvas的高度direction: false, // true 代表横屏, false 代表'竖屏'el: '', // canvas domctx: '', // canvas contextbackground: '#ddd', // canvas background-colorcolor: '#000', // 绘制时线条的颜色linewidth: 3, // 线条的宽度liColors: ['#ee0a24', '#000', '#1890ff'],isDraw: false,imgUrl:''}},created() {this.color = this.radiowindow.addEventListener('onorientationchange' in window ? 'orientationchange' : 'resize', () => {if (window.orientation === 180 || window.orientation === 0) {this.direction = falsethis.draw()}if (window.orientation === 90 || window.orientation === -90) {this.direction = truethis.draw()}}, false)},mounted() {this.draw()},methods: {radioHandle(value) {this.color = valuethis.setCanvas()},// 添加绘制 linedraw() {document.addEventListener('touchmove', e => e.preventDefault(), {passive: false})this.el = this.$refs.signHandlethis.initCanvas()},// 初始化canvas配置initCanvas() {const { height, direction, el } = this// 动态设置 canvas 的宽高if (direction) {el.width = heightel.height = clientWidth} else {el.width = clientWidthel.height = height}// 创建 context 对象this.ctx = el.getContext('2d')this.setCanvas()this.drawStart()this.drawing()this.drawEnd()},// 配置 canvassetCanvas() {const { ctx, height, direction } = this// 设置背景色ctx.fillStyle = this.background// 绘制矩形 fillRect定义了矩形当前的填充方式if (direction) {ctx.fillRect(0, 0, clientHeight, clientWidth - height)} else {ctx.fillRect(0, 0, clientWidth, clientHeight - height)}// 设置线条颜色ctx.strokeStyle = this.color// 设置线宽ctx.lineWidth = this.linewidth// 设置线条两头的结束点和开始点是圆形的ctx.lineCap = 'round'},// 开始绘制drawStart() {console.log('开始绘制');const { el, ctx } = thisel.addEventListener('touchstart', e => {ctx.beginPath()ctx.moveTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY)}, false)},// 绘制中drawing() {console.log('绘制中');const { el, ctx } = thisconst _this = thisel.addEventListener( 'touchmove', e => {_this.isDraw = trueconsole.log(_this.isDraw);ctx.lineTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY)ctx.stroke()}, false)},// 绘制结束drawEnd() {console.log('绘制结束');const { el, ctx } = thisel.addEventListener('touchend', () => {ctx.closePath()}, false)},// 清空clearHandle() {this.initCanvas()this.imgUrl = ''this.isDraw = false},// 保存信息saveImg() {if(!this.isDraw){// console.log('请签名后提交')return false}const imgBase64 = this.el.toDataURL()this.imgUrl = imgBase64console.log('保存签名成功' + imgBase64)let fileData = this.base64UrltoFile(imgBase64, 'fileName')let fileBlob = this.base64UrlToBlob(imgBase64)console.log(fileData);console.log(fileBlob);},// 将base64转换为文件base64UrltoFile(dataurl, filename) { let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n)while(n--){u8arr[n] = bstr.charCodeAt(n)}return new File([u8arr], filename, {type:mime})},// 将base64转换为Blobbase64UrlToBlob(urlData) {var bytes = window.atob(urlData.split(',')[1]); //去掉url的头,并转换为byte//处理异常,将ascii码小于0的转换为大于0var ab = new ArrayBuffer(bytes.length);var ia = new Uint8Array(ab);for (var i = 0; i < bytes.length; i++) {ia[i] = bytes.charCodeAt(i);}return new Blob([ab], {type: 'image/jpg'});}}
}
</script><style  lang="scss" scoped>
.sign_handle {.cav_wrapper{width: 100%;}.canvas {width: 100%;height: 400px;}.btn_container {width: 100%;height: 100px;background-color: #fff;display: flex;align-items: center;box-sizing: border-box;justify-content: space-between;.radio_container {.color-item{display: inline-block;color: #fff;width: 30px;height: 30px;margin: 0 10px;}}.btn{display: flex;.clear{width: 50px;height: 24px;font-size: 12px;text-align: center;line-height: 24px;border: 1px solid #000;border-radius: 4px;}.sure{width: 50px;height: 26px;font-size: 12px;text-align: center;line-height: 26px;color: #fff;margin: 0 20px;background: rgb(86, 70, 235);border-radius: 4px;}}}
}
.show_sign_container{display: flex;flex-direction: column;justify-content: center;align-items: center;background: #fff;width: 100%;height: 240px;font-size: 14px;img{width: 200px;height: 200px;margin-top: 10px;}
}
</style>

参考文章: vue 签名组件

GitHub地址: signature_pad

canvas用法参考网站:HTML5 Canvas

本文标签: vue之签名板实现