1,当前代码是本人亲自一行行敲出来的哦
<template>
<div style="margin-left: 28%;">
<!-- 画布对象 -->
<div ref="grapDiv" style="width:800px;height:400px;border: 2px dotted #ddd; border-radius: 10px;" v-show="!isCommit">
<canvas ref="grapCvs" id="container" @mousedown.stop="mousedown" @mousemove.stop="mousemove"/>
</div>
<!-- 设置面板 -->
<div ref="setControlDiv"
style="width:280px;height:200px;background-color:#474747;border:1px solid #ddd;border-radius: 10px;margin-top: -203px;margin-left: 1px;position:absolute;"
v-show="ifSetController">
<div style="width:100%;height:30%;margin-top: 10px;">
<span style="width:100%;height:30%;">
<label style="float:left;color:white;margin-left: 14px;margin-top: 15px;">字体大小</label>
<label style="float:right;color:white;margin-right: 14px;margin-top: 15px;">{{fontSize}}</label>
</span>
<el-div style="width:100%;height:20%;margin-top: 40px;">
<el-slider v-model="fontSize" style="width:89%;margin-top:20px;margin-left:17px;" :min="1" :max="10" />
</el-div>
</div>
<div style="width:100%;height:45%;margin-top: 15px;padding: 7px;">
<li @click="setImgColor" class="" v-for="(item, index) in fontColorArray" :key="index" :style="'list-style: none;width: 38px;height: 38px;float: left;background: ' + item"></li>
</div>
</div>
<div ref="setDiv" v-show="!isCommit && ifSet">
<img title="画笔设置" src="../assets/brush.png" @click="setGraph" style="margin-top:4px;float: left;margin-left: 15px;cursor: pointer;" />
</div>
<!-- 提交的画布对象 -->
<div style="width:800px;height:400px;border:2px solid green; border-radius: 10px;" v-show="isCommit">
<img :src="content">
</div>
<!-- 操作按钮 -->
<div style="width:800px;padding-top: 10px;">
<el-button @click="set()" v-show="!isCommit">画笔设置</el-button>
<el-button @click="clear()" v-show="!isCommit">清除</el-button>
<el-button type="primary" @click="commit()" v-show="!isCommit">提交</el-button>
<el-button @click="goback()" v-show="isCommit">返回</el-button>
</div>
</div>
</template>
<style>
.activeteLi {
box-shadow: 0 0 3px rgb(0 0 0 / 95%);
transform: scale(1.2);
}
</style>
<script>
import { ElMessage, ElMessageBox } from 'element-plus'
export default {
data() {
return {
canvas : null,
graphics: null,
isDrawing : false,
curMouseY : null,
curMouseX: null,
offsetY: null,
xoffsetX: null,
cvsWidth: 800,
cvsHeight: 400,
isCommit: false,
content: null,
ifGraph: false,
ifSet: false,
ifSetController: false,
fontSize: 1,
fontColorArray: ["#F59999", "#E86262", "#AA4446", "#6B4849",
"#34231E", "#435772", "#2DA4A8", "#EFDCD3", "#FEAA3A",
"#FD6041", "#CF2257", "#404040", "#92BEE2", "#2286D8"],
fontColor: "#000000"
}
},
methods: {
setImgColor(curIndex) {
let liArray = curIndex.currentTarget.parentElement.children;
for (let child of liArray) {
child.className = ""
}
curIndex.currentTarget.className = "activeteLi"
this.fontColor = curIndex.currentTarget.style.background;
},
setGraph() {
this.ifSetController = this.ifSetController ? false : true
},
mousedown(e) {
this.isDrawing = true;
this.curMouseX = e.pageX - this.offsetX;
this.curMouseY = e.pageY - this.offsetY;
this.graphics.beginPath()
this.graphics.moveTo(this.curMouseX, this.curMouseY);
this.ifSetController = false
this.ifSet = false
this.$refs.grapDiv.style.cssText = "width:800px;height:400px;border: 2px dotted #ddd; border-radius: 10px;"
},
mousemove(e) {
if (this.isDrawing) {
this.graphics.strokeStyle = this.fontColor;
this.graphics.lineWidth = this.fontSize;
this.curMouseX = e.pageX - this.offsetX
this.curMouseY = e.pageY - this.offsetY
this.graphics.lineTo(this.curMouseX, this.curMouseY)
this.graphics.stroke()
this.ifGraph = true
}
},
set() {
if (this.ifSet) {
this.ifSetController= false
this.ifSet = false
this.$refs.grapDiv.style.cssText = "width:800px;height:400px;border: 2px dotted #ddd; border-radius: 10px;"
} else {
this.ifSet = true
this.$refs.grapDiv.style.cssText = "width:800px;height:400px;border: 2px dotted #ddd; border-radius: 10px 10px 0px 0px;"
this.$refs.setDiv.style.cssText = "width:800px;height:45px;border: 2px dotted #ddd;border-top:none;border-radius:0px 0px 10px 10px;"
}
},
clear() {
this.ifGraph = false
this.$refs.grapCvs.width = this.$refs.grapCvs.width
},
commit() {
if (!this.ifGraph) {
ElMessage({ message: "没有可提交的内容!", type: 'error', duration:2000 })
return
}
ElMessageBox({
title: '操作提示',
message: '确定提交?',
confirmButtonText: '确定',
cancelButtonText: '取消',
showCancelButton: true,
closeOnClickModal: false,
type: 'warning',
}).then(() => {
this.isCommit = true
this.ifSetController = false
this.ifSet = false
this.content = this.canvas.toDataURL()
ElMessage({ message: "提交成功!", type: 'success', duration: 1000 })
});
},
goback() {
this.ifGraph = false
this.$refs.grapCvs.width = this.$refs.grapCvs.width
this.isCommit = false
}
},
mounted() {
var canvas = document.getElementById("container");
canvas.width = this.cvsWidth;
canvas.height = this.cvsHeight;
this.offsetY = canvas.offsetTop;
this.offsetX = canvas.offsetLeft;
this.graphics = canvas.getContext("2d");
this.canvas = canvas;
document.addEventListener('mouseup', e => {
this.isDrawing = false;
this.graphics.closePath()
})
}
};
</script>
2,效果 3,提交后为base64编码 上面是本人写的一款,只适合PC, 最后,本人发现一个比较好用插件,可以直接引用,下来记录下使用方式
点击我查看demo
功能描述: 1,兼容 PC 和 Mobile; 2,画布自适应屏幕大小变化(窗口缩放、屏幕旋转时画布无需重置,自动校正坐标偏移); 3,自定义画布尺寸(导出图尺寸),画笔粗细、颜色,画布背景色; 4,支持裁剪 (针对需求:有的签字需要裁剪掉四周空白)。 5,导出图片格式为 base64 ;
第一步:安装: npm install vue-esign --save 第二步:使用: 在main.js 中 引入插件 import vueEsign from ‘vue-esign’ Vue.use(vueEsign)
第三步:页面使用说明: 必须设置 ref ,用来调用组件的两个内置方法 reset() 和 generate() 无需给组件设置 style 的宽高,如果画布的 width 属性值没超出父元素的样式宽度,则该组件的样式宽度就是画布宽度,超出的话,组件样式宽度则是父元素的100%; 所以只需设置好父元素的宽度即可;
<vue-esign ref="esign" :width="800" :height="300" :isCrop="isCrop" :lineWidth="lineWidth" :lineColor="lineColor" :bgColor.sync="bgColor" />
<button @click="handleReset">清空画板</button>
<button @click="handleGenerate">生成图片</button>
export default {
data () {
return {
lineWidth: 6,
lineColor: '#000000',
bgColor: '',
resultImg: '',
isCrop: false
}
},
methods: {
handleReset () {
this.$refs.esign.reset()
},
handleGenerate () {
this.$refs.esign.generate().then(res => {
this.resultImg = res
}).catch(err => {
alert(err)
})
}
}
插件说明:
属性 | 类型 | 默认值 | 说明 |
---|
width | Number | 800 | 画布宽度,即导出图片的宽度 | height | Number | 300 | 画布高度,即导出图片的高度 | lineWidth | Number | 4 | 画笔粗细 | lineColor | String | #000000 | 画笔颜色 | bgColor | String | 空 | 画布背景色,为空时画布背景透明, 支持多种格式 ‘#ccc’,‘#E5A1A1’,‘rgb(229, 161, 161)’,‘rgba(0,0,0,.6)’,‘red’ | isCrop | Boolean | false | 是否裁剪,在画布设定尺寸基础上裁掉四周空白部分 |
外加两个内置方方法: 清空画布 this.$refs.esign.reset()
生成图片 this.$refs.esign.generate().then(res => { console.log(res) // base64图片 }).catch(err => { alert(err) // 画布没有签字时会执行这里 ‘Not Signned’ })
|