公司项目制作一个手写签名,由于是移动端,所以需要大屏手写,所以我结合和layui中的弹窗,在弹窗中创建canvas画布手写签名,然后保存成图片存到页面上给用户看,提交的时候再提交到服务器。
先给大家看一下效果图:
HTML需要一个按钮控制弹出层,和一个显示图片的区域,这个我就不多说了,可以到layui文档上看按钮绑定弹出层的方法。图片显示显示区域的话一个img标签就好。Html代码如下:
<div class="signature_img" style="width: 100%; height: 150px; display: none">
<img style="height: 150px; width: auto" src="" alt="">
</div>
然后是layer方法中的弹出层信息的设置,在这里需要把canvas画布信息设置在content中,如果放在body中然后用content:$(#id)的方法引入也是可以的。重要的部分来了,打开的弹出层中存在canvas之后,要在layer的success方法中获得元素,否则会造成元素找不到的情况,画不出东西来。
代码如下:
var active = {
setTop: function(){
layer.open({
type: 0
,title: '签名'
,content: '<div id="canvas">\n' +
' <p id="clearCanvas">清除</p>\n' +
' <p class="layui-layer-close" id="saveCanvas">保存</p>\n' +
' <canvas id="canvas_id"></canvas>\n' +
' </div>'
,area:['100%','100%']
,success:function(layero, index){
new lineCanvas({
el: document.getElementById("canvas"),//绘制canvas的父级div
clearEl: document.getElementById("clearCanvas"),//清除按钮
saveEl: document.getElementById("saveCanvas"),//保存按钮
canvas:document.getElementById("canvas_id"),
// linewidth:1,//线条粗细,选填
// color:"black",//线条颜色,选填
// background:"#ffffff"//线条背景,选填
});
}
});
}
};
然后问题又来了,在签名的时候,还是没有效果,可是元素啥的都能找到,打印以下点触的位置,发现熟知很大,根本就不是我画的鼠标的位置,所以能确定的是,画是画出来了,看不见在哪里。是什么问题呢?因为我的是长页面,所以有滚动条,在签名的时候就发现滚动条跟着手指动来动去,所以随便滚动一下鼠标,当我把滚动条拉到最下面的时候,既然发现签名真的是在这里地方写了!!!
要解决这个问题,要控制弹出层出现的时候,滚动条是禁止滑动的,并且是显示的位置要是文档的最下面。所以我要用当前笔触的位置减掉滚动条上面的上面的位置,以便当我打开弹出层的时候就已经是最下面了,并且滚动条不会滑来滑去,书写方便。
控制滚动调滑动的代码也是加在layer方法中的success方法里面。是打开弹出层成功之后再控制不会滚动:
function unScroll() {
var top = $(document).scrollTop();
$(document).on('scroll.unable',function (e) {
$(document).scrollTop(top);
})
};
unScroll();
$(".layui-layer-close").click(function () {
$(document).unbind("scroll.unable");
})
然后以下是绘制签名的方法:
<script>
function lineCanvas(obj) {
this.linewidth = 1;
this.color = "#000000";
this.background = "#ffffff";
for (var i in obj) {
this[i] = obj[i];
};
this.cxt = this.canvas.getContext("2d");
this.cxt.fillStyle = this.background;
this.canvas.width = document.documentElement.clientWidth-40;//画布的宽度是设备的宽度,40是我要减去的宽度,你用的时候不需要。
this.canvas.height = 380; //用以上同样的方法可以获得设备的高度,只是我根据我的项目设成380px;
this.cxt.strokeStyle = this.color;//画笔的颜色
this.cxt.lineWidth = this.linewidth;//线条的宽度
this.cxt.lineCap = "round";
//开始绘制
this.canvas.addEventListener("touchstart", function(e) {
this.cxt.beginPath();
this.cxt.moveTo(e.changedTouches[0].pageX-40, e.changedTouches[0].pageY-document.documentElement.scrollTop-82);//document.documentElement.scrollTop是滚动条到顶部的距离。
}.bind(this), false);
//绘制中
this.canvas.addEventListener("touchmove", function(e) {
this.cxt.lineTo(e.changedTouches[0].pageX-40, e.changedTouches[0].pageY-document.documentElement.scrollTop-82);
this.cxt.stroke();
}.bind(this), false);
//结束绘制
this.canvas.addEventListener("touchend", function() {
this.cxt.closePath();
}.bind(this), false);
//清除画布
this.clearEl.addEventListener("click", function() {
this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
}.bind(this), false);
//保存图片,直接转base64
this.saveEl.addEventListener("click", function() {
var imgBase64 = this.canvas.toDataURL();
console.log(imgBase64);//图片路径
$(".signature_img").show();
$(".signature_img img").attr("src",imgBase64);//获取元素的src属性,并赋值图片的路劲。
}.bind(this), false);
};
</script>
以上就是结合layui框架的弹出层制作手写签名的全过程和代码。刚开始的时候去下载手写签名框架啥的,不单止需要引入的文件太多,也不是全屏的,不好用,还不如自己写的轻便。